ใช้ Google Test 1.6 (Windows 7, Visual Studio C ++) ฉันจะปิดการทดสอบที่กำหนดได้อย่างไร (aka ฉันจะป้องกันไม่ให้การทดสอบทำงานได้อย่างไร) ฉันสามารถทำอะไรได้บ้างนอกจากแสดงความคิดเห็นในการทดสอบทั้งหมด
ใช้ Google Test 1.6 (Windows 7, Visual Studio C ++) ฉันจะปิดการทดสอบที่กำหนดได้อย่างไร (aka ฉันจะป้องกันไม่ให้การทดสอบทำงานได้อย่างไร) ฉันสามารถทำอะไรได้บ้างนอกจากแสดงความคิดเห็นในการทดสอบทั้งหมด
คำตอบ:
เอกสารสำหรับ Google ทดสอบ 1.7 แนะนำ :
"หากคุณมีการทดสอบที่เสียซึ่งคุณไม่สามารถแก้ไขได้ในทันทีคุณสามารถเพิ่มคำนำหน้า DISABLED_ ลงในชื่อซึ่งจะไม่รวมการทดสอบดังกล่าวออกจากการดำเนินการ"
ตัวอย่าง:
// 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 เพื่อใช้งาน
GTEST_SKIP()
มีให้ตั้งแต่ 1.10.0
GTEST_SKIP_("some message")
(โปรดสังเกตขีดล่าง)
นี่คือนิพจน์เพื่อรวมการทดสอบที่ชื่อมีสตริง 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 *"
export GTEST_FILTER='*'
ไฟล์.
*
" not "" ฉันจะใช้ตัวแปรสภาพแวดล้อมอื่นที่แทนที่ตัวกรองแทน
หากจำเป็นต้องข้ามการทดสอบมากกว่าหนึ่งครั้ง
--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);
}
}
สิ่งนี้มีประโยชน์สำหรับฉันเนื่องจากฉันพยายามเรียกใช้การทดสอบบางอย่างเฉพาะเมื่อระบบรองรับ dual stack IPv6
ในทางเทคนิคแล้วสิ่งที่ดูอัลสแต็คไม่ควรเป็นการทดสอบหน่วยเนื่องจากขึ้นอยู่กับระบบ แต่ฉันไม่สามารถทำการทดสอบการผสานรวมได้จนกว่าฉันจะทดสอบว่ามันใช้งานได้จริงและสิ่งนี้ทำให้มั่นใจได้ว่าจะไม่รายงานความล้มเหลวเมื่อไม่ใช่ความผิดปกติของรหัส
สำหรับการทดสอบนั้นฉันมีวัตถุต้นขั้วที่จำลองระบบรองรับ dualstack (หรือขาด) โดยการสร้างซ็อกเก็ตปลอม
ข้อเสียเพียงอย่างเดียวคือผลการทดสอบและจำนวนการทดสอบจะเปลี่ยนไปซึ่งอาจทำให้เกิดปัญหากับสิ่งที่ตรวจสอบจำนวนการทดสอบที่ประสบความสำเร็จ
คุณยังสามารถใช้ ASSERT_ * แทน EQUAL_ * ยืนยันจะเกี่ยวกับการทดสอบที่เหลือหากล้มเหลว ป้องกันไม่ให้มีการถ่ายโอนข้อมูลซ้ำซ้อนจำนวนมากไปยังคอนโซล
ฉันมีความต้องการแบบเดียวกันสำหรับการทดสอบตามเงื่อนไขและฉันพบวิธีแก้ปัญหาที่ดี ฉันกำหนดมาโคร TEST_C ที่ทำงานเหมือนแมโคร TEST_F แต่มีพารามิเตอร์ที่สามซึ่งเป็นนิพจน์บูลีนซึ่งประเมินรันไทม์ใน 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();