簡體   English   中英

Google 測試:測試按 INSTANTIATE 而不是 test_fixture 安排

[英]Google Test: Tests arranges per INSTANTIATE rather than test_fixture

我對來自 Google 測試框架的參數化測試有疑問。 我有一個正在測試的 class,我想用這個特定的 class 測試的是:

  1. 一系列有效值
  2. 一系列有效值。
  3. 一系列無效值類型。

我的 class 的輸入是字符串,它在內部被轉換為一個 int。

現在我在谷歌測試中得出的結構如下圖所示:

// Class under test
class MyClass
{
    // Class contents
public:
    void MyFunction(std::string input) 
    {
        // Do stuff.
    }
};

class MyClassBaseTest : public ::testing::TestWithParam<std::string>
{};
// In bound values
class MyClassOKTest : public MyClassBaseTest 
{};

INSTANTIATE_TEST_SUITE_P(OKValues,
                         MyClassOKTest,
                         testing::Values(
                            "1", "2", "3"
                         ));

TEST_P(MyClassOKTest, OKValuesTest)
{
    MyClass sut;
}

// Out of bound values
class MyClassOutOfBoundTest : public MyClassBaseTest 
{};

INSTANTIATE_TEST_SUITE_P(OutOfBound,
                         MyClassOutOfBoundTest,
                         testing::Values(
                            "30", "40", "50"
                         ));

TEST_P(MyClassOutOfBoundTest, OutOfBoundValuesTest)
{
    MyClass sut;
}

// Invalid values values
class MyClassInvalidTest : public MyClassBaseTest 
{};

INSTANTIATE_TEST_SUITE_P(Invalid,
                         MyClassInvalidTest,
                         testing::Values(
                            "3.0", "Foo", "Bar"
                         ));

TEST_P(MyClassInvalidTest, InvalidValuesTest)
{
    MyClass sut;
}

我想要實現的是如下所示,我不必重新定義我的 test_fixture 。

// Class under test
class MyClass
{
    // Class contents
public:
    void MyFunction(std::string input) 
    {
        // Do stuff.
    }
};

// In bound values
class MyClassTest : public ::testing::TestWithParam<ParamType>
{};

INSTANTIATE_TEST_SUITE_P(OKValues,
                         MyClassOKTest,
                         testing::Values(
                            "1", "2", "3"
                         ));

TEST_P(OKValues, OKValuesTest)
{
    MyClass sut;
}

// Out of bound values
INSTANTIATE_TEST_SUITE_P(OutOfBound,
                         MyClassOutOfBoundTest,
                         testing::Values(
                            "30", "40", "50"
                         ));

TEST_P(OutOfBound, OutOfBoundValuesTest)
{
    MyClass sut;
}

// Invalid values values
INSTANTIATE_TEST_SUITE_P(Invalid,
                         MyClassInvalidTest,
                         testing::Values(
                            "3.0", "Foo", "Bar"
                         ));

TEST_P(Invalid, InvalidValuesTest)
{
    MyClass sut;
}

我檢查了文檔,看起來 Google Test 不支持這樣的結構。 我的問題是我的初始設置是否是執行此操作的唯一方法,還是我在這里遺漏了什么?

或者,如果有人建議用另一種干凈的方式來構建它,我們將不勝感激。

不可能將單個測試套件的特定TEST_P與特定的INSTANTIATE_TEST_SUITE_P相關聯。 INSTANTIATE_TEST_SUITE_P總是實例化測試套件的所有TEST_P (正如名稱INSTANTIATE_TEST_SUITE_P已經暗示的那樣)。 但是,您通常可以將期望從TEST_P測試中移出並放入實例化中,就像這樣( godbolt 上的實例):

class MyClass
{
public:
    std::optional<int> MyFunction(std::string input) 
    {
        try {
            std::size_t numProcessed = 0;
            int const result = std::stoi(input, &numProcessed);
            if (numProcessed != input.size()) {
                return std::nullopt;
            }
            return result;
        }
        catch (std::invalid_argument const &){
            return std::nullopt;
        }
    }
};

struct Params
{
    std::string input;
    bool expectation;
};

std::ostream& operator<<(std::ostream & out, Params const & p) {
    return out << "{input=\"" << p.input << "\", expectation=" << p.expectation << "}" << std::endl;
}

class MyClassTest : public ::testing::TestWithParam<Params>
{};

TEST_P(MyClassTest, TestAllValues)
{
    MyClass sut;
    EXPECT_EQ(sut.MyFunction(GetParam().input).has_value(), GetParam().expectation);
}

INSTANTIATE_TEST_SUITE_P(OKValues,
                         MyClassTest,
                         testing::Values(
                            Params{"1", true},
                            Params{"1", true},
                            Params{"1", true}
                         ));

INSTANTIATE_TEST_SUITE_P(OutOfBound,
                         MyClassTest,
                         testing::Values(
                            Params{"30", true},
                            Params{"40", true},
                            Params{"50", true}
                         ));

INSTANTIATE_TEST_SUITE_P(Invalid,
                         MyClassTest,
                         testing::Values(
                            Params{"3.0", false},
                            Params{"Foo", false},
                            Params{"Bar", false}
                         ));

請注意,您的示例缺少任何可以測試的 output,例如MyClass::MyFunction()的一些返回值。 因此我添加了一個非常簡單的。 但是根據實際代碼返回 output(異常?)的方式,需要使用不同的代碼來檢查預期。 原則上,您可以在TEST_P中引入分支來檢查期望應該是什么(例如值或異常),然后做一些不同的事情(例如EXPECT_EQEXPECT_THROW ),但是如果有多個這樣的情況,這可能會變得混亂。 對於每個結果“類”有一個測試套件的原始方式,您可能會更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM