CPPTest实例分析(C++ Test)

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 return

    Test::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 seconds
        Test:    always_fail
        Suite:   FailTestSuite
        File:    mytest.cpp
        Line:    62
        Message: "unconditional fail"

CompareTestSuite: 3/3, 33% correct in 0.000005 seconds
        Test:    compare
        Suite:   CompareTestSuite
        File:    mytest.cpp
        Line:    89
        Message: 0 == 1

        Test:    delta_compare
        Suite:   CompareTestSuite
        File:    mytest.cpp
        Line:    100
        Message: delta(0.5, 0.7, 0.1)

ThrowTestSuite: 2/2, 50% correct in 0.000092 seconds
        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    122
        Message: func() does not throw, expected int exception

        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    123
        Message: func_no_throw() does not throw, expected int exception

        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    124
        Message: func() does not throw, expected any exception

        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    125
        Message: func_no_throw() does not throw, expected any exception

        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    139
        Message: func_throw_int() throws an int, expected a float exception

        Test:    test_throw
        Suite:   ThrowTestSuite
        File:    mytest.cpp
        Line:    140
        Message: func_throw_int() throws an int, expected no exception at all

Total: 7 tests, 42% correct in 0.000101 seconds

3.4 Html格式

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/568658.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

进程概念(进程第1篇)【Linux复习篇】

目录 1、冯诺依曼体系结构怎么画&#xff1f;中央处理器是什么&#xff1f;存储器是什么&#xff1f;每个部分有什么作用&#xff1f; 2、什么是操作系统&#xff1f; 3、什么叫进程&#xff1f;操作系统如何管理进程的&#xff1f; 4、怎么查看进程&#xff1f; 5、C语言…

springcloud Ribbon的详解

1、Ribbon是什么 Ribbon是Netflix发布的开源项目&#xff0c;Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。 2、Ribbon能干什么 LB负载均衡(Load Balance)是什么&#xff1f;简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达…

AI视频改字个性化祝福豪车装X系统uniapp前端开源源码下载

装X系统源码简介 创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝福视频不再难&#xff01; 想要为你的朋友或家人送上一份特别的祝福&#xff0c;让他们感受到你的真诚与关怀吗&#xff1f;现在&#xff0c; 通过开源的AI视频…

从0到1—POC编写基础篇(二)

接着上一篇 POC常用基础模块 urllib 模块 Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 urllib 包 包含以下几个模块&#xff1a; ●urllib.request - 打开和读取 URL。 ●urllib.error - 包含 urllib.request 抛出的异常。 ●urllib.parse - …

新技术前沿-2024-大型语言模型LLM的本地化部署

参考快速入门LLM 参考究竟什么是神经网络 1 深度学习 1.1 神经网络和深度学习 神经网络是一种模拟人脑神经元工作方式的机器学习算法,也是深度学习算法的基本构成块。神经网络由多个相互连接的节点(也称为神经元或人工神经元)组成,这些节点被组织成层次结构。通过训练,…

【网络安全】在网络中如何对报文和发送实体进行鉴别?

目录 1、报文鉴别 &#xff08;1&#xff09;使用数字签名进行鉴别 &#xff08;2&#xff09;密码散列函数 &#xff08;3&#xff09;报文鉴别码 2、实体鉴别 鉴别(authentication) 是网络安全中一个很重要的问题。 一是要鉴别发信者&#xff0c;即验证通信的对方的确是…

小扎宣布开放 Meta Horizo​​n OS

日前&#xff0c;Meta以“混合现实的新时代”为题的博文宣布向第三方制造商开放Meta Horizon OS&#xff0c;包括华硕、联想和微软Xbox等等&#xff1a; Meta正在朝着为元宇宙建立一个更开放的计算平台的愿景迈出下一步。Meta正在向第三方硬件制造商开放赋能Meta Quest设备的操…

使用 IPAM 解决方案简化分布式网络管理

随着组织在数字领域的全球扩张&#xff0c;分布式网络是不可避免的&#xff0c;这意味着&#xff0c;随着 IT 基础设施的发展&#xff0c;组织需要适应&#xff0c;这包括在不断增长的系统需求、应用程序堆栈、各种协议和安全防御中监控、现代化和简化流程和资源。在有效管理现…

AJAX——案例

