当前位置: 首页 > 工具软件 > doctest > 使用案例 >

doctest使用心得

纪畅
2023-12-01

        最近使用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自带的例子里。我也主要是用它做单元测试,

 类似资料: