目的

程序开发中测试是非常重要的一个部分,代码的测试通常需要一些测试框架,Cpputest是一个可以用于C/C++开发的测试框架,比较轻量,所以也常常用于嵌入式系统程序开发。这篇文章将对Cpputest入门使用进行说明。

在这里插入图片描述

CppUTest is a C/C++ based unit xUnit test framework for unit testing and for test-driving your code. It is written in C++ but is used in C and C++ projects and frequently used in embedded systems but it works for any C/C++ project.

CppUTest是一个基于C/C++的单元测试框架,用于单元测试和测试驱动开发。它是用C++编写的,但可以用于C和C++项目,并经常在嵌入式系统中使用。

官方页面: https://cpputest.github.io/
项目地址: https://github.com/cpputest/cpputest

快速入门

Cpputest可以在各个平台上使用,可以使用编译好的二进制文件,也可以直接以源码形式使用。这里使用的版本是 Nov 22, 2021 自动发布的版本(v4.0+)进行介绍。

下载了Cpputest的项目后其本身就集成了多个直接可用的项目,Windows上用 Visual Studio 直接就可以打开用:
在这里插入图片描述

CommandLineTestRunner::RunAllTests(ac, av); 这里会加载一个个的测试用例进行测试,测试用例是按组进行的,每个组下面可以有多个测试。每个组有组名,每个测试有测试名,这里随便找一个文件进行测试:
在这里插入图片描述

上面图片中 printf("\n%s %s %d", __FILE__, __FUNCTION__, __LINE__); 是我添加的代码,方便观察:
在这里插入图片描述
从上面的测试可以知道:

  • TEST_GROUPTEST 都是一些宏,实际会被替换成类和方法;
  • 每一个测试都会先运行 setup() ,然后运行 testBody(TEST所定义的内容) ,最后运行 teardown
  • 一组中 TEST 编写的顺序和运行的顺序并不是从上至下的(好像是从下至上的?);
  • CHECK_EQUAL 等都是一些断言,用于测试条件或结果比对;

各种宏和断言可以从官方文档中获取到:
https://cpputest.github.io/manual.html

Most commonly used Test Macros

  • TEST(group, name) - define a test
  • IGNORE_TEST(group, name) - turn off the execution of a test
  • TEST_GROUP(group) - Declare a test group to which certain tests belong. This will also create the link needed from another library.

Assertions

  • CHECK(boolean condition) - checks any boolean result.
  • CHECK_TEXT(boolean condition, text) - checks any boolean result and prints text on failure.
  • CHECK_EQUAL(expected, actual) - checks for equality between entities using . So if you have a class that supports operator() you can use this macro to compare two instances. You will also need to add a StringFrom() function like those found in SimpleString. This is for printing the objects when the check failed.
  • STRCMP_EQUAL(expected, actual) - checks const char* strings for equality using strcmp().
  • STRNCMP_EQUAL(expected, actual, length) - checks const char* strings for equality using strncmp().
  • STRCMP_CONTAINS(expected, actual) - checks whether const char* actual contains const char* expected.
  • LONGS_EQUAL(expected, actual) - compares two numbers.
  • UNSIGNED_LONGS_EQUAL(expected, actual) - compares two positive numbers.
  • BYTES_EQUAL(expected, actual) - compares two numbers, eight bits wide.
  • POINTERS_EQUAL(expected, actual) - compares two pointers.
  • DOUBLES_EQUAL(expected, actual, tolerance) - compares two floating point numbers within some tolerance
  • FUNCTIONPOINTERS_EQUAL(expected, actual) - compares two void (*)() function pointers
  • MEMCMP_EQUAL(expected, actual, size) - compares two areas of memory
  • BITS_EQUAL(expected, actual, mask) - compares expected to actual bit by bit, applying mask
  • FAIL(text) - always fails

从源码构建测试项目

Cpputest的项目中源码相关的最主要需要关注的就下面一些:
在这里插入图片描述

下面在 Ubuntu 上演示从源码构建测试项目,环境准备可以参考下面文章:
https://blog.csdn.net/Naisu_kun/article/details/136787119

创建项目如下:
在这里插入图片描述
cpputest 可以直接从 git 克隆:git clone https://github.com/cpputest/cpputest.git

test2.cpp 代码如下:

#include "CppUTest/TestHarness.h"

TEST_GROUP(Test2)
{
   void setup() 
   {
        printf("\n%s %s %d", __FILE__, __FUNCTION__, __LINE__);
   }

   void teardown() 
   {
        printf("\n%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
   }
};

TEST(Test2, SuccessTest)
{
    printf("\n%s %s %d", __FILE__, __FUNCTION__, __LINE__);
   CHECK(true);
}

main.cpp 代码如下(这个直接就是例程的 AllTests.cpp 的代码):

#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/TestMemoryAllocator.h"
#include "CppUTest/SimpleStringInternalCache.h"

#define SHOW_MEMORY_REPORT 0

int main(int ac, char **av)
{
    int returnValue = 0;
    GlobalSimpleStringCache stringCache;

    {
        /* These checks are here to make sure assertions outside test runs don't crash */
        CHECK(true);
        LONGS_EQUAL(1, 1);

#if SHOW_MEMORY_REPORT
        GlobalMemoryAccountant accountant;
        accountant.start();
#endif

        returnValue = CommandLineTestRunner::RunAllTests(ac, av); /* cover alternate method */

#if SHOW_MEMORY_REPORT
        accountant.stop();
        printf("%s", accountant.report().asCharString());
#endif
    }

    return returnValue;
}

CMakeLists.txt 代码如下:

# 最低CMake版本要求
cmake_minimum_required(VERSION 3.21)

# 项目名称
project(test)

#编译选项
#add_compile_options(-std=c++11)

# cpputest头文件和源文件
include_directories(cpputest/include)
aux_source_directory(cpputest/src/CppUTest CPPUTEST_SRC_LIST)
aux_source_directory(cpputest/src/Platforms/Gcc/ CPPUTEST_SRC_LIST)

# 测试用例头文件和源文件
include_directories(mytest)
aux_source_directory(mytest MYTEST_SRC_LIST)

#将所有源文件生成一个可执行文件
add_executable(test main.cpp ${MYTEST_SRC_LIST} ${CPPUTEST_SRC_LIST})

编译和执行情况如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

test1因为被设置成了 IGNORE_TEST 所以并不会运行,如果把它设置成普通的 TEST ,那么就会看到该用例测试不通过:
在这里插入图片描述

总结

Cpputest入门使用来说还是比较简单的,更多内容参考官方页面中各个文档即可了解。

同类型的测试框架比较出名的还有 Unity(不是3D引擎那个):
项目地址: https://github.com/ThrowTheSwitch/Unity

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