在运行时检测 Catch2 中的特定标签匹配
Detect specific tag match in Catch2 at runtime
我在我的 Catch2 项目中进行了集成测试,该测试依赖于正在设置的一些昂贵的全局状态。我只想在测试运行器实际测试依赖它的系统时才初始化该全局状态。
我所看到的工作,但它有点可怕......它取决于 Catch 配置中相当多的实现细节。
这是我的主要内容:
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
...
int main(int argc, const char* argv[])
{
// Construct a fake TestCaseInfo to match against the [integration] tag
const char * expensive_tag = "integration";
Catch::SourceLineInfo fake_source_line("?", 0)
Catch::TestCaseInfo fake_test_case("?", "?", "?", {expensive_tag}, fake_source_line);
Catch::Session session;
session.applyCommandLine(argc, argv);
auto test_spec = session.config().testSpec();
const bool want_integration_tests = test_spec.matches(fake_test_spec);
if(want_integration_tests)
{
do_expensive_setup();
}
return session.run();
}
然后我的测试文件就是:
#include "catch.hpp"
...
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
REQUIRE(expensive_setup_is_done());
SECTION("has property 1") { ... }
SECTION("has property 2") { ... }
...
}
请注意,因为有多个部分(在我的实际项目中,有多个测试用例)依赖于全局设置,所以我不能只将初始化移到 TEST_CASE
的顶部。
有没有更好的方法?
只需按需进行初始化,使用 std::call_once
:
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
static std::once_flag init_flag;
std::call_once(init_flag, do_expensive_setup);
// ...
}
这将确保 do_expensive_setup
仅在需要时被调用一次。如果有多个地方需要这个设置,只需将其包装在一个函数中即可。
请注意,如果 do_expensive_setup
抛出,它可能会被调用第二次。但是一旦函数成功退出,就是这样。
我在我的 Catch2 项目中进行了集成测试,该测试依赖于正在设置的一些昂贵的全局状态。我只想在测试运行器实际测试依赖它的系统时才初始化该全局状态。
我所看到的工作,但它有点可怕......它取决于 Catch 配置中相当多的实现细节。
这是我的主要内容:
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
...
int main(int argc, const char* argv[])
{
// Construct a fake TestCaseInfo to match against the [integration] tag
const char * expensive_tag = "integration";
Catch::SourceLineInfo fake_source_line("?", 0)
Catch::TestCaseInfo fake_test_case("?", "?", "?", {expensive_tag}, fake_source_line);
Catch::Session session;
session.applyCommandLine(argc, argv);
auto test_spec = session.config().testSpec();
const bool want_integration_tests = test_spec.matches(fake_test_spec);
if(want_integration_tests)
{
do_expensive_setup();
}
return session.run();
}
然后我的测试文件就是:
#include "catch.hpp"
...
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
REQUIRE(expensive_setup_is_done());
SECTION("has property 1") { ... }
SECTION("has property 2") { ... }
...
}
请注意,因为有多个部分(在我的实际项目中,有多个测试用例)依赖于全局设置,所以我不能只将初始化移到 TEST_CASE
的顶部。
有没有更好的方法?
只需按需进行初始化,使用 std::call_once
:
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
static std::once_flag init_flag;
std::call_once(init_flag, do_expensive_setup);
// ...
}
这将确保 do_expensive_setup
仅在需要时被调用一次。如果有多个地方需要这个设置,只需将其包装在一个函数中即可。
请注意,如果 do_expensive_setup
抛出,它可能会被调用第二次。但是一旦函数成功退出,就是这样。