การทดสอบหน่วยสำหรับรหัส C ++ - เครื่องมือและระเบียบวิธี [ปิด]


134

ฉันกำลังทำงานกับระบบ c ++ ขนาดใหญ่ที่อยู่ระหว่างการพัฒนามาสองสามปีแล้ว ในฐานะที่เป็นส่วนหนึ่งของความพยายามในการปรับปรุงคุณภาพของโค้ดที่มีอยู่เราจึงมีส่วนร่วมในโครงการปรับโครงสร้างระยะยาวขนาดใหญ่

คุณรู้จักเครื่องมือที่ดีที่สามารถช่วยฉันเขียนการทดสอบหน่วยใน C ++ ได้หรือไม่? อาจจะคล้ายกับ Junit หรือ Nunit?

ใครสามารถให้คำแนะนำที่ดีเกี่ยวกับวิธีการเขียนการทดสอบหน่วยสำหรับโมดูลที่เขียนโดยไม่คำนึงถึงการทดสอบหน่วย


1
ลองดูคำถามนี้: stackoverflow.com/questions/3150/…
Aardvark

คำตอบ:


83

การใช้การทดสอบหน่วยกับรหัสเดิมเป็นสาเหตุที่ทำให้ การทำงานอย่างมีประสิทธิผลกับ Legacy Codeถูกเขียนขึ้น ไมเคิลขนเป็นผู้เขียน - ตามที่กล่าวไว้ในคำตอบอื่น ๆ เขามีส่วนเกี่ยวข้องในการสร้างของทั้งสองCppUnitและCppUnitLite

ข้อความแสดงแทน


4
เพิ่มภาพขนาดย่อ - โหวตขึ้น หนังสือช่วยได้มากกว่าเครื่องมือใด ๆ
Gishu

2
ฉันคิดว่า CPPUnit สามารถช่วยให้เขียนข้อสอบได้ง่ายขึ้น เราใช้ CPPUnit แต่ฉันไม่พอใจ ฉันต้องการอัปเดตไฟล์สองไฟล์สำหรับการทดสอบแต่ละครั้งและในความคิดของฉันการทดสอบควรเขียนได้ง่ายเพียงแค่: 'TEST ("testname") {ASSERT (1 == 1);}' ในทางกลับกันหนังสือคือ สิ่งจำเป็นสำหรับทุกคนไม่เพียง แต่ผู้ที่ทำงานกับรหัสเดิมเท่านั้น แต่ยังรวมถึงผู้ที่สร้างด้วย)
daramarak

9
c ++ เป็นมรดกตกทอดตั้งแต่เมื่อใด!
นิลส์

9
ไม่ใช่ว่า C ++ เป็นแบบดั้งเดิม - ถ้าฉันจำได้อย่างถูกต้องหนังสือเล่มนั้นจะกำหนดโครงการดั้งเดิมว่าเป็นโครงการที่ไม่มีเลยหรือมีการทดสอบหน่วยน้อยมาก โครงการดังกล่าวมีแนวโน้มที่จะ / ยาก / เขียนการทดสอบหน่วยเนื่องจากการพัฒนาที่ขับเคลื่อนด้วยการทดสอบไม่เคยมีอิทธิพลต่อฐานรหัสดังนั้นจึงเป็นเรื่องเล็กน้อยที่จะเขียน
Arafangion

7
@Nils: ในฐานะที่เป็นหนึ่งในผู้ตรวจสอบหนังสือของ Amazon กล่าวว่า "รหัสเดิมคือรหัสที่ไม่มีการทดสอบหน่วย" ซึ่งเป็นคำถามที่เกี่ยวกับคำถามนี้
David Johnstone

40

Google เพิ่งเปิดตัวไลบรารีของตนเองสำหรับการทดสอบหน่วยแอป C ++ เรียกว่า Google Test

โครงการบน Google Code


1
มันเป็นไปได้ที่จะใช้นี้ด้วย VC ++
yesraaj

ดูเหมือนจะค่อนข้างโอเคโดยเฉพาะอย่างยิ่งวิธีที่พวกเขาต้องเพิ่มคำอธิบายในการยืนยันแต่ละครั้ง ในด้านลบโดยส่วนตัวแล้วฉันชอบที่จะมีคลาสทดสอบหน่วยแทนที่จะเป็นมาโครที่ดูไม่เหมือนคลาสจริงๆ
Wernight

