超轻量级c++单元测试框架Catch2

与googletest简单对比

之前工作中做单元测试,一直用的是googletest,使用时只需要下载源码编译出库,在测试工程中引用即可,googletest提供了很多宏来让我们很轻松的组织测试用例。
前段时间公司让研究适合项目的单元测试框架,然后就发现了Catch2,Catch2比googletest使用更简单,源码就一个头文件,使用时只需要将Catch2.hpp引用到工程中即可,基本的测试用例组织方法与googletest相似;对于测试夹具,个人认为Catch提供的TEST_CASE+SECTION更简单。

Catch2简单用法

环境配置

下载头文件Catch2.hpp即可,不需要其他配置。

第一个测试用例

新建一个空工程,然后加入待测代码,这里是一个简单的计算器类calculator.h:

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }

    int minus(int a, int b) {
        return a - b;
    }

    int multiply(int a, int b) {
        return a * b;
    }

    int division(int a, int b) {
        return a / b;
    }
};

#endif // CALCULATOR_H

下面是简单的测试用例main.cpp:

#define CATCH_CONFIG_MAIN // 该宏用于生成Catch2的main函数

#include "../catch.hpp"
#include "calculator.h"

TEST_CASE("Test add function", "[calculator.add]") {
    Calculator calc;
    REQUIRE(calc.add(1, 2) == 3);
    REQUIRE_FALSE(calc.add(1, 2) == 4);
}

可以看到测试框架部分仅:

#define CATCH_CONFIG_MAIN // 该宏用于生成Catch2的main函数
#include "../catch.hpp"

然后测试用例使用TEST_CASE宏组织:

TEST_CASE("Test add function", "[calculator.add]")

TEST_CASE宏的参数都是字符串,参数1是用例名称,参数2是标签名称(标签名称注意要使用[]括起来)。
注意:用例名称不能重复,标签名可以重复
测试用例中子逻辑使用REQUIRE宏进行判断。

 REQUIRE(calc.add(1, 2) == 3);

这样,一个简单的测试用例就完成了,运行效果是这样:

halo@halo:build-test-unknown-Debug$ ./test
=================================================================
All tests passed (2 assertions in 1 test case)

所有用例通过,共一条用例,该条用例包含2条断言。
再看下用例不通过的情况:

halo@halo:build-test-unknown-Debug$ ./test
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test is a Catch v2.12.2 host application.
Run with -? for options

-------------------------------------------------------------------------------
Test add function
-------------------------------------------------------------------------------
../test/main.cpp:6
...............................................................................

../test/main.cpp:9: FAILED:
  REQUIRE_FALSE( calc.add(1, 2) == 3 )
with expansion:
  !(3 == 3)

================================================================
test cases: 1 | 1 failed
assertions: 2 | 1 passed | 1 failed

可以看出第二条用例失败了。
目前来看的话,基础的测试用例组织与googletest用法类似。

Catch2之SECTION

前面说过,SECTION可以完成测试夹具之类的工作,我们来看一个简单的例子:

TEST_CASE("Test multiply function", "[calculator.multiply]") {
   Calculator calc;
   std::cout << "init" << std::endl;
   SECTION("hello") {
       std::cout << "SECTION hello" << std::endl;
       REQUIRE(calc.multiply(1, 2) == 2);
   }
   SECTION("world") {
       std::cout << "SECTION world" << std::endl;
       REQUIRE(calc.multiply(2, 2) == 4);
   }
   std::cout << "end" << std::endl;
}

运行结果:

halo@halo:build-test-unknown-Debug$ ./test
init
SECTION hello
end
init
SECTION world
end
====================================================
All tests passed (2 assertions in 1 test case)

我在代码里打印了一些标记,从标记的输出我们可以发现,每个SECTION都输出了init和end,说明他们是共享SECTION定义之外的代码,并且是独立运行的,执行顺序就是SECTION的定义顺序。使用时我们就要注意:对于SECTION之外的代码,仅是代码共享,运行时不相关,每一个SECTION都会运行一遍
另外,SECTION是可以嵌套的,就是可以在SECTION里面再定义SECTION。

其他

BDD(行为驱动开发)方式组织用例

一般情况下,掌握基础用法和SECTION基本够用了。
Catch2还提供了一种BDD方式的用例组织方式,我们简单看下:

SCENARIO("I want to test", "Calculator") {
    GIVEN("A calculator") {
        Calculator calc;
        WHEN("I add 1 and 2") {
            int a = calc.add(1, 2);
            THEN("the result must be correct") {
                REQUIRE(a == 3);
            }
        }
    }
}

我们简单白话一下:

场景:我想测试下计算器
	给定一个计算器
		--定义一个计算器
		当计算1+2时
			--使用计算器进行1+2计算
			然后结果必须正确
				--判断结果是否正确

大概这样子。

指定运行部分用例

我们前面在写用例时,提到TEST_CASE有2个参数,在我们测试程序编好之后,我们可以通过命令行参数来控制运行哪部分用例。
运行指定名称的用例:

halo@halo:build-test-unknown-Debug$ ./test "Test add function"
Filters: Test add function
=================================================================
All tests passed (2 assertions in 1 test case)

运行指定tag的用例:

halo@halo:build-test-unknown-Debug$ ./test [calculator.add]
Filters: [calculator.add]
=================================================================
All tests passed (2 assertions in 1 test case)

在增量开发或者修改bug时并不需要跑完全部用例,那在我们提交代码时,可以带上tag,CI上根据tag去跑对应的用例,是不是看起来很有用~~

总结

Catch2的环境配置和用例组织都相当简单,有需求的话大胆的使用吧,Catch2还有很多其他的特性,可以去github看看官方文档。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值