เปรียบเทียบกรอบการทดสอบหน่วย C ++ [ปิด]


300

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

ฉันคิดว่ากรอบที่น่าสนใจที่สุดคือ CppUnit, Boost และกรอบการทดสอบใหม่ของ Google มีใครเปรียบเทียบบ้างไหม?



ฉันมีกรอบการทดสอบตาม IOC ของตัวเองซึ่งฉันชอบมากกว่านี้เพราะมันไม่ได้เป็นเพียงโคลนของสิ่งที่คนอื่นทำ แต่ที่อยู่สิ่งที่ฉันพบปัญหาทั้งหมดของคนอื่นเป็น คุณเขียนกรณีทดสอบโดยมาจากคลาสไม่ใช่โดยใช้แมโคร มาโครใช้สำหรับการยืนยันตามที่พวกเขาให้ภาพสะท้อนเท่านั้น เอาต์พุตที่กำหนดเองของสถิติการทดสอบ เรียกใช้จากการเขียนสคริปต์ IOC เพื่อให้คุณเลือกสิ่งที่คุณทดสอบความถี่และพารามิเตอร์ใด
CashCow

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

คำตอบ:


99

ดูคำถามนี้สำหรับการสนทนา

พวกเขาแนะนำบทความ: สำรวจ Jungle C Framework Framework Test Unitโดย Noel Llopis และล่าสุด: C ++ Test Unit Frameworks

ฉันยังไม่พบบทความที่เปรียบเทียบ googletest กับเฟรมเวิร์กอื่น ๆ


อย่างที่ฉันเขียน: คำตอบทั้งหมดเพียงแค่แนะนำหนึ่งในกรอบงาน แต่อย่าเปรียบเทียบกรอบกับอีกกรอบหนึ่ง
housemaister

คุณไม่มีความสุขกับบทความด้วยใช่ไหม
Gishu

7
การวิจารณ์อย่างหนึ่ง: บทความในขณะที่ดีนั้นมาจากปี 2004 และไม่รวม Google Test
richq

2
ในลิงค์แรกคุณจะเห็นการเปรียบเทียบสองแบบ ยกเว้นเฟรมเวิร์กใหม่จาก google ข้อมูลส่วนใหญ่ยังคงเกี่ยวข้อง (และ CppUnit ไม่ใช่สิ่งที่น่าสนใจที่สุดมันใช้งานไม่ได้)
Luc Hermitte

1
แก้ไขลิงก์และขยายคำตอบด้วยการเปรียบเทียบล่าสุด
Sam Saffron

120

ผู้เล่นใหม่คือGoogle Test (หรือที่เรียกว่าGoogle C ++ Testing Framework ) ซึ่งค่อนข้างดีทีเดียว

#include <gtest/gtest.h>

TEST(MyTestSuitName, MyTestCaseName) {
    int actual = 1;
    EXPECT_GT(actual, 0);
    EXPECT_EQ(1, actual) << "Should be equal to one";
}

คุณสมบัติหลัก:

  • แบบพกพา
  • การยืนยันที่ร้ายแรงและไม่ร้ายแรง
  • ข้อความยืนยันข้อมูลง่าย ๆ:ASSERT_EQ(5, Foo(i)) << " where i = " << i;
  • Google ทดสอบจะตรวจจับการทดสอบของคุณโดยอัตโนมัติและไม่ต้องการให้คุณระบุการทดสอบเหล่านั้นเพื่อเรียกใช้
  • ทำให้ง่ายต่อการขยายคำศัพท์การยืนยันของคุณ
  • การทดสอบความตาย (ดูคำแนะนำขั้นสูง)
  • SCOPED_TRACE สำหรับรูทีนย่อยลูป
  • คุณสามารถตัดสินใจได้ว่าจะทำการทดสอบใด
  • การสร้างรายงานทดสอบXML
  • การแข่งขัน / จำลอง / แม่แบบ ...

3
ฉันสนุกกับการใช้การทดสอบ google มากกว่าเฟรมเวิร์กอื่น ๆ โดยเฉพาะอย่างยิ่งกับความสามารถในการเยาะเย้ยที่สามารถพบได้ในเฟรมเวิร์ก googlemock
Mike

8
ฉันมีคุณสมบัติเหล่านี้ทั้งหมด (แม้ว่าบางส่วนยังไม่เปิดเผย) และอื่น ๆ อีกมากมายในกรอบการทดสอบใหม่ของฉัน CATCH ดูคำตอบของฉันสำหรับลิงค์
philsquared

2
การรวมเข้าด้วยกันกับกรอบการเยาะเย้ยของ Google C ++ ทำให้เฟรมเวิร์กการทดสอบ xUnit ที่ทรงพลังสำหรับรหัส C ++ สำหรับการทดสอบหน่วย
ratkok

5
@CashCow การรันด้วย build เป็นสิ่งที่แตกต่างจากการตรวจจับการทดสอบ การรันด้วยบิลด์นั้นขึ้นอยู่กับระบบบิลด์ของคุณ การตรวจจับการทดสอบหมายความว่าคุณไม่จำเป็นต้องแสดงรายการการทดสอบทั้งหมดในคลาสอื่นเพียงแค่สร้างวิธีการทดสอบเท่านั้น
Wernight

ฉันไม่ชอบมาโครที่มากเกินไปและความจริงที่ว่าใช้คำทั่วไปเช่น TEST ซึ่งอาจขัดแย้งกับบางสิ่ง GTEST น่าจะดีกว่าและมีโอกาสน้อยกว่าที่จะปะทะกัน
CashCow

112

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

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

นอกจากนี้ยังมีการผูกวัตถุประสงค์ -C โครงการนี้โฮสต์บนGithub


โปรดพิจารณาการเพิ่มCHECK_FLASEและREQUIRE_FLASEมาโคร
Emile Cormier

6
กรอบที่ดีที่สุดในความคิดของฉัน
CoffeDeveloper

3
doctestคือการนำการติดตั้งไปใช้ใหม่ด้วยการเน้นความเร็วในการรวบรวมเป็นอย่างมาก - ชำระเงินคำถามที่พบบ่อยเพื่อดูความแตกต่าง
onqtam

@einpoklum Catch ไม่ได้ถูกละทิ้ง - ผู้สร้างทำงานกับไลบรารีเวอร์ชัน 2 doctest คือการจัดเรียงของ reimplementation ของจับ 1 กับบางส่วนตัดสินใจในการออกแบบโบนัส
onqtam

2
ฉันเสียการเปรียบเทียบกรอบการทดสอบทั้งหมด (ซึ่งตอนนี้ฉันต้องเลือก) คุณจะเขียนคำตอบของคุณเองเปรียบเทียบและเปรียบเทียบหลักคำสอนกับ Catch และข้อเสนออื่น ๆ หรือไม่?
einpoklum

53

Boost Test Libraryเป็นตัวเลือกที่ดีโดยเฉพาะถ้าคุณใช้ Boost อยู่แล้ว

// TODO: Include your class to test here.
#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(MyTestCase)
{
    // To simplify this example test, let's suppose we'll test 'float'.
    // Some test are stupid, but all should pass.
    float x = 9.5f;

    BOOST_CHECK(x != 0.0f);
    BOOST_CHECK_EQUAL((int)x, 9);
    BOOST_CHECK_CLOSE(x, 9.5f, 0.0001f); // Checks differ no more then 0.0001%
}

มันรองรับ:

  • การลงทะเบียนทดสอบอัตโนมัติหรือด้วยตนเอง
  • ยืนยันมากมาย
  • เปรียบเทียบคอลเลกชันอัตโนมัติ
  • รูปแบบเอาต์พุตต่างๆ (รวมถึงXML )
  • การแข่งขัน / แม่แบบ ...

PS: ฉันเขียนบทความเกี่ยวกับเรื่องนี้ที่อาจช่วยให้คุณเริ่มต้น: กรอบการทดสอบหน่วย C ++: แบบฝึกหัดทดสอบการทดสอบ


ฉันเคยใช้ Boost test และชอบ แต่ดูเหมือนว่ามันจะเปลี่ยนไปมากระหว่างการเปิดตัว มันยากที่จะขายการทดสอบหน่วยให้กับลูกค้าของฉันโดยไม่ต้องใช้เวลามากขึ้น (และเงินของพวกเขา) ในการแก้ไขการทดสอบเมื่อ API เปลี่ยนแปลงไปกว่าการแก้ไขรหัสที่ควรจะเป็นการทดสอบ ในที่สุดฉันก็ทิ้งมันและเขียนของตัวเอง - นี่คือประมาณ 5 ปีที่ผ่านมาแม้ว่า
องค์ประกอบที่ 10

5
ลิงก์การสอนเสียหาย
mloskot

2
@mloskot มันทำงานได้อีกครั้ง
Chris Jester-Young

@mloskot ขออภัยสำหรับสิ่งนั้นโปรดส่งอีเมลถึงฉันโดยตรงหากคุณเห็นว่ามันใช้งานไม่ได้ ง่ายต่อการค้นหามากกว่าความคิดเห็น :)
Wernight

@Wightight Yup ทำงานอีกครั้ง ขอบคุณ
mloskot


16

ฉันเพิ่งเปิดตัวxUnit ++โดยเฉพาะเป็นทางเลือกแทน Google Test และ Boost Test Library (ดูการเปรียบเทียบ ) หากคุณคุ้นเคยกับ xUnit.Net คุณก็พร้อมสำหรับ xUnit ++

#include "xUnit++/xUnit++.h"

FACT("Foo and Blah should always return the same value")
{
    Check.Equal("0", Foo()) << "Calling Foo() with no parameters should always return \"0\".";
    Assert.Equal(Foo(), Blah());
}

THEORY("Foo should return the same value it was given, converted to string", (int input, std::string expected),
    std::make_tuple(0, "0"),
    std::make_tuple(1, "1"),
    std::make_tuple(2, "2"))
{
    Assert.Equal(expected, Foo(input));
}