3
อีกประเด็นที่ดีคือความเป็นไปได้ในการเยาะเย้ย: code.google.com/p/googlemock
Philipp

ฉันพบว่าสิ่งนี้ดีกว่า CPPUNIT ซึ่งต้องใช้มาโครและไฟล์เวทย์มนตร์จำนวนมากเพื่อให้การทดสอบทำงานได้
paulm

30

ตรวจสอบการเปรียบเทียบที่ยอดเยี่ยมระหว่างห้องชุดต่างๆที่มีอยู่ ผู้เขียนบทความที่ต่อมาพัฒนาUnitTest ++

สิ่งที่ฉันชอบเป็นพิเศษเกี่ยวกับเรื่องนี้ (นอกเหนือจากข้อเท็จจริงที่ว่ามันจัดการกับข้อยกเว้น ฯลฯ ได้ดี) คือมี 'การบริหาร' ที่ จำกัด มากสำหรับกรณีทดสอบและคำจำกัดความของอุปกรณ์ทดสอบ


3
ไม่ใช่ 'ที่เข้าใจผิดพื้นฐานของเรา? เขามีข้อมูลเชิงลึกที่ดีเกี่ยวกับโครงการที่มีอยู่ - แต่แทนที่จะปรับปรุงพวกเขาเขาเริ่มด้วยตัวเอง
peterchen

@peterchen: ใช่; แต่แล้ว UnitTest ++ นั้นมีขนาดเล็กและน้ำหนักเบามากจนมีคุณค่าในการเป็นโปรเจ็กต์แยกต่างหาก - มันง่ายมากที่จะเริ่มต้นใช้งาน
TimStaley

24

Boost มีไลบรารีการทดสอบที่รองรับการทดสอบหน่วย อาจคุ้มค่าที่จะลองดู


4
ฉันสามารถแนะนำชุดเครื่องมือที่ยอดเยี่ยมนี้ได้
Rob

1
ใช่บูสต์คือหนทางที่จะไป ไม่มีค่าใช้จ่ายเพียงแค่ทดสอบและเริ่มต้น! จริงๆแล้วฉันกำลังทำงานในกรอบของตัวเองด้วยความสิ้นหวังเมื่อการเพิ่มเข้ามาช่วยฉัน ขอบคุณเพิ่ม (สำหรับทุกสิ่ง!)
daramarak

คุณสามารถอ่านบทความที่ฉันเขียนแนะนำ Boost Unit Testing beroux.com/english/articles/boost_unit_testing
Wernight

21

Noel Llopis จากGames From Withinเป็นผู้เขียนExploring the C ++ Unit Testing Framework Jungleซึ่งเป็นการประเมินที่ครอบคลุม (แต่ปัจจุบันลงวันที่แล้ว) ของกรอบการทดสอบหน่วย C ++ ต่างๆรวมถึงหนังสือเกี่ยวกับการเขียนโปรแกรมเกม

เขาใช้ CppUnitLite มากในขณะที่การแก้ไขสิ่งต่างๆ แต่ในที่สุดก็เข้าร่วมกองกำลังกับผู้เขียนห้องสมุดทดสอบหน่วยอื่นและผลิตUnitTest ++ เราใช้ UnitTest ++ ที่นี่และฉันชอบมันมากจนถึงตอนนี้ มันมี (สำหรับฉัน) สมดุลของพลังที่ถูกต้องและมีรอยเท้าเล็ก ๆ

ฉันใช้โซลูชันพื้นบ้าน CxxTest (ซึ่งต้องใช้ Perl) และ boost :: test เมื่อฉันใช้การทดสอบหน่วยที่นี่ในงานปัจจุบันของฉันมันค่อนข้างจะลงมาที่ UnitTest ++ vs boost :: test

ฉันชอบไลบรารีบูสต์ส่วนใหญ่ที่ฉันเคยใช้ แต่ IMHO, boost :: test นั้นค่อนข้างหนักเกินไป ฉันไม่ชอบโดยเฉพาะอย่างยิ่งที่คุณ (AFAIK) ต้องใช้โปรแกรมหลักของสายรัดทดสอบโดยใช้มาโครการทดสอบบูสต์ :: ฉันรู้ว่ามันไม่ใช่ TDD ที่ "บริสุทธิ์" แต่บางครั้งเราก็ต้องการวิธีเรียกใช้การทดสอบจากการใช้แอปพลิเคชัน GUI เช่นเมื่อมีการส่งแฟล็กทดสอบพิเศษในบรรทัดคำสั่งและ boost :: test ไม่รองรับประเภทนี้ ของสถานการณ์

