本主题介绍一种方法,其中使用 Visual Studio 2012 Express for Windows 8 和面向 C++ 的 Microsoft 单元测试框架,针对 Windows 应用商店应用程序的 C++ DLL 创建单元测试。RooterLib DLL 通过实现计算给定数的平方根的估计的函数来演示限制计算理论的模糊内存。随后可在一个 Windows 应用商店应用程序中加入该 DLL,向用户展示数学方面的一些趣事。
说明
本节中的主题介绍 Visual Studio 2012 Express for Windows 8 的功能。Visual Studio Ultimate、VS Premium 和 VS Professional 提供了用于单元测试的其他功能。
在 VS Ultimate、VS Premium 和 VS Professional 中,可使用已为 Microsoft 测试资源管理器创建外接程序适配器的任何第三方或开放源代码单元测试框架。还可为测试分析并显示代码覆盖率信息。
// The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the ROOTERLIB_EXPORTS// symbol defined on the command line. This symbol should not be defined on any project// that uses this DLL. This way any other project whose source files include this file see // ROOTERLIB_API functions as being imported from a DLL, whereas this DLL sees symbols// defined with this macro as being exported.#ifdef ROOTERLIB_EXPORTS#define ROOTERLIB_API __declspec(dllexport)#else#define ROOTERLIB_API __declspec(dllimport)#endif //ROOTERLIB_EXPORTSclassROOTERLIB_APICRooterLib{public:CRooterLib(void);doubleSquareRoot(doublev);};注释解释ifdef块不仅适用于dll的开发人员,还适用于在其项目中引用DLL的所有人。您可使用DLL的项目属性将ROOTERLIB_EXPORTS符号添加到命令行。CRooterLib类声明一个构造函数和SqareRootestimator方法。
TEST_METHOD(BasicTest)
{
CRooterLib rooter;
Assert::AreEqual(
// Expected value:
0.0,
// Actual value:
rooter.SquareRoot(0.0),
// Tolerance:
0.01,
// Message:
L"Basic test failed",
// Line number - used if there is no PDB file:
LINE_INFO());
}
TEST_METHOD(RangeTest)
{
CRooterLib rooter;
for (double v = 1e-6; v < 1e6; v = v * 3.2)
{
double expected = v;
double actual = rooter.SquareRoot(v*v);
double tolerance = expected/1000;
Assert::AreEqual(expected, actual, tolerance);
}
};
**提示**
建议您不要更改已通过的测试。而是添加新测试,更新代码以便测试通过,然后添加其他测试等。
当您的用户更改其要求时,请禁用不再正确的测试。编写新测试并使它们以相同的增量方式一次运行一个。
在测试资源管理器中,选择“全部运行”。
测试将不会通过。
提示
编写测试后,立即验证每个测试是否都会失败。这帮助您避免易犯的错误,不会编写从不失败的测试。
增强受测代码,以便新测试通过。将以下代码添加到 RooterLib.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <math.h>...// Find the square root of a number.doubleCRooterLib::SquareRoot(doublev){doubleresult=v;doublediff=v;while(diff>result/1000){doubleoldResult=result;result=result-(result*result-v)/(2*result);diff=abs(oldResult-result);}returnresult;}
#include <stdexcept>
...
double CRooterLib::SquareRoot(double v)
{
//Validate the input parameter:
if (v < 0.0)
{
throw std::out_of_range("Can't do square roots of negatives");
}
...