Googleテストで、さまざまなテストケースで使用するテストフィクスチャを指定したいと思います。フィクスチャは、クラスTheClass
およびそのデータ管理クラスTheClassData
のオブジェクトを割り当ておよび割り当て解除します。データ管理クラスは、データファイルの名前を必要とします。
テストごとに、ファイル名は異なる必要があります。
次のフィクスチャを定義しました:
class TheClassTest : public ::testing::Test {
protected:
TheClassTest(std::string filename) : datafile(filename) {}
virtual ~TheClassTest() {}
virtual void SetUp() {
data = new TheClassData(datafile);
tc = new TheClass(data);
}
virtual void TearDown() {
delete tc;
delete data;
}
std::string datafile;
TheClassData* data;
TheClass* tc;
};
現在、異なるテストでは、異なるファイル名のフィクスチャを使用する必要があります。これをテスト環境のセットアップと想像してください。
質問:テストからファイル名を指定するにはどうすればよいですか、つまり、フィクスチャのデフォルト以外のコンストラクタを呼び出す方法は?
::testing::TestWithParam<T>
やTEST_P
のようなものが見つかりましたが、1つのテストを異なる値で実行するのではなく、1つのフィクスチャで異なるテストを実行する必要があるため、役に立ちません。
別のユーザーが提案したように、デフォルト以外のコンストラクターを使用してフィクスチャーをインスタンス化しても、希望どおりの結果は得られません。ただし、他の方法もあります。単にSetUp
関数をオーバーロードし、テストでそのバージョンを明示的に呼び出します。
class TheClassTest : public ::testing::Test {
protected:
TheClassTest() {}
virtual ~TheClassTest() {}
void SetUp(const std::string &filename) {
data = new TheClassData(filename);
tc = new TheClass(data);
}
virtual void TearDown() {
delete tc;
delete data;
}
TheClassData* data;
TheClass* tc;
};
テストでは、このオーバーロードを使用してファイル名を設定します。
TEST_F(TheClassTest, MyTestCaseName)
{
SetUp("my_filename_for_this_test_case");
...
}
パラメータなしのTearDown
は、テストが完了すると自動的にクリーンアップされます。
現在のクラスをフィクスチャの基本クラスとして使用します。
class TheClassTestBase : public ::testing::Test {
protected:
TheClassTestBase(std::string filename) : datafile(filename) {}
...
};
特定のファイル名ごとに、派生フィクスチャを使用します。
class TheClassTestForFooTxt : public TheClassTestBase {
protected:
TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {}
};
ただし、これはすべてのパラメーターセットに必要な追加の手順です。したがって、テンプレートまたはマクロを使用して、少ない労力でそれを実行できます。お気に入り:
template <typename ClassTestTag>
struct ClassTestParams
{
static std::string filename;
};
template<typename ClassTestTag>
class TheClassTest : public TheClassTestBase {
protected:
TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {}
};
次に、すべてのパラメータセットについて、次のようにします。
class FooTxtTag {};
template <> std::string ClassTestParams<FooTxtTag>::value = "foo.txt";
using TheClassTestForFooTxt = TheClassTest<FooTxtTag>;
TEST_F(TheClassTestForFooTxt, xxxx) {}
ただし、特定のケースでは GoogleTest:type-parameterized-tests も試してみます。
これに対処するもう1つの優れた方法は、フィクスチャを拡張し、拡張されたクラスで、必要な引数で古いコンストラクタを呼び出す新しいデフォルトコンストラクタを提供することです。例えば:
struct MySpecializedTestFixture : public GenericTestFixture
{
MySpecializedTestFixture() : GenericTestFixture("a thing", "another thing") {}
};
TEST_F(MySpecializedTestFixture, FancyTest)
{
// Use the thing environment and make some assertions.
}
この特定のケースでは、テストフィクスチャを完全に取り除くほうがはるかに簡単だと思います。 SetUp
関数は、代わりに、必要なファイル名でクラスをインスタンス化するヘルパー関数で置き換えることができます。これにより、TEST_P
またはTEST_F
の代わりにTEST
を使用できます。これで、各テストケースはスタンドアロンテストになり、ヘルパー関数を使用して、またはテストケースの本文に直接、独自のテストクラスインスタンスを作成します。
例えば:
using namespace testing;
TEST(FooClassTest, testCase1)
{
FooClass fooInstance("File_name_for_testCase1.txt");
/* The test case body*/
delete fooInstance;
}
提案されているようにSetUp
メソッドをオーバーロード here し、オーバーロードしたSetUp
を必ず使用するようにしたい場合は、TearDown
メソッドでアサーションを使用できます。
class my_fixture : public ::testing::Test
{
protected:
bool SETUP_HIT_FLAG = false;
void SetUp(double parameter)
{
...
SETUP_HIT_FLAG = true;
}
void TearDown() override
{
assert(SETUP_HIT_FLAG && "You forgot to call SetUp with your parameter!");
}
};