UnitC++是一个轻量级的C++单元测试库,旨在简化C++代码的测试过程。它是一个header-only库,这意味着只需将库的头文件包含到项目中即可使用。UnitC++支持跨平台,可以在多种编译器上运行,包括g++、clang和Microsoft Visual C++。
UnitC++存储在Mercurial版本库中,可以通过克隆到本地磁盘来获取它。操作如下:
cd ~
hg clone https://davidcorne@bitbucket.org/davidcorne/unitcpp
也可以从GitHub克隆:
https://github.com/davidcorne/UnitCpp
由于UnitC++是一个header-only库,包含它的步骤非常简单。具体方法取决于构建过程,但通常都很直接。只需将库的路径添加到编译器的include行即可。以下是两种常见的方法:
在命令行编译时,可以添加参数:
-I $(path_to_unitc++)
这适用于g++/clang/cl等命令行编译器。也可以将这个参数添加到makefile的编译器参数中。
在Visual Studio中,需要转到“项目属性”->“C/C++”->“附加包含目录”,然后浏览到$(path_to_unitc++)。
编写测试的第一步是包含头文件:
#include
然后,需要声明正在编写一个测试,使用:
TEST(group_name, test_name)
这类似于声明一个函数。例如,如果要为一个名为MyString的类编写一组测试,它看起来可能是这样的:
TEST(MyString, length_test)
{
//...
}
TEST(MyString, validity_test)
{
//...
}
注意这里的模式是为一个类编写多个测试,类名作为group_name,正在测试的内容作为test_name在TEST宏中。
现在已经准备好编写测试代码了。UnitC++提供了一些有用的宏来编写测试。以下是它们的一部分:
TEST_EQUAL(A, B)
TEST_NOT_EQUAL(A, B)
TEST_LESS_THAN(A, B)
TEST_MORE_THAN(A, B)
TEST_APPROX_EQUAL(A, B, TOLERANCE)
TEST_TRUE(A)
TEST_FALSE(A)
TEST_THROWS(FUNCTION, EXCEPTION, ...)
以下是上述示例的完整版本:
#include
TEST(MyString, length_test)
{
MyString str("This is a string");
TEST_EQUAL(str.length(), 16);
TEST_NOT_EQUAL(str.length(), 17);
TEST_LESS_THAN(str.length(), 20);
TEST_MORE_THAN(str.length(), 10);
TEST_APPROX_EQUAL(str.length(), 15, 1.1); // 测试长度是否在15的1.1范围内
}
TEST(MyString, validity_test)
{
MyString invalid_string;
TEST_FALSE(invalid_string.valid());
MyString valid_string("");
TEST_TRUE(valid_string.valid());
#ifdef UNITCPP_TEST_THROWS_AVAILABLE
TEST_THROWS([&](){invalid_string.length();}, MyString::InvalidStringException);
#endif // UNITCPP_TEST_THROWS_AVAILABLE
}
这显然是一个虚构的例子,有几个测试检查同一件事情,即字符串"This is a string"的长度是16。然而,这是一个宏如何被使用的示例。
已经编写了一组漂亮的测试,现在想运行它们。这可以通过TestRegister类来完成。这是一个单例,它注册了用TEST宏声明的所有测试。这些测试可以按照以下方式运行:
#include
int main()
{
return UnitCpp::TestRegister::test_register().run_tests();
}
只要包含测试的代码链接到可执行文件中,TestRegister::test_register().run_tests()就会运行测试。
也可以调用TestRegister::test_register().run_tests("group_name")来运行特定组的所有测试。
在Example文件夹中,有一个工作示例,进一步展示了UnitC++的一些功能。
这不是一个常见的问题。但是,如果编译器与UnitC++不兼容,请告诉!会尽快修复。有关如何让知道,请参见“如何报告问题或请求功能”。
总是乐于改进或修复bug,只需要告诉。最好的方法是在问题跟踪器上提交问题。它位于这里,不要害羞,不会对任何人发火。
为个人使用创建了UnitC++。这意味着需要测试任何东西时都会使用它。
它当然是用UnitC++测试的!使用drone.io进行持续集成。目前用g++、clang和cl测试它。在drone.io上,测试g++和clang,在Windows机器上使用cygwin开发和测试g++和cl。drone.io构建的当前状态是。
每个TEST做了3件事:
它定义了一个从TestCase派生的类。
它创建了这个类的全局实例。
它让提供了覆盖的run()函数的主体。
声明一个全局对象的原因是调用构造函数。在TestCase的构造函数中,它注册自己,这样TestRegister就知道要运行哪些测试。这就是为什么只要对象链接在一起,TestRegister::test_register().run_tests()就会运行它们。