1.商品分类 需求&#xff1a;尽可能同时展示所有商品分类到页面上 步骤&#xff1a; 获取所有的一级分类数据遍历id&#xff0c;创建获取二级分类请求合并所有二级分类Promise对象等待同时成功后&#xff0c;渲染页面 index.html代码 <!DOCTYPE html> <html lang&qu…

Pycharm代码规范与代码格式化插件安装

给大家分享两个PyCharm编辑器的插件&#xff0c;分别是pylint与autopep8&#xff0c;主要用来提高我们在使用python进行自动化测试编写以及性能测试脚本编写过程中的代码质量、可读性与美观性。 pylint&#xff1a; ● 代码检查工具&#xff1a;它可以帮助检查代码中的错误、…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233

MaaAssistantArknights/MaaAssistantArknights Stars: 11.6k License: AGPL-3.0 MaaAssistantArknights 是一款《明日方舟》游戏的小助手&#xff0c;基于图像识别技术&#xff0c;支持一键完成全部日常任务。 刷理智、掉落识别及上传企鹅物流智能基建换班、自动计算干员效率…

《ElementPlus 与 ElementUI 差异集合》el-select 差异点,如:高、宽、body插入等

宽度 Element UI 父元素不限制宽度时&#xff0c;默认有个宽度 207px&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#xff1b; Element Plus 父元素不限制宽度时&#xff0c;默认100%&#xff1b; 父元素有固定宽度时&#xff0c;以父元素宽度为准&#x…

哪些因素影响了PCB电路板切割精度?

PCB电路板切割是电子制造过程中一个至关重要的环节&#xff0c;其精度对后续工序的质量和效率具有决定性影响。因此&#xff0c;了解影响PCB电路板切割精度的原因&#xff0c;对于提高电子产品的质量和生产效率具有重要意义。 1. PCB分板机稳定性 PCB分板机的性能直接影响到切…

李沐62_序列到序列学习seq2seq——自学笔记

"英&#xff0d;法”数据集来训练这个机器翻译模型。 !pip install --upgrade d2l0.17.5 #d2l需要更新import collections import math import torch from torch import nn from d2l import torch as d2l循环神经网络编码器。 我们使用了嵌入层&#xff08;embedding l…

广东理工学院携手泰迪智能科技成功部署人工智能实验室

广东理工学院是经国家教育部批准设立的全日制普通本科院校&#xff0c;入选全国应用型人才培养工程培养基地、国家级众创空间试点单位、广东省高校电子商务人才孵化基地。开设34个本科专业&#xff0c;涵盖工学、经济学、管理学、文学、艺术学、教育学等6大学科门类&#xff0c…

【docker】拉取人大金仓KingbaseES数据库镜像速度很慢问题

作为一种新兴的虚拟化方式&#xff0c;Docker 跟传统的虚拟化方式相比具有众多的优势。 对于学习新技术、快速搭建实验环境等是很不错的选择。优势大致总结如下&#xff1a; 1.镜像拉取速度对比 速度前后对比&#xff0c;提升10倍不止&#xff0c;很快将镜像文件下载至本地。 …

Java常见面试题总结

文章目录 1. 什么是线程和进程?2. 请简要描述线程与进程的关系,区别及优缺点&#xff1f;3. 什么是堆和方法区&#xff1f;4. 并发与并行的区别5. 同步和异步的区别6.为什么要使用多线程? 优点&#xff1f;&#xff08;重要&#xff09;7. 使用多线程可能带来什么问题?8. 如…

python爬虫 - 爬取html中的script数据(zum.com新闻信息 )

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法&#xff0c;编写爬虫代码3. 使用re.search 方法&#xff0c;编写爬虫代码 1. 分析页面内容数据格式 &#xff08;1&#xff09;打开 https://zum.com/ &#xff08;2&#xff09;按F12&#xff08;或 在网页上右键 --…

SpringCloud Alibaba--nacos简介和配置管理和登录

目录 一.理论基础 二.nacos 2.1 简介 2.2 安装 三.父项目 三.生产者 3.1 配置依赖 3.2 配置文件 3.3 启动类 3.4 控制类 四.消费者 4.1 配置依赖 4.2 配置文件 4.3 启动类 4.4 feign的接口 五.效果 六.负载均衡--权重算法 6.1重启nacos 6.2 设置权重 6.3 设…