UnitTest ++ เป็นกรอบการทดสอบที่ง่ายที่สุดในการตั้งค่าและใช้งานที่ฉันพบในประสบการณ์ (จำกัด ) ของฉัน


17

ฉันใช้ไลบรารีBoost.Test ที่ยอดเยี่ยมร่วมกับห้องสมุดTurtle ที่เป็นที่รู้จักน้อยกว่ามาก แต่น่ากลัวมาก: ไลบรารีวัตถุจำลองตามการเพิ่ม

ในฐานะที่เป็นตัวอย่างโค้ดพูดได้ดีกว่าคำสมมติว่าคุณต้องการทดสอบcalculatorวัตถุที่ทำงานบนviewอินเทอร์เฟซ (นั่นคือตัวอย่างเบื้องต้นของ Turtle):

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

มาดูกันว่าการประกาศความคาดหวังในวัตถุจำลองนั้นง่ายและละเอียดเพียงใด? เห็นได้ชัดว่าการทดสอบล้มเหลวหากไม่เป็นไปตามความคาดหวัง


14

ฉันเพิ่งผลักดันกรอบงานของตัวเองCATCHออกไป มันยังอยู่ระหว่างการพัฒนา แต่ฉันเชื่อว่ามันเกินกรอบอื่น ๆ ไปแล้ว ต่างคนต่างมีเกณฑ์ที่แตกต่างกัน แต่ฉันพยายามปกปิดส่วนใหญ่โดยไม่มีการแลกเปลี่ยนมากเกินไป ดูรายการบล็อกที่เชื่อมโยงของฉันสำหรับนักชิม คุณสมบัติห้าอันดับแรกของฉันคือ:

  • ส่วนหัวเท่านั้น
  • การลงทะเบียนอัตโนมัติของการทดสอบตามฟังก์ชันและวิธีการ
  • สลายนิพจน์ C ++ มาตรฐานเป็น LHS และ RHS (ดังนั้นคุณไม่จำเป็นต้องมีมาโครยืนยันทั้งตระกูล)
  • รองรับส่วนที่ซ้อนกันภายในฟิกซ์เจอร์ตามฟังก์ชัน
  • การทดสอบชื่อโดยใช้ภาษาธรรมชาติ - สร้างชื่อฟังก์ชัน / วิธีการ

นอกจากนี้ยังมีการผูก Objective-C


4
หลักปฏิบัติคือการนำ Catch มาใช้ใหม่โดยให้ความสำคัญอย่างมากกับความเร็วในการรวบรวม - ดูคำถามที่พบบ่อยเพื่อดูว่าแตกต่างกันอย่างไร
onqtam




6

ขณะนี้ฉันกำลังมองหาการทดสอบหน่วยและกรอบการทำงานจำลองที่สามารถใช้ที่ บริษัท ของเราสำหรับฐานรหัสที่ใช้งานได้ยาวนาน ดังที่คุณทราบรายการกรอบการทดสอบหน่วยสำหรับ c ++ นั้นยาวดังนั้นฉันจึงใช้ตัวกรองบางตัวเพื่อลดให้เป็นแบบเต็มมือที่สามารถดูได้อย่างใกล้ชิดมากขึ้น เกณฑ์การกรองแรกคือต้องเป็นแบบฟรี เกณฑ์ที่สองคือกิจกรรมโครงการ ฉันยังมองหากรอบการเยาะเย้ยเพราะคุณต้องการถ้าคุณต้องการเขียนแบบทดสอบหน่วย

