I know, I know - that question title is very much all over the place. However, I am not sure what could be an issue here that is causing what I am witnessing.

I have the following method in class Project that is being unit tested:

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;
}

The goal of this method is to parse any text file for the ID portion, based on matching the port # that the application is publishing data to.

Format of the file is like this:

Idenntifications {
  ID {
    port = 1001
  }
}

In a separate Visual Studio project that unit tests various methods, including this Project::DetermineID method.

#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);
    }
};

Now, when I run the tests, DetermineID fails and the stack trace states:

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

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

Now, in my test .cpp file, TEST_METHOD(DetermineID) { is present on line 86. But that method's } is located on line 91, as the stack trace indicates.

And, when debugging, the unit test passes, because the return of x in the TEST_METHOD is true. Only when running the test individually or running all tests does that test method fail.

Some notes that may be relevant:

  • This is a single-threaded application with no tasks scheduled (no race condition to worry about supposedly)
  • There is another method in the Project class that also processes a file with an std::ifstream same as this method does
    • That method has its own test method that has been written and passes without any problems
    • The test method also access the "normal.cfg" file
  • Yes, this->port has an assigned value

Thus, my questions are:

  1. Why does the stack trace reference the closing bracket for the test method instead of the single Assert within the method that is supposedly failing?
  2. How to get the unit test to pass when it is ran? (Since it currently only plasses during debugging where I can confirm that x is true).
  3. If the issue is a race condition where perhaps the other test method is accessing the "normal.cfg" file, why does the test method fail even when the method is individually ran?

Any support/assistance here is very much appreciated. Thank you!

0

There are 0 answers