我知道,我知道 - 这个问题的标题到处都是。但是,我不确定这里可能是什么问题导致了我所看到的情况。
我在类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 行,如堆栈跟踪所示。
并且,在调试时,单元测试通过了,因为返回x
的TEST_METHOD
是true
. 只有在单独运行测试或运行所有测试时,该测试方法才会失败。
一些可能相关的注释:
- 这是一个单线程应用程序,没有安排任何任务(据说没有竞争条件)
- 类中还有另一种方法,
Project
它也处理与std::ifstream
此方法相同 的文件- 该方法有自己的测试方法,已编写并通过,没有任何问题
- 测试方法也访问“normal.cfg”文件
- 是的,
this->port
有一个赋值
因此,我的问题是:
- 为什么堆栈跟踪引用测试方法的右括号,而不是
Assert
据称失败的方法中的单个? - 如何让单元测试在运行时通过?(因为它目前仅在我可以确认的调试过程中出现
x
)true
。 - 如果问题是竞争条件,可能其他测试方法正在访问“normal.cfg”文件,为什么即使单独运行该方法,测试方法也会失败?
非常感谢这里的任何支持/帮助。谢谢!