ฉันมาพร้อมกับรายการต่อไปนี้ (โดยประมาณ) เรียงตามกิจกรรมกิจกรรมสูงสุดที่ด้านบน:

  • GoogleTest / GoogleMock:ผู้ร่วมให้ข้อมูลจำนวนมากและใช้งานโดย Google เอง นี่อาจจะอยู่ที่นี่สักระยะและรับการอัปเดต สำหรับฐานรหัสส่วนตัวของฉันฉันจะเปลี่ยนไปใช้ชุดค่าผสมนี้โดยหวังว่าจะได้ขึ้นรถไฟที่เร็วที่สุด

  • BoostTest + Turtle:ไม่ได้รับการอัปเดตบ่อยนัก แต่กรอบการทดสอบเป็นส่วนหนึ่งของการเพิ่มประสิทธิภาพดังนั้นจึงควรรักษาไว้ ในทางกลับกันเต่าถูกดูแลโดยผู้ชายคนหนึ่งเป็นหลัก แต่มันมีกิจกรรมที่ไม่พอใจดังนั้นมันจึงไม่ตาย ฉันสร้างประสบการณ์การทดสอบเกือบทั้งหมดด้วยชุดค่าผสมนี้เพราะเราใช้ไลบรารีเพิ่มในงานก่อนหน้านี้อยู่แล้วและฉันก็ใช้มันเป็นรหัสส่วนตัวของฉัน

  • CppUTest:ให้การทดสอบและการล้อเลียน โครงการนี้เริ่มดำเนินการตั้งแต่ปี 2551 ถึง 2558 และมีกิจกรรมล่าสุดค่อนข้างมาก การค้นพบนี้เป็นเรื่องที่น่าแปลกใจเล็กน้อยเนื่องจากมีโครงการจำนวนมากที่มีกิจกรรมน้อยกว่าอย่างมีนัยสำคัญเกิดขึ้นบ่อยขึ้นเมื่อค้นหาบนเว็บ (เช่น CppUnit ซึ่งมีการอัปเดตล่าสุดในปี 2013) ฉันไม่ได้มองลึกลงไปในเรื่องนี้จึงไม่สามารถพูดอะไรเกี่ยวกับรายละเอียดได้ แก้ไข (16.12.2015):ฉันเพิ่งลองใช้และพบว่าเฟรมเวิร์กนี้ดูงุ่มง่ามและ "C-stylish" เล็กน้อยโดยเฉพาะเมื่อใช้คลาสจำลอง นอกจากนี้ดูเหมือนว่าจะมีการยืนยันที่หลากหลายกว่ากรอบอื่น ๆ ฉันคิดว่าจุดแข็งหลักของมันคือสามารถใช้กับโครงการ C ล้วน ๆ

  • QTest:ไลบรารีทดสอบที่มาพร้อมกับกรอบงาน Qt ควรรับประกันการบำรุงรักษาเป็นระยะเวลาหนึ่ง แต่ฉันใช้มันแทนไลบรารีที่สนับสนุนเนื่องจากการลงทะเบียนทดสอบเป็น IMO ที่งุ่มง่ามมากกว่าในกรอบอื่น ๆ เท่าที่ฉันเข้าใจมันบังคับให้คุณมี test-exe หนึ่งครั้งต่อการทดสอบหนึ่งครั้ง แต่ฟังก์ชันตัวช่วยทดสอบสามารถใช้งานได้ดีเมื่อทดสอบโค้ด Qt-Gui มันไม่มีล้อเลียน

  • จับ:มีกิจกรรมล่าสุด แต่ส่วนใหญ่พัฒนาโดยผู้ชายคนหนึ่ง สิ่งที่ดีเกี่ยวกับเฟรมเวิร์กนี้คือวิธีการติดตั้งทางเลือกที่ช่วยให้คุณสามารถเขียนโค้ดฟิกซ์เจอร์ที่ใช้ซ้ำได้ในการทดสอบ นอกจากนี้ยังให้คุณตั้งชื่อการทดสอบเป็นสตริงซึ่งดีเมื่อคุณมักจะเขียนทั้งประโยคเป็นชื่อทดสอบ ฉันอยากจะฉีกสไตล์นี้และใส่ลงใน googleTest ;-)

กรอบงานจำลอง

จำนวนเฟรมเวิร์กจำลองมีขนาดเล็กกว่ามากเมื่อเทียบกับจำนวนเฟรมเวิร์กทดสอบ แต่นี่คือเฟรมที่ฉันพบว่ามีกิจกรรมล่าสุด

  • Hippomock : ใช้งานตั้งแต่ปี 2008 unitl ในขณะนี้ แต่มีความเข้มต่ำเท่านั้น

  • FakeIt : ใช้งานตั้งแต่ปี 2013 unitl ตอนนี้ แต่พัฒนาโดยผู้ชายคนหนึ่งไม่มากก็น้อย

สรุป

