doctest+FakeIt+nanobench(现代C++测试工具链)可以完美地替代gtest/gmock和google bench
没有任何依赖,无需安装,直接包含头文件就可以用,非常容易集成和使用
doctest
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN#include "doctest.h"TEST_CASE("vectors can be sized and resized") {std::vector<int> v(5);REQUIRE(v.size() == 5);REQUIRE(v.capacity() >= 5);SUBCASE("adding to the vector increases it's size") {v.push_back(1);CHECK(v.size() == 6);CHECK(v.capacity() >= 6);}SUBCASE("reserving increases just the capacity") {v.reserve(6);CHECK(v.size() == 5);CHECK(v.capacity() >= 6);}}
SUBCASE
- 允许在当前case下增加更多的子case去测试一些special一些的东西,非常实用,这也是相比gtest更好的一个地方。
断言宏
- CHECK宏是只检查并不会终止测试
- REQUIRE宏则会终止测试和gtest里面的ASSET_XX宏类似
这两个宏也是平时做单测时用得最多的两个宏了
除此之外,还有更丰富的宏。比如:
<LEVEL> is one of 3 possible: REQUIRE/CHECK/WARN.<LEVEL>_EQ(left, right) - same as <LEVEL>(left == right)<LEVEL>_NE(left, right) - same as <LEVEL>(left != right)<LEVEL>_GT(left, right) - same as <LEVEL>(left > right)<LEVEL>_LT(left, right) - same as <LEVEL>(left < right)<LEVEL>_GE(left, right) - same as <LEVEL>(left >= right)<LEVEL>_LE(left, right) - same as <LEVEL>(left <= right)<LEVEL>_UNARY(expr) - same as <LEVEL>(expr)<LEVEL>_UNARY_FALSE(expr) - same as <LEVEL>_FALSE(expr)
判断异常的宏
CHECK_THROWS_AS(func(), const std::exception&);CHECK_THROWS_AS(func(), std::exception); // same as aboveCHECK_THROWS_WITH(func(), "invalid operation!");CHECK_THROWS_WITH_AS(func(), "invalid operation!", std::runtime_error);<LEVEL>_NOTHROW(expression)
Fakelt(Mock库)
用doctest+FakeIt两个header only的库就可以完美替代gtest了。
FakeIt是C++11写的header only的mock库,用起来也很方便:
struct SomeInterface {virtual int foo(int) = 0;virtual int bar(string) = 0;};Mock<SomeInterface> mock;When(Method(mock,foo)).Return(0);SomeInterface &i = mock.get();// Production codei.foo(1);// Verify method mock.foo was invoked.Verify(Method(mock,foo));// Verify method mock.foo was invoked with specific arguments.Verify(Method(mock,foo).Using(1));
nanobench
nanobench也是C++11写的header only的库,使用起来也很简单,包含头文件即可。
#define ANKERL_NANOBENCH_IMPLEMENT#include <nanobench.h>int main() {double d = 1.0;ankerl::nanobench::Bench().run("some double ops", [&] {d += 1.0 / d;if (d > 5.0) {d -= 5.0;}ankerl::nanobench::doNotOptimizeAway(d);});}
