我是第一次尝试用C++进行单元测试,多年来我没有使用过C++(目前我主要是C#编码器).看起来我正在做一个正确的猪耳朵 - 我希望有人能引导我回到正义的道路上.我刚开始在这里开始,并且真的希望使用最佳实践来实现这些测试,所以欢迎任何和所有评论,即使我目前最关心的是我的链接器错误.
所以,我有一个整体解决方案"Technorabble",子项目"CalibrationTool"和"CalibrationToolUnitTests".
CalibrationTool有一个MathUtils.h文件:
#ifndef __math_utils__
#define __math_utils__
#include "stdafx.h"
#include <vector>
namespace Technorabble
{
namespace CalibrationTool
{
double GetDoubleVectorAverage(std::vector<double> v)
{
double cumulativeValue = 0;
for(std::vector<double>::iterator iter = v.begin(); iter != v.end(); ++iter)
{
cumulativeValue += *iter;
}
return cumulativeValue / v.size();
}
}; // end namespace CalibrationTool
}; // end namespace Technorabble
#endif // !__math_utils__
Run Code Online (Sandbox Code Playgroud)
(但是没有.cpp文件,因为我有各种(有些类似的)问题让我的模板功能正常工作 - 所以我最终定义了内联).
继续单元测试项目,我有一个main.cpp:
#include "MathUtilsTest.h"
void RunMathUtilsTests();
int main()
{
RunMathUtilsTests();
// Other class tests will go here when I have things to test
}
void RunMathUtilsTests()
{
MathUtilsTest* mathUtilsTest = new MathUtilsTest();
mathUtilsTest->RunTests();
delete mathUtilsTest;
}
Run Code Online (Sandbox Code Playgroud)
最后,MathUtilsTest类的头和cpp再次相当简单:
.H:
#ifndef __MATH_UTILS_TEST__
#define __MATH_UTILS_TEST__
#include "CalibrationToolUnitTestsLogging.h"
#include "..\CalibrationTool\MathUtils.h"
class MathUtilsTest
{
public:
MathUtilsTest();
~MathUtilsTest();
bool RunTests();
private:
bool GetDoubleVectorAverageTest();
}; // end class MathUtilsTest
#endif
Run Code Online (Sandbox Code Playgroud)
的.cpp:
#include "MathUtilsTest.h"
#include <sstream>
bool MathUtilsTest::RunTests()
{
return GetDoubleVectorAverageTest();
}
MathUtilsTest::~MathUtilsTest()
{
}
MathUtilsTest::MathUtilsTest()
{
}
bool MathUtilsTest::GetDoubleVectorAverageTest()
{
bool passed = true;
std::vector<double> values;
for (int i = 1; i < 23; i++)
{
values.push_back(i);
}
// vector becomes: 1, 2, 3, 4, .....20, 21, 22. Average is 11.5
double expectedAverage = 11.5;
double calculatedAverage = Technorabble::CalibrationTool::GetDoubleVectorAverage(values);
if (calculatedAverage != expectedAverage)
{
std::ostringstream s;
s << calculatedAverage;
std::string avgString = s.str();
CalibrationToolUnitTestsLogging::Write("Failed MathUtilsTest.GetDoubleVectorAverageTest: " + avgString);
passed = false;
}
else
{
CalibrationToolUnitTestsLogging::Write("Passed MathUtilsTest.GetDoubleVectorAverageTest");
}
return passed;
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很好,我用#ifndef等保护我的标题但是我仍然遇到以下错误:
1)错误LNK1169:找到一个或多个多重定义的符号
2)错误LNK2005:"double __cdecl Technorabble :: CalibrationTool :: GetDoubleVectorAverage(class std :: vector>)"(?GetDoubleVectorAverage @ CalibrationTool @ Technorabble @@ YANV?$ vector @ NV?$ allocator @ N @ std @@@ std @@@ Z)已在main.obj中定义C:_SVN\Technorabble\Windows Software\CalibrationToolUnitTests\MathUtilsTest.obj
怎么会这样?任何人都可以发现它出错的地方吗?
标题中定义的函数应标记为inline:
inline double GetDoubleVectorAverage(std::vector<double> v)
{
}
Run Code Online (Sandbox Code Playgroud)
如果它比两行长,请考虑将其移动到实现文件.
pragmas或包含警卫不能防止多种定义.
请注意,您应该传递v通过const引用而不是通过值.