คุณสมบัติหลัก:

  • อย่างไม่น่าเชื่ออย่างรวดเร็ว: การทดสอบทำงานควบคู่กันไป
  • แบบพกพา
  • การลงทะเบียนทดสอบอัตโนมัติ
  • ประเภทการยืนยันหลายประเภท (Boost ไม่มีอะไรใน xUnit ++)
  • เปรียบเทียบคอลเลกชันโดยกำเนิด
  • การยืนยันมีสามระดับ:
    • ข้อผิดพลาดร้ายแรง
    • ข้อผิดพลาดที่ไม่ร้ายแรง
    • คำเตือน
  • การบันทึกการยืนยันง่าย ๆ:Assert.Equal(-1, foo(i)) << "Failed with i = " << i;
  • ทดสอบการบันทึก:Log.Debug << "Starting test"; Log.Warn << "Here's a warning";
  • การแข่งขัน
  • การทดสอบที่ขับเคลื่อนด้วยข้อมูล (ทฤษฎี)
  • เลือกการทดสอบที่จะทำงานโดยขึ้นอยู่กับ:
    • การจับคู่คุณสมบัติ
    • ชื่อสตริงย่อยที่ตรงกัน
    • ห้องทดสอบ

2
คำถามกำลังถามเพื่อเปรียบเทียบ IMO เป็นสิ่งสำคัญที่จะต้องนำเสนอความแตกต่างระหว่างกรอบการทำงานของคุณและอย่างน้อยสองสิ่งที่ได้รับความนิยมคือ googletest และ Boost โดยเฉพาะถ้าคุณโฆษณา xUnit ++ เป็นทางเลือกแทนสองรายการนั้น จะเป็น +1 หากอัปเดต :)
mloskot

ยุติธรรมพอสมควร :) ฉันได้แล้วมีตารางเปรียบเทียบในวิกิพีเดียแต่ฉันจะพยายามที่จะรวมถึงบางส่วนของความแตกต่างโดยตรงในคำตอบของฉัน
moswald

1
ฉันตัดสินใจที่จะเพียงเชื่อมโยงตาราง wiki โดยตรงมันทำให้ข้อมูลสรุปยุ่งเหยิงเพื่อแสดงรายการทั้งหมด
moswald

ลิงค์ใช้งานได้สำหรับฉันขอบคุณ! +1
mloskot

1
โครงการของคุณถูกยกเลิกหรือไม่ การกระทำล่าสุดวันที่กลับไปที่ 09/2015 ... อย่างไรก็ตามคำตอบที่ดี ขอบคุณ
zertyz


4

CPUnit ( http://cpunit.sourceforge.net ) เป็นเฟรมเวิร์กที่คล้ายกับ Google Test แต่ใช้มาโครน้อยกว่า (การยืนยันคือฟังก์ชั่น) และที่มาโครจะมีคำนำหน้าเพื่อหลีกเลี่ยงข้อผิดพลาดของแมโครปกติ การทดสอบมีลักษณะดังนี้:

#include <cpunit>

namespace MyAssetTest {
    using namespace cpunit;

    CPUNIT_FUNC(MyAssetTest, test_stuff) {
        int some_value = 42;
        assert_equals("Wrong value!", 666, some_value);
    }

    // Fixtures go as follows:
    CPUNIT_SET_UP(MyAssetTest) {
        // Setting up suite here...
        // And the same goes for tear-down.
    }

}

พวกเขาลงทะเบียนอัตโนมัติดังนั้นคุณไม่จำเป็นต้องมากกว่านี้ จากนั้นก็จะรวบรวมและเรียกใช้ ฉันพบว่าการใช้เฟรมเวิร์กนี้เหมือนกับการใช้ JUnit สำหรับผู้ที่ต้องใช้เวลาในการเขียนโปรแกรม Java ดีมาก!



2

API Sanity Checker - กรอบการทดสอบสำหรับไลบรารี C / C ++:

เครื่องกำเนิดไฟฟ้าอัตโนมัติของการทดสอบหน่วยพื้นฐานสำหรับไลบรารี C / C ++ ที่ใช้ร่วมกัน มันสามารถสร้างข้อมูลที่สมเหตุสมผล (ส่วนใหญ่ แต่น่าเสียดายที่ไม่ใช่ทุกกรณี) ข้อมูลอินพุตสำหรับพารามิเตอร์และสร้างกรณีทดสอบแบบง่าย ("สติปัญญา" หรือ "ตื้น" - คุณภาพ) สำหรับทุกฟังก์ชั่นใน API ผ่านการวิเคราะห์การประกาศในส่วนหัว ไฟล์

คุณภาพของการทดสอบที่สร้างขึ้นช่วยให้ตรวจสอบว่าไม่มีข้อผิดพลาดร้ายแรงในกรณีที่ใช้ง่าย เครื่องมือนี้สามารถสร้างและดำเนินการทดสอบที่สร้างขึ้นและตรวจสอบข้อผิดพลาด (segfaults), ยกเลิก, สัญญาณที่ปล่อยออกมาทุกชนิด, โค้ดส่งคืนโปรแกรมที่ไม่เป็นศูนย์และโปรแกรมหยุดทำงาน

คุณสมบัติที่เป็นเอกลักษณ์เมื่อเปรียบเทียบกับ CppUnit, Boost และ Google Test:

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