[英]GoogleTest: How to skip a test?
使用 Google Test 1.6(Windows 7、Visual Studio C++)。 如何關閉給定的測試? (也就是我怎樣才能阻止測試運行)。 除了注釋掉整個測試,我還能做些什么嗎?
如果您有一個無法立即修復的損壞測試,您可以在其名稱中添加
DISABLED_
前綴。 這會將其排除在執行之外。 這比注釋掉代碼或使用#if 0
更好,因為禁用的測試仍在編譯(因此不會腐爛)。
上述文檔中的示例:
// Tests that Foo does Abc. TEST(FooTest, DISABLED_DoesAbc) { ... } class DISABLED_BarTest : public testing::Test { ... }; // Tests that Bar does Xyz. TEST_F(DISABLED_BarTest, DoesXyz) { ... }
根據文檔,您還可以運行測試的子集:
運行測試的子集
默認情況下,Google 測試程序會運行用戶定義的所有測試。 有時,您只想運行測試的子集(例如,用於調試或快速驗證更改)。 如果您將 GTEST_FILTER 環境變量或 --gtest_filter 標志設置為過濾器字符串,Google Test 將僅運行全名(以 TestCaseName.TestName 的形式)與過濾器匹配的測試。
過濾器的格式是一個“:”分隔的通配符模式列表(稱為正模式),可選地后跟一個“-”和另一個“:”分隔的模式列表(稱為負模式)。 當且僅當它匹配任何正模式但不匹配任何負模式時,測試才匹配過濾器。
模式可能包含“*”(匹配任何字符串)或“?” (匹配任何單個字符)。 為方便起見,過濾器“*-NegativePatterns”也可以寫成“-NegativePatterns”。
例如:
./foo_test Has no flag, and thus runs all its tests. ./foo_test --gtest_filter=* Also runs everything, due to the single match-everything * value. ./foo_test --gtest_filter=FooTest.* Runs everything in test case FooTest. ./foo_test --gtest_filter=*Null*:*Constructor* Runs any test whose full name contains either "Null" or "Constructor". ./foo_test --gtest_filter=-*DeathTest.* Runs all non-death tests. ./foo_test --gtest_filter=FooTest.*-FooTest.Bar Runs everything in test case FooTest except FooTest.Bar.
不是最漂亮的解決方案,但它有效。
您現在可以使用GTEST_SKIP()
宏在運行時有條件地跳過測試。 例如:
TEST(Foo, Bar)
{
if (blah)
GTEST_SKIP();
...
}
請注意,這是一個非常新的功能,因此您可能需要更新您的 GoogleTest 庫才能使用它。
下面的表達式包含名稱中包含字符串 foo1 或 foo2 的測試,並排除名稱中包含字符串 bar1 或 bar2 的測試:
--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*
我更喜歡用代碼來做:
// Run a specific test only
//testing::GTEST_FLAG(filter) = "MyLibrary.TestReading"; // I'm testing a new feature, run something quickly
// Exclude a specific test
testing::GTEST_FLAG(filter) = "-MyLibrary.TestWriting"; // The writing test is broken, so skip it
我可以注釋掉這兩行以運行所有測試,取消注釋第一行以測試我正在調查/工作的單個功能,或者如果測試被破壞但我想測試其他所有內容,則取消注釋第二行。
您還可以通過使用通配符和編寫列表“MyLibrary.TestNetwork*”或“-MyLibrary.TestFileSystem*”來測試/排除一組功能。
如果需要超過一項測試,則跳過
--gtest_filter=-TestName.*:TestName.*TestCase
對於另一種方法,您可以將測試包裝在一個函數中,並在運行時使用正常的條件檢查來僅在需要時執行它們。
#include <gtest/gtest.h>
const bool skip_some_test = true;
bool some_test_was_run = false;
void someTest() {
EXPECT_TRUE(!skip_some_test);
some_test_was_run = true;
}
TEST(BasicTest, Sanity) {
EXPECT_EQ(1, 1);
if(!skip_some_test) {
someTest();
EXPECT_TRUE(some_test_was_run);
}
}
這對我很有用,因為我僅在系統支持雙棧 IPv6 時才嘗試運行一些測試。
從技術上講,雙棧的東西不應該是真正的單元測試,因為它取決於系統。 但是在我測試它們無論如何都可以工作之前,我不能真正進行任何集成測試,這樣可以確保在不是代碼錯誤時它不會報告失敗。
至於對它的測試,我有通過構造假套接字來模擬系統對雙棧(或不支持)的支持的存根對象。
唯一的缺點是測試輸出和測試數量會發生變化,這可能會導致監控成功測試數量的東西出現問題。
您也可以使用 ASSERT_* 而不是 EQUAL_*。 如果測試失敗,斷言將處理其余的測試。 防止大量多余的東西被轉儲到控制台。
我對條件測試也有同樣的需求,我想出了一個很好的解決方法。 我定義了一個像 TEST_F 宏一樣工作的宏 TEST_C,但它有第三個參數,它是一個布爾表達式,在測試開始之前在 main.cpp 中評估運行時。 不執行評估為假的測試。 宏很丑,但它看起來像:
#pragma once
extern std::map<std::string, std::function<bool()> >* m_conditionalTests;
#define TEST_C(test_fixture, test_name, test_condition)\
class test_fixture##_##test_name##_ConditionClass\
{\
public:\
test_fixture##_##test_name##_ConditionClass()\
{\
std::string name = std::string(#test_fixture) + "." + std::string(#test_name);\
if (m_conditionalTests==NULL) {\
m_conditionalTests = new std::map<std::string, std::function<bool()> >();\
}\
m_conditionalTests->insert(std::make_pair(name, []()\
{\
DeviceInfo device = Connection::Instance()->GetDeviceInfo();\
return test_condition;\
}));\
}\
} test_fixture##_##test_name##_ConditionInstance;\
TEST_F(test_fixture, test_name)
此外,在您的 main.cpp 中,您需要此循環來排除評估為假的測試:
// identify tests that cannot run on this device
std::string excludeTests;
for (const auto& exclusion : *m_conditionalTests)
{
bool run = exclusion.second();
if (!run)
{
excludeTests += ":" + exclusion.first;
}
}
// add the exclusion list to gtest
std::string str = ::testing::GTEST_FLAG(filter);
::testing::GTEST_FLAG(filter) = str + ":-" + excludeTests;
// run all tests
int result = RUN_ALL_TESTS();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.