CPPTest实例分析(C++ Test)

news/2024/10/9 13:31:24/

1 概述

  CppTest是一个可移植、功能强大但简单的单元测试框架,用于处理C++中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式,并且可以轻松添加新的输出格式。

CppTest下载地址:下载地址1  下载地址2

下面结合实例分析下CppTest如何使用。

2 实例

利用CppTest编写单元测试用例需要从Suite类派生(这里Suite翻译为组),CppTest所有类型命名空间是Test。
实例选择CppTest源码中自带的例子。

2.1 无条件失败测试用例

测试用例组定义如下:

#include "cpptest.h"// Tests unconditional fail asserts
//
class FailTestSuite : public Test::Suite
{
public:FailTestSuite(){TEST_ADD(FailTestSuite::success)TEST_ADD(FailTestSuite::always_fail)}
private:void success() {}void always_fail(){// This will always fail//TEST_FAIL("unconditional fail");}
};

说明:

  • 类型FailTestSuite从Test::Suite派生
  • 在构造函数中通过宏TEST_ADD增加两个测试用例success和always_fail
  • success函数什么也不作做所以是成功的
  • always_fail函数调用TEST_FAIL宏报告一个无条件失败。

2.2 比较测试用例

测试用例组定义如下:

class CompareTestSuite : public Test::Suite
{
public:CompareTestSuite(){TEST_ADD(CompareTestSuite::success)TEST_ADD(CompareTestSuite::compare)TEST_ADD(CompareTestSuite::delta_compare)}
private:void success() {}void compare(){// Will succeed since the expression evaluates to true//TEST_ASSERT(1 + 1 == 2)// Will fail since the expression evaluates to false//TEST_ASSERT(0 == 1);}void delta_compare(){// Will succeed since the expression evaluates to true//TEST_ASSERT_DELTA(0.5, 0.7, 0.3);// Will fail since the expression evaluates to false//TEST_ASSERT_DELTA(0.5, 0.7, 0.1);}
};

说明:

  • 类型CompareTestSuite从Test::Suite派生
  • 在构造函数中通过宏TEST_ADD增加三个测试用例success, compare和delta_compare
  • success函数什么也不作做所以是成功的
  • compare函数调用TEST_ASSERT宏判断条件是否成立,如果条件失败报告错误。
  • delta_compare函数调用TEST_ASSERT_DELTA宏判断条件是否成立,第一次调用满足0.7 > (0.5 - 0.3) && 0.7 < (0.5 + 0.3)所以是成功的,第二次调用不满足0.7 > (0.5 - 0.1) && 0.7 < (0.5 + 0.1)所以报告失败。

2.3 异常测试用例

测试用例组定义如下:

class ThrowTestSuite : public Test::Suite
{
public:ThrowTestSuite(){TEST_ADD(ThrowTestSuite::success)TEST_ADD(ThrowTestSuite::test_throw)}
private:void success() {}void test_throw(){// Will fail since the none of the functions throws anything//TEST_THROWS_MSG(func(), int, "func() does not throw, expected int exception")TEST_THROWS_MSG(func_no_throw(), int, "func_no_throw() does not throw, expected int exception")TEST_THROWS_ANYTHING_MSG(func(), "func() does not throw, expected any exception")TEST_THROWS_ANYTHING_MSG(func_no_throw(), "func_no_throw() does not throw, expected any exception")// Will succeed since none of the functions throws anything//TEST_THROWS_NOTHING(func())TEST_THROWS_NOTHING(func_no_throw())// Will succeed since func_throw_int() throws an int//TEST_THROWS(func_throw_int(), int)TEST_THROWS_ANYTHING(func_throw_int())// Will fail since func_throw_int() throws an int (not a float)//TEST_THROWS_MSG(func_throw_int(), float, "func_throw_int() throws an int, expected a float exception")TEST_THROWS_NOTHING_MSG(func_throw_int(), "func_throw_int() throws an int, expected no exception at all")}void func() {}void func_no_throw() {}void func_throw_int() { throw 13; }
};

说明:

  • 类型ThrowTestSuite从Test::Suite派生
  • 在构造函数中通过宏TEST_ADD增加两个测试用例success和test_throw
  • success函数什么也不作做所以是成功的
  • 函数func和func_no_throw不会抛异常
  • 函数func_throw_int抛int类型异常13
  • test_throw调用6种宏测试函数调用异常,_MSG后缀版本指定异常文本。
    • TEST_THROWS_MSG 宏测试函数调用如果抛出指定异常则成功,否则失败
    • TEST_THROWS 宏测试函数调用如果抛出指定异常则成功,否则失败
    • TEST_THROWS_ANYTHING_MSG 宏测试函数调用如果抛出任意类型异常则成功,否则失败
    • TEST_THROWS_ANYTHING 宏测试函数调用如果抛出任意类型异常则成功,否则失败
    • TEST_THROWS_NOTHING 宏测试函数调用不抛异常则成功,否则失败
    • TEST_THROWS_NOTHING_MSG 宏测试函数调用不抛异常则成功,否则失败

2.4 测试用例运行

前面定义了三个测试用例组FailTestSuite,CompareTestSuite和ThrowTestSuite,下面将三个测试用例组加到测试程序中。

2.4.1 main

main(int argc, char* argv[])
{try{// Demonstrates the ability to use multiple test suites//Test::Suite ts;ts.add(unique_ptr<Test::Suite>(new FailTestSuite));ts.add(unique_ptr<Test::Suite>(new CompareTestSuite));ts.add(unique_ptr<Test::Suite>(new ThrowTestSuite));// Run the tests//unique_ptr<Test::Output> output(cmdline(argc, argv));ts.run(*output, true);Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());if (html)html->generate(cout, true, "MyTest");}catch (...){cout << "unexpected exception encountered\n";return EXIT_FAILURE;}return EXIT_SUCCESS;
}

说明:

  • 定义测试用例组ts
  • 通过ts函数add将FailTestSuite,CompareTestSuite和ThrowTestSuite加到测试用例组ts中
  • 定义测试输出对象outuput
  • 调用ts函数run运行测试用例,run第二参数cont_after_fail指示出错后是否接着执行,这里设置为true表示出错后接着执行。
  • 如果output是html类型,最后将html内容输出标准输出cout.

2.4.2 usage/cmdline

CppTest的输出格式默认支持四种格式:

  • Compiler 编译器格式
  • Html 网页格式
  • TextTerse 简约文本格式
  • TextVerbose 详细文本格式

可以派生新的输出格式:

  • 从Test::Output类型派生新的输出格式。
  • 从Test::CollectorOutput类型派生新的收集器输出格式。收集器输出格式整个测试用例运行完毕后再输出,HtmlOutput就是收集器输出格式。

下面代码从命令参数获取输出格式:

static void
usage()
{cout << "usage: mytest [MODE]\n"<< "where MODE may be one of:\n"<< "  --compiler\n"<< "  --html\n"<< "  --text-terse (default)\n"<< "  --text-verbose\n";exit(0);
}static unique_ptr<Test::Output>
cmdline(int argc, char* argv[])
{if (argc > 2)usage(); // will not returnTest::Output* output = 0;if (argc == 1)output = new Test::TextOutput(Test::TextOutput::Verbose);else{const char* arg = argv[1];if (strcmp(arg, "--compiler") == 0)output = new Test::CompilerOutput;else if (strcmp(arg, "--html") == 0)output =  new Test::HtmlOutput;else if (strcmp(arg, "--text-terse") == 0)output = new Test::TextOutput(Test::TextOutput::Terse);else if (strcmp(arg, "--text-verbose") == 0)output = new Test::TextOutput(Test::TextOutput::Verbose);else{cout << "invalid commandline argument: " << arg << endl;usage(); // will not return}}return unique_ptr<Test::Output>(output);
}

函数说明:

  • usage 输出命令参数用法
  • cmdline 根据命令参数构造不同类型输出格式。

3 运行

3.1 Compiler输出

$ ./mytest --compiler
mytest.cpp:62: "unconditional fail"
mytest.cpp:89: 0 == 1
mytest.cpp:100: delta(0.5, 0.7, 0.1)
mytest.cpp:122: func() does not throw, expected int exception
mytest.cpp:123: func_no_throw() does not throw, expected int exception
mytest.cpp:124: func() does not throw, expected any exception
mytest.cpp:125: func_no_throw() does not throw, expected any exception
mytest.cpp:139: func_throw_int() throws an int, expected a float exception
mytest.cpp:140: func_throw_int() throws an int, expected no exception at all

3.2 TextTerse输出

$ ./mytest --text-terse
FailTestSuite: 2/2, 50% correct in 0.000005 seconds
CompareTestSuite: 3/3, 33% correct in 0.000005 seconds
ThrowTestSuite: 2/2, 50% correct in 0.000093 seconds
Total: 7 tests, 42% correct in 0.000103 seconds

3.3 TextVerbose输出

$ ./mytest --text-verbose
FailTestSuite: 2/2, 50% correct in 0.000004 secondsTest:    always_failSuite:   FailTestSuiteFile:    mytest.cppLine:    62Message: "unconditional fail"CompareTestSuite: 3/3, 33% correct in 0.000005 secondsTest:    compareSuite:   CompareTestSuiteFile:    mytest.cppLine:    89Message: 0 == 1Test:    delta_compareSuite:   CompareTestSuiteFile:    mytest.cppLine:    100Message: delta(0.5, 0.7, 0.1)ThrowTestSuite: 2/2, 50% correct in 0.000092 secondsTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    122Message: func() does not throw, expected int exceptionTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    123Message: func_no_throw() does not throw, expected int exceptionTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    124Message: func() does not throw, expected any exceptionTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    125Message: func_no_throw() does not throw, expected any exceptionTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    139Message: func_throw_int() throws an int, expected a float exceptionTest:    test_throwSuite:   ThrowTestSuiteFile:    mytest.cppLine:    140Message: func_throw_int() throws an int, expected no exception at allTotal: 7 tests, 42% correct in 0.000101 seconds

3.4 Html格式

html格式输出截图如下:
html格式输出截图


http://www.ppmy.cn/news/1438561.html

相关文章

智能解决装箱问题:使用优化算法实现高效包装

组合优化问题 组合优化&#xff08;Combinatorial Optimization&#xff0c;CO&#xff09;数学优化研究的一个分支。主要关注的是从有限的对象集合中寻找最优解的问题。这个词的由来主要是由“组合”和“优化”两部分构成。“组合”指的是从有限的对象集合中选择一部分的过程…

单机三pxc节点集群,+docker-haproxy2.0负载均衡实现

一.下载 https://www.haproxy.org/download/2.0/src/haproxy-2.0.5.tar.gz 或者在这里下载&#xff08;下面需要的各个配置文件都有&#xff09;&#xff1a; https://download.csdn.net/download/cyw8998/89170129 二.编写文件&#xff0c;制作docker镜像 1.Dockerfile&a…

运行django

确保app被注册 urls.py中编写url 视图对应关系 命令行启动 python manage.py runserver

【Linux】学习记录_15_POSIX信号量

15 POSIX信号量 15.1 POSIX信号量基本概念 信号量&#xff08;Semaphore&#xff09;是一种实现进程/线程间通信的机制&#xff0c;可以实现进程/线程之间同步或临界资源的互斥访问&#xff0c; 常用于协助一组相互竞争的进程/线程来访问临界资源。在多进程/线程系统中&#…

C++ //练习 13.4 假定Point是一个类类型,它有一个public的拷贝构造函数,指出下面程序片段中哪些地方使用了拷贝构造函数:

C Primer&#xff08;第5版&#xff09; 练习 13.4 练习 13.4 假定Point是一个类类型&#xff0c;它有一个public的拷贝构造函数&#xff0c;指出下面程序片段中哪些地方使用了拷贝构造函数&#xff1a; Point global; Point foo_bar(Point arg){Point local arg, *heap ne…

06.JAVAEE之线程4

1.定时器 1.1 定时器是什么 定时器也是软件开发中的一个重要组件. 类似于一个 " 闹钟 ". 达到一个设定的时间之后 , 就执行某个指定好的代码. 约定一个时间,时间到达之后,执行某个代码逻辑, 定时器非常常见,尤其是在进行网络通信的时候, 需要有等待的最大时间&…

WPF之Label

Label在wpf中表示控件的文本标签&#xff0c;并提供访问密钥支持。 常用属性: 属性 HorizontalContentAlignment文本水平内容排列VerticalContentAlignment垂直内容排列width宽height高fontsize字体大小fontfamily字体样式fontwidth字体粗细 具体写法 <Label Width"20…

Projector投影器-Unity使用Projector投影器实现简单的阴影

在Unity中&#xff0c;可以使用Projector投影器来实现简单的阴影效果。Projector投影器是一种用于在场景中投射纹理的组件&#xff0c;可以用来模拟光照、阴影等效果。 要使用Projector投影器实现阴影效果&#xff0c;可以按照以下步骤进行操作&#xff1a; 创建一个空对象&am…