首页 > 解决方案 > CppUnitTestFramework:测试方法失败,堆栈跟踪列出方法末尾的行号,调试测试通过

问题描述

我知道,我知道 - 这个问题的标题到处都是。但是,我不确定这里可能是什么问题导致了我所看到的情况。

我在类Project中有以下正在单元测试的方法:

bool Project::DetermineID(std::string configFile, std::string& ID)
{
    std::ifstream config;
    config.open(configFile);

    if (!config.is_open()) {
        WARNING << "Failed to open the configuration file for processing ID at: " << configFile;
        return false;
    }

    std::string line = "";
    ID = "";

    bool isConfigurationSection = false;
    bool isConfiguration = false;

    std::string tempID = "";

    while (std::getline(config, line))
    {
        std::transform(line.begin(), line.end(), line.begin(), ::toupper); // transform the line to all capital letters
        boost::trim(line);

        if ((line.find("IDENTIFICATIONS") != std::string::npos) && (!isConfigurationSection)) {

            // remove the "IDENTIFICATIONS" part from the current line we're working with
            std::size_t idStartPos = line.find("IDENTIFICATIONS");
            line = line.substr(idStartPos + strlen("IDENTIFICATIONS"), line.length() - idStartPos - strlen("IDENTIFICATIONS"));
            boost::trim(line);

            isConfigurationSection = true;
        }

        if ((line.find('{') != std::string::npos) && isConfigurationSection) {

            std::size_t bracketPos = line.find('{');

            // we are working within the ids configuration section
            // determine if this is the first character of the line, or if there is an ID that precedes the { 

            if (bracketPos == 0) {
                // is the first char
                // remove the bracket and keep processing

                line = line.substr(1, line.length() - 1);
                boost::trim(line);
            }
            else {
                // the text before { is a temp ID

                tempID = line.substr(0, bracketPos - 1);
                isConfiguration = true;

                line = line.substr(bracketPos, line.length() - bracketPos);
                boost::trim(line);
            }
        }

        if ((line.find("PORT") != std::string::npos) && isConfiguration) {

            std::size_t indexOfEqualSign = line.find('=');

            if (indexOfEqualSign == std::string::npos) {
                WARNING << "Unable to determine the port # assigned to " << tempID;
            }
            else {
                std::string portString = "";
                portString = line.substr(indexOfEqualSign + 1, line.length() - indexOfEqualSign - 1);
                boost::trim(portString);

                // confirm that the obtained port string is not an empty value

                if (portString.empty()) {
                    WARNING << "Failed to obtain the \"Port\" value that is set to " << tempID;
                }
                else {

                    // attempt to convert the string to int

                    int workingPortNum = 0;

                    try {
                        workingPortNum = std::stoi(portString);
                    }
                    catch (...) {
                        WARNING << "Failed to convert the obtained \"Port\" value that is set to " << tempID;
                    }

                    if (workingPortNum != 0) {
                        // check if this port # is the same port # we are publishing data on

                        if (workingPortNum == this->port) {
                            ID = tempID;
                            break;
                        }
                    }
                }
            }
        }
    }

    config.close();

    if (ID.empty())
        return false;
    else
        return true;
}

此方法的目标是解析任何文本文件的 ID 部分,基于匹配应用程序正在向其发布数据的端口号。

文件的格式是这样的:

Idenntifications {
  ID {
    port = 1001
  }
}

在单独的 Visual Studio 项目中对各种方法(包括此Project::DetermineID方法)进行单元测试。

#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)

TEST_CLASS(ProjectUnitTests) {
    Project* parser;
    std::string projectDirectory;

    TEST_METHOD_INITIALIZE(ProjectUnitTestInitialization) {
        projectDirectory = EXPAND(UNITTESTPRJ);
        projectDirectory.erase(0, 1);
        projectDirectory.erase(projectDirectory.size() - 2);

        parser = Project::getClass(); // singleton method getter/initializer
    }

    // Other test methods are present and pass/fail accordingly

    TEST_METHOD(DetermineID) {
        std::string ID = "";

        bool x = parser ->DetermineAdapterID(projectDirectory + "normal.cfg", ID);
        Assert::IsTrue(x);
    }
};

现在,当我运行测试时,DetermineID失败并且堆栈跟踪状态:

   DetermineID
   Source: Project Tests.cpp line 86
   Duration: 2 sec

  Message: 
    Assert failed
  Stack Trace: 
    ProjectUnitTests::DetermineID() line 91

现在,在我的测试 .cpp 文件中,TEST_METHOD(DetermineID) {它位于第 86 行。但该方法}位于第 91 行,如堆栈跟踪所示。

并且,在调试时,单元测试通过了,因为返回xTEST_METHODtrue. 只有在单独运行测试或运行所有测试时,该测试方法才会失败。

一些可能相关的注释:

因此,我的问题是:

  1. 为什么堆栈跟踪引用测试方法的右括号,而不是Assert据称失败的方法中的单个?
  2. 如何让单元测试在运行时通过?(因为它目前仅在我可以确认的调试过程中出现xtrue
  3. 如果问题是竞争条件,可能其他测试方法正在访问“normal.cfg”文件,为什么即使单独运行该方法,测试方法也会失败?

非常感谢这里的任何支持/帮助。谢谢!

标签: c++unit-testingmicrosoft-cpp-unit-test

解决方案


推荐阅读