3、catch2测试框架学习
3.1、概念
简单易用,只需要引入一个头文件
测试case可以分割为sections: 每个setcion都是独立的运行单元
BDD式的测试模式:可以使用Given-When-Then section来做BDD测试,行为测试,是一种从用户行为的角度出发的开发方法,他强调使用自然语言来描述系统的方法,并将这些描述转化为可执行的测试用例。
TDD:核心理念就是在编码之前编写好测试用例,
核心的assertion宏来做比较。用标准的C++运算符来做比较,但是可以分解表达式,记录表达式等号左侧和右侧的值。
3.2、实践
获取头文件
运行demo实践
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"
int Factorial( int number ) {
return number <= 1 ? number : Factorial( number - 1 ) * number; // fail
// return number <= 1 ? 1 : Factorial( number - 1 ) * number; // pass
}
TEST_CASE( "Factorial of 0 is 1 (fail)", "[single-file]" ) {
REQUIRE( Factorial(0) == 1 );
}
TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
解析代码:
#define CATCH_CONFIG_MAIN ,这个宏定义了catch的main函数。
TEST_CASE表示一次测试用例在里面实现单元测试逻辑:并且也可以为其取名字或者加标签。
测试名称,必填,字符串类型。可填写任意字符串,需要保证全局唯一。tags,标签名,可选,字符串类型。字符串中需要使用方括号将标签名包含,可填写多个标签。标签名无需全局唯一。标签的意义在于可以使用命令参数指定某个系列的相同标签的测试用例去执行。还有一些特殊标签可以参考Catch2/docs/test-case-and-sections.md at devel ·catchorg/Catch2 (github.com)
Catch2的断言宏很少,核心的只有REQUIRE
和CHECK
这两个。REQUIRE
宏在断言失败时,会退出当前单元测试,不再执行后续代码,而CHECK宏在断言失败后,依旧会执行后续的代码。
在测试用例TEST_CASE内部还有定义section,定义的每个section都是一段独立的逻辑,与其他section无关。section使用宏SECTION
定义,是单独的,顺序执行的。section中可以内嵌任意多个section(受限于堆栈的大小)。可将内嵌section的结构可以理解为一个树结构,树的根节点是单元测试的起始代码,每个含有内嵌section的section都是根的一个子树,没有内嵌section的section是树的叶子节点。Catch2会遍历执行树的所有路径(根到叶子节点),每个路径的执行均与其他路径的执行不相关。
#define CATCH_CONFIG_MAIN
#include <iostream>
#include <vector>
#include "catch2/catch.hpp"
using namespace std;
TEST_CASE("vectors can be sized and resized", "[vector]"){
std::vector<int> v(5);
REQUIRE(v.size() == 5);
REQUIRE(v.capacity() >= 5);
SECTION("resizing bigger changer size and capacity"){
v.resize(10);
REQUIRE(v.size() == 10);
REQUIRE(v.capacity() >= 10);
}
SECTION("resizing smaller changer size and capacity"){
v.resize(0);
REQUIRE(v.size() == 1);
REQUIRE(v.capacity() >= 5
);
}
}