#头文件
#include "co/unitest.h"
#API
公开函数只有一个,在 co 命名空间:
int co::run_unitests();
- 运行单元测试,返回失败用例数;
main一般是固定写法:
#include "co/unitest.h"
int main(int argc, char** argv) {
flag::parse(argc, argv);
co::run_unitests();
return 0;
}
#定义测试单元
DEF_test(name) {
// 测试代码
// DEF_case(xxx) {}
}
DEF_test宏定义一个测试单元,实际是一个函数,用户可以在其中自由添加代码,如各测试用例共用的初始化代码;name必须是合法变量名;- 有多个
DEF_test时,name不能重复。
#定义测试用例
DEF_case(name) {
// 测试用例代码
}
DEF_case宏定义一个测试用例,实际是DEF_test所定义函数中的代码块;name不要求是合法变量名;DEF_test中不含任何DEF_case时,会创建一个默认测试用例。
#EXPECT 宏
EXPECT(x)
EXPECT_EQ(x, y) // ==
EXPECT_NE(x, y) // !=
EXPECT_GE(x, y) // >=
EXPECT_LE(x, y) // <=
EXPECT_GT(x, y) // >
EXPECT_LT(x, y) // <
- 失败信息在最后统一汇总。
EXPECT_XX中参数需要支持相应比较运算符,且可打印,即支持:operator<<(co::string&, const T&);
#运行逻辑
- 每个
DEF_test内部定义一个 bool flag,默认值false。 - 若所有测试单元 flag 都是默认值,则运行所有测试单元。
- 若有 flag 为
true,则只运行 flag 为true的测试单元。 - 测试单元按注册顺序执行。
#示例
#include "co/unitest.h"
DEF_test(math) {
DEF_case(add) {
EXPECT_EQ(1 + 1, 2);
EXPECT_NE(1 + 1, 3);
EXPECT_GT(2, 1);
EXPECT_LT(1, 2);
EXPECT_GE(2, 2);
EXPECT_LE(2, 2);
EXPECT(1 + 1 == 2);
}
DEF_case(mul) {
EXPECT_EQ(2 * 3, 6);
EXPECT_NE(2 * 3, 5);
}
}
DEF_test(string) {
co::string s;
// 不在 DEF_case 中,默认测试用例
EXPECT(s.empty());
DEF_case(empty) {
EXPECT(s.empty());
}
DEF_case(size) {
s = "hello";
EXPECT_EQ(s.size(), 5);
}
}
int main(int argc, char** argv) {
flag::parse(argc, argv);
co::run_unitests();
return 0;
}
运行:
./xx # 运行 math 和 string 两个单元
./xx -math # 只运行 math
./xx -string # 只运行 string
#构建及运行 coost 内部单元测试
unitest 目录下是 coost 内部单元测试代码,在 coost 根目录执行下述命令构建及运行:
# 构建
xmake b unitest
# 默认运行所有单元测试代码
xmake r unitest
# 仅运行指定的测试单元
xmake r unitest -os -json
测试结果示例:
- 测试全部通过

- 测试用例未通过
