使用 Visual Studio 2015 对 C++ 代码运行单元测试
2016-04-08 21:49
323 查看
代码写多了,往往规模会越来越大,这时候就有必要保证代码的稳定性了;不过我从网上看到的单元测试貌似大多都是用的 JUnit, 难道 C++ 就没有了吗?我从网上找了一些方法试了下其实挺简单的。下面我以一个示例作说明。(如果你有准备好的待测代码可直接看创建单元测试项目那里。)
创建一个 Win32 空项目“stg”并添加下面的代码用作测试。这里我创建了一个结构体用来表示一个物体,有X,Y,半径这些变量,还有一个用来表示另一个物体是否在它的半径内的函数,是则返回1,否则为0。
【stg.h】
【stg.cpp】
(为了简单我把 main 函数省略了。)
然后是创建单元测试项目。在这个解决方案中创建一个名为 stgTest 的单元测试工程(命名规则是“项目名”+Test),
创建好后在引用中添加待测项目的引用(右键引用选择“添加引用项目”),
点确定,它应该会出现在单元测试工程的引用中。
然后在“stg”项目上右键选择属性,将其配置类型改为静态库(你可以在测试完后改回为应用程序)
接下来找到单元测试的代码,其文件名默认为“unittest1.cpp”,最好也改为“stgTest.cpp”以便区分;在这个代码中有一个默认的方法“TestMethod1”,它是由宏“TEST_METHOD”定义的一个函数,这个函数就是用来作测试的,运行测试时它里面的代码会执行,测试结果由 Assert 中的一系列函数决定。另外两个宏“TEST_METHOD_INITIALIZE”,“TEST_METHOD_CLEANUP”分别用于定义测试开始前与结束后执行的函数,通常将函数名定义为“SetUp”和“TearDown”(或许是因为
JUnit 中就是这样的?)。这里我将默认的“TestMethod1”改为“TestShot”(命名规则为 Test+“函数名”),然后包含头文件 #include“..\stg\stg.h”,加入测试代码后形成下面这个样子:
【stgTest.cpp 中的部分代码】
上面 AreEqual 那句中,模板填入待测值的类型,第一个参数为预测值,第二个为实际运行的结果,若相等则测试成功,否则为失败。写好代码后选择生成 stgTest 项目,然后在测试,窗口中打开测试资源管理器,如果生成没有问题就可以在这里看到测试项了,选择运行即可。
既然学会了如何使用单元测试,那么以后写代码就不要忘了用哦!这样你的代码中的BUG就会越来越少了!
创建一个 Win32 空项目“stg”并添加下面的代码用作测试。这里我创建了一个结构体用来表示一个物体,有X,Y,半径这些变量,还有一个用来表示另一个物体是否在它的半径内的函数,是则返回1,否则为0。
【stg.h】
#pragma once struct SpriteType { SpriteType(); void SetValue(float, float, float, float); int IsShotBy(SpriteType*); private: float posX, posY, shotRadius, sensedRadius; float _temp0; };
【stg.cpp】
#include<cmath> #include"stg.h" SpriteType::SpriteType() :posX(0.0f), posY(0.0f), shotRadius(0.0f), sensedRadius(0.0f) { } void SpriteType::SetValue(float x, float y, float rshot, float rsensor) { posX = x, posY = y, shotRadius = rshot, sensedRadius = rsensor; } int SpriteType::IsShotBy(SpriteType *pOtherSprite) { _temp0 = sqrtf((pOtherSprite->posX - posX)*(pOtherSprite->posX - posX) + (pOtherSprite->posY - posY)*(pOtherSprite->posY - posY)); return (int)(_temp0 < shotRadius); }
(为了简单我把 main 函数省略了。)
然后是创建单元测试项目。在这个解决方案中创建一个名为 stgTest 的单元测试工程(命名规则是“项目名”+Test),
创建好后在引用中添加待测项目的引用(右键引用选择“添加引用项目”),
点确定,它应该会出现在单元测试工程的引用中。
然后在“stg”项目上右键选择属性,将其配置类型改为静态库(你可以在测试完后改回为应用程序)
接下来找到单元测试的代码,其文件名默认为“unittest1.cpp”,最好也改为“stgTest.cpp”以便区分;在这个代码中有一个默认的方法“TestMethod1”,它是由宏“TEST_METHOD”定义的一个函数,这个函数就是用来作测试的,运行测试时它里面的代码会执行,测试结果由 Assert 中的一系列函数决定。另外两个宏“TEST_METHOD_INITIALIZE”,“TEST_METHOD_CLEANUP”分别用于定义测试开始前与结束后执行的函数,通常将函数名定义为“SetUp”和“TearDown”(或许是因为
JUnit 中就是这样的?)。这里我将默认的“TestMethod1”改为“TestShot”(命名规则为 Test+“函数名”),然后包含头文件 #include“..\stg\stg.h”,加入测试代码后形成下面这个样子:
【stgTest.cpp 中的部分代码】
namespace AmIShotTest { TEST_CLASS(UnitTest1) { private: SpriteType *s1, *s2; public: TEST_METHOD_INITIALIZE(SetUp) { s1 = new SpriteType(); s2 = new SpriteType(); Logger::WriteMessage("Test initialized.\n"); //用于输出信息 } TEST_METHOD_CLEANUP(TearDown) { delete s1; delete s2; Logger::WriteMessage("Test completed.\n"); } TEST_METHOD(TestShot) { s1->SetValue(2.0f, 3.0f, 1.2f, 1.5f); s2->SetValue(2.2f, 3.1f, 0.0f, 0.0f); Assert::AreEqual<int>(1, s1->IsShotBy(s2)); Logger::WriteMessage("Shot tested.\n"); } }; }
上面 AreEqual 那句中,模板填入待测值的类型,第一个参数为预测值,第二个为实际运行的结果,若相等则测试成功,否则为失败。写好代码后选择生成 stgTest 项目,然后在测试,窗口中打开测试资源管理器,如果生成没有问题就可以在这里看到测试项了,选择运行即可。
既然学会了如何使用单元测试,那么以后写代码就不要忘了用哦!这样你的代码中的BUG就会越来越少了!
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Ruby单元测试框架TestUnit的替代者MiniTest介绍
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解