最近使用doctest较多,有些新的心得,发现doctest一些新的特性,还有以前的一些错误,现对错误进行一些修改。
单元测试框架很多,ubuntu使用gtest很方便,window平台主要是使用vs2017开发,我使用vs开发qt的项目,虽然vs自带的单元测试现在配置少了许多,不过还是需要导入.props文件,测试时需要将应用程序工程改为静态库工程,我qt的.props配置只导入include,这样,工程里面的include就需要一级目录。后来在网上找到doctest轻量级测试框架,详细介绍可以看C++单元测试工具——doctest_liao20081228的博客-CSDN博客_doctest,写的很详细。
doctest的导入很简单,只需要将doctest.h文件放入工程目录,在用#include"doctest.h"即可,无需其他配置。
我觉得doctest最大的优点无需新建测试工程,特别是第三方库很多的工程,每次配置环境都是折磨,测试代码和源码在同一文件。
因为doctest测试代码与生产代码放在同一cpp文件,看文章说也可以像gtest一样另写测试文件,只是这样就放弃doctest的优势。我希望在正式编译时,可以去掉测试代码,看文档说,定义DOCTEST_CONFIG_DISABLE标识符可以从二进制执行文件中删除与测试相关的所有内容。我使用的时候,定义DOCTEST_CONFIG_DISABLE后,会编译报错,
#define DOCTEST_CONFIG_DISABLE
#define DOCTEST_CONFIG_IMPLEMENT
DOCTEST_CONFIG_DISABLE需要放在DOCTEST_CONFIG_IMPLEMENT前面,运行时才不会进行测试。
使用 #define DOCTEST_CONFIG_IMPLEMENT,这样的好处是可以配置一些选项,我将一些常用设置写在注释中,这样工程在main.cpp中的代码为
#include "mainWin.h"
#include <QApplication>
#include <vtkOutputWindow.h>
#include "def.h"
#define DOCTEST_CONFIG_IMPLEMENT
#include "doctest.h"
int main(int argc, char *argv[])
{
//去掉vtk报错窗口
//vtkOutputWindow::SetGlobalWarningDisplay(0);
QApplication a(argc, argv);
MainWin w;
w.show();
w.showMaximized();
doctest::Context context;
context.applyCommandLine(argc, argv);
// defaults 设置测试选项
// context.addFilter("test-case",
// "*common*"); // test cases with "common" intheir
// // name defaults 设置测试选项
// context.addFilter(
// "test-suite-exclude",
// "*utils*"); // exclude test cases with "utils" in their name
// context.setOption("abort-after",
// 5); // stop test execution after 5 failed assertions
context.setOption("order-by", "name"); // sort the test cases by their name
//默认是控制台输出,console,配合out可以将结果生成为xml文件
// context.setOption("reporters",
// "xml"); // Output reporters
// context.setOption("out",
// "myreporter.xml"); // Output file name
context.setOption("order-by", "name");
int res = context.run(); // run doctest
if (context.shouldExit()) {
}
int ret = a.exec();
return ret;
}
注意 #define DOCTEST_CONFIG_IMPLEMENT要在#include "doctest.h"前面,def.h文件为
移除测试代码时,将两个宏注释去掉。
有时候,想要让cpp文件里的测试代码不要生效, doctest提供一个宏DOCTEST_LIBRARY_INCLUDED,可以在.cpp中使用#ifdef DOCTEST_LIBRARY_INCLUDED和#endif将测试代码包含,这样只有在cpp文件有#include "doctest.h"这一句代码时,测试代码才会有效。
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "common.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>
#include "doctest.h"
using namespace doctest;
Common::Common() {}
bool Common::Init() {
bool init = true;
return init;
}
#ifdef DOCTEST_LIBRARY_INCLUDED
TEST_CASE("factorial") {
Common com;
CHECK(com.factorial(1) == 1);
INFO("common factorial");
CHECK(false);
}
#endif
当然,我写的这些也是比较浅,更详细的特性示例在doctest自带的例子里。我也主要是用它做单元测试,