这里的问题是,Catch 旨在降低测试的树状组织,它会自动发现结构的所有叶节点,并使用未经测试的代码路径回调到测试用例中,直到它们都经过测试。叶节点(测试,部分)是独立的。
听起来您想测试存储库- 可以保留一些数据然后将其重新加载的东西。
要在两个不同的场景(序列化之前,序列化之后)重复完全相同的测试,您需要将相同的测试放在某个公共位置并调用该位置。您仍然可以在非测试用例函数中使用相同的 Catch 宏,只要您从测试用例调用它。
一种可能的方法是:
struct TestFixture {
Data data;
Repository repository;
TestFixture() : data(), instance() { }
};
void fillUpData(Data& data) {
// ...
}
void isDataAsExpected(Data& data) {
// Verify that 'data' is what we expect it to be, whether we
// loaded it or filled it up manually
SECTION("Data has ...) {
REQUIRE(data...);
}
}
TEST_CASE_METHOD(TestFixture, "Test with raw data") {
fillUpData(data);
isDataAsExpected(data);
REQUIRE(repository.save(data));
}
TEST_CASE_METHOD(TestFixture, "Operate on serialised data") {
REQUIRE(repository.load(data));
isDataAsExpected(_data);
}
一种可能的替代方法是提供您自己的 main 然后使用命令行参数来控制数据是否首先被序列化。
我能想到的第三种方法是使用 Catch - Generators 的尚未完全就绪的功能:
TEST_CASE("...") {
using Catch::Generators;
int iteration(GENERATE(values(0, 1)));
const bool doSave(iteration == 0);
const bool doLoad(iteration == 1);
Repository repository;
Data data;
if (doLoad) {
REQUIRE(repository.load(data));
} else {
// fill up data
}
REQUIRE(..data..test..);
if (doSave) {
REQUIRE(repository.save(data));
}
}
这种方法的优点是您可以看到流程和测试运行两次(对于两个值),但主要缺点是生成器与 SECTION 和 BDD 样式的功能不兼容。