[[https://github.com/catchorg/Catch2|Site Web]] Catch2 permet de créer des tests unitaires. =====Exemples===== ====Test de base==== #include #include uint32_t factorial( uint32_t number ) { return number <= 1 ? number : factorial(number-1) * number; } TEST_CASE("Factorials are computed", "[factorial]") { REQUIRE(factorial( 1) == 1); REQUIRE(factorial( 2) == 2); REQUIRE(factorial( 3) == 6); REQUIRE(factorial(10) == 3628800); SECTION("section1") { std::vector v(5); v.resize(10); REQUIRE(v.size() == 10); REQUIRE(v.capacity() >= 10); }} L'usage de ''SECTION'' permet de créer des sous cas tests qui peuvent être désactivés via ''%%--section
%%'' lors de l'appel du programme tests en ligne de commande. Pour les cas courants, il n'y a pas besoin d'avoir une méthode ''main''. Si suffit de se lier avec la target ''CMake'' ''Catch2WithMain''. Toutes les macros de tests ''REQUIRE'' et autres ne s'utilisent qu'à l'intérieur d'un ''TEST_CASE'' et donc le main de Catch2. ====Benchmark==== TEST_CASE("Benchmark Fibonacci", "[!benchmark]") { REQUIRE(fibonacci(5) == 5); REQUIRE(fibonacci(20) == 6765); BENCHMARK("fibonacci 20") { return fibonacci(20); }; REQUIRE(fibonacci(25) == 75025); BENCHMARK("fibonacci 25") { return fibonacci(25); }; BENCHMARK_ADVANCED("Warmup") (Catch::Benchmark::Chronometer meter) { warm_up_each_execution(); meter.measure( [] { .... } }); }; } Il faut passer par ''BENCHMARK_ADVANCED'' pour ne mesurer que certaines parties du code qui doit être exécutées. ===Nombre d'exécutions=== Les benchmarks sont exécutés 100 fois par défaut. Tous les benchmarks vont être exécutés le même nombre de fois. Ce n'est pas personnalisable individuellement [[https://github.com/catchorg/Catch2/issues/1711|Github 1711]]. C'est modifiable en passant ''%%--benchmark-samples 10%%'' en ligne de commande. Ou encore, c'est modifiable dans le code: class ConfigDataSession : public Catch::Session { public: ConfigDataSession() { auto& config_data = configData(); config_data.benchmarkSamples = 10; } }; int main(int argc, char* argv[]) { ConfigDataSession session; return session.run(argc, argv); } Dans ce dernier cas, le binaire doit se lier avec ''Catch2'' et non plus ''Catch2WithMain''. ===Récupérer les résultats des tests=== Il faut ajouter un Listener. namespace { size_t byte_count = 0; } class ComputeBandwidthReporter : public Catch::EventListenerBase { public: using Catch::EventListenerBase::EventListenerBase; void benchmarkEnded(Catch::BenchmarkStats<> const& benchmark_stats) override { std::cout << "\n[speed] " << byte_count / (benchmark_stats.mean.point.count() / 1000000000) / 1024 / 1024 << "Mo/s\n"; } }; CATCH_REGISTER_LISTENER(ComputeBandwidthReporter) Le listener étant un objet global, il n'est pas possible de lui passer des paramètres. Dans mon cas, je passe par un objet global. Les temps du benchmark sont en nanosecondes. =====Intégration===== ====CMake==== find_package(Catch2 REQUIRED) target_link_libraries(target_test PRIVATE Catch2::Catch2WithMain)