ถ้ารหัสฐานของคุณอยู่ในสำหรับระยะยาวเลือกระหว่างระหว่างBoostTest + เต่าและGoogleTest + GoogleMock ฉันคิดว่าทั้งสองจะมีการบำรุงรักษาในระยะยาว หากคุณมีโค้ดพื้นฐานเพียงสั้น ๆ คุณสามารถลองใช้Catchซึ่งมีไวยากรณ์ที่ดี จากนั้นคุณจะต้องเลือกกรอบการเยาะเย้ยเพิ่มเติม หากคุณทำงานกับ Visual Studio คุณสามารถดาวน์โหลดอะแดปเตอร์สำหรับนักวิ่งทดสอบสำหรับ BoostTest และ GoogleTest ได้ซึ่งจะช่วยให้คุณทำการทดสอบด้วย GUI ของนักวิ่งทดสอบที่รวมอยู่ใน VS


3

ดูคำตอบของคำถามที่เกี่ยวข้องอย่างใกล้ชิด "การเลือกเครื่องมือ / กรอบการทดสอบหน่วย c ++" ได้ที่นี่


3

นอกจากนี้ยังมีTUT , Template-Unit-Test, เฟรมเวิร์กที่ใช้เทมเพลต เป็นไวยากรณ์ที่น่าอึดอัดใจ (บางคนเรียกว่าการใช้เทมเพลตในทางที่ผิด) แต่ข้อได้เปรียบหลักคือทั้งหมดนี้มีอยู่ในไฟล์ส่วนหัวเดียวไฟล์ส่วนหัวเดียว

คุณจะพบตัวอย่างการทดสอบหน่วยที่เขียนด้วย TUTที่นี่


2
ฉันวางไลบรารีเฉพาะส่วนหัวที่ให้การตัดมาโครของ TUT ทำให้แน่ใจว่าฟังก์ชันและรหัสการถอดรหัสทดสอบทั้งสองเพื่อทำให้ง่ายขึ้นและให้ข้อมูลไฟล์และหมายเลขบรรทัดในกรณีที่ล้มเหลว นี่คือลิงค์ไปยังโพสต์ที่มีตัวอย่างของความแตกต่างในผลลัพธ์และโค้ดรวมถึงลิงก์ไปยังโปรเจ็กต์บน github: codecrafter.wordpress.com/2012/12/19/tutadapter1
Josh Heitzman

2

ฉันได้ลองใช้ CPPunit แล้วและไม่ค่อยเป็นมิตรกับผู้ใช้

ทางเลือกเดียวที่ฉันรู้คือใช้ C ++ NET เพื่อรวมคลาส C ++ ของคุณและเขียนการทดสอบหน่วยด้วยกรอบการทดสอบหน่วย. NET (NUnit, MBUnit เป็นต้น)




1

มีลักษณะที่CUnitWin32 เขียนขึ้นสำหรับ MS Visual C ซึ่งรวมถึงตัวอย่าง


1

ดูที่ cfix ( http://www.cfix-testing.org ) ซึ่งมีไว้สำหรับการพัฒนา Windows C / C ++ และรองรับทั้งโหมดผู้ใช้และการทดสอบหน่วยโหมดเคอร์เนล


ขอบคุณสำหรับการแบ่งปัน. ฉันเพิ่งเริ่มใช้ cfix เพื่อการทดสอบ ฉันกำลังมองหาวิธีดู call stack ทั้งในกรณีทดสอบที่ผ่านและไม่ผ่าน มีวิธีใน cfix เพื่อให้บรรลุสิ่งนี้หรือไม่?
tryToLearn

1

หากคุณใช้ Visual Studio 2008 SP1 ฉันขอแนะนำให้ใช้ MSTest ในการเขียนการทดสอบหน่วย จากนั้นฉันใช้ Google เยาะเย้ยเพื่อเขียนล้อเลียน การรวมเข้ากับ IDE นั้นเหมาะอย่างยิ่งและอนุญาตและไม่ถือค่าใช้จ่ายของ CPPunit ในแง่ของการแก้ไขสามตำแหน่งสำหรับการเพิ่มการทดสอบหนึ่งครั้ง


1

ฉันคิดว่าVisualAssertทำได้ดีมากในการรวม VS ช่วยให้คุณสามารถเรียกใช้และดีบักการทดสอบจาก VS และคุณไม่จำเป็นต้องสร้างไฟล์ปฏิบัติการเพื่อเรียกใช้การทดสอบ


0

ตรวจสอบฟรุกโตส: http://sourceforge.net/projects/fructose/

เป็นเฟรมเวิร์กที่เรียบง่ายมีเฉพาะไฟล์ส่วนหัวและพกพาได้ง่าย


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.