Solusi satu header sederhana untuk pengujian unit untuk C/C ++.
Just #include "utest.h" dalam kode Anda!
Platform yang didukung saat ini adalah Linux, MacOS, dan Windows.
Kompiler yang didukung saat ini adalah GCC, Clang, MSVC's Cl.exe, dan Clang-Cl.exe.
Ini juga berfungsi dengan TCC tetapi dengan peringatan: rilis terbaru dari TCC Compiler (versi 0.9.27) tidak memiliki fitur untuk bekerja sama sekali. Pastikan untuk menggunakan TCC yang ditambal dengan ekstensi atribut konstruktor. Distro Ubuntu dan Debian Linux baru -baru ini mengirimkan TCC dengan tambalan itu sudah termasuk. Jika Anda mengkompilasi TCC sendiri, gunakan versi trunk dan itu akan berfungsi seperti yang diharapkan.
utest.h mendukung beberapa opsi baris perintah:
--help untuk menghasilkan pesan bantuan--filter=<filter> Akan memfilter kasus uji yang akan dijalankan (berguna untuk menjalankan kembali satu case uji pelanggaran tertentu).--list-tests akan mencantumkan nama test, satu per baris. Nama keluaran dapat diteruskan ke --filter .--output=<output> Akan mengeluarkan file XML XUnit dengan hasil tes (bahwa Jenkins, Travis-CI, dan Appveyor dapat menguraikan untuk hasil tes).--enable-mixed-units akan memungkinkan output per-test berisi unit campuran (S/MS/US/NS).--random-order[=<seed>] akan mengacak urutan tes dijalankan. Jika argumen opsional tidak disediakan, maka biji awal acak digunakan. UTEST adalah pustaka header tunggal untuk memungkinkan semua kesenangan pengujian unit di C dan C ++. Perpustakaan telah dirancang untuk memberikan output yang mirip dengan kerangka kerja Googletest Google:
[==========] Running 1 test cases.
[ RUN ] foo.bar
[ OK ] foo.bar (631ns)
[==========] 1 test cases ran.
[ PASSED ] 1 tests.
Dalam satu file C atau C ++, Anda harus menghubungi UTest_Main makro:
UTEST_MAIN ()Ini akan memanggil ke utest.h, instantiate semua testcases dan jalankan kerangka kerja uji unit.
Atau, jika Anda ingin menulis utama utama Anda sendiri dan menelepon ke utest.h, Anda dapat, dalam satu panggilan file C atau C ++:
UTEST_STATE ();Dan kemudian ketika Anda siap untuk memanggil kerangka kerja utest.h:
int main ( int argc , const char * const argv []) {
// do your own thing
return utest_main ( argc , argv );
}Untuk mendefinisikan test case untuk dijalankan, Anda dapat melakukan hal berikut;
#include "utest.h"
UTEST ( foo , bar ) {
ASSERT_TRUE ( 1 );
}Makro Utest mengambil dua parameter - yang pertama adalah himpunan yang dimiliki oleh kasus uji, yang kedua adalah nama tes. Ini memungkinkan tes dikelompokkan untuk kenyamanan.
Testcase perlengkapan adalah salah satu di mana ada struct yang dipakai yang dapat dibagikan di beberapa testcases.
struct MyTestFixture {
char c ;
int i ;
float f ;
};
UTEST_F_SETUP ( MyTestFixture ) {
utest_fixture -> c = 'a' ;
utest_fixture -> i = 42 ;
utest_fixture -> f = 3.14f ;
// we can even assert and expect in setup!
ASSERT_EQ ( 42 , utest_fixture -> i );
EXPECT_TRUE (true);
}
UTEST_F_TEARDOWN ( MyTestFixture ) {
// and also assert and expect in teardown!
ASSERT_EQ ( 13 , utest_fixture -> i );
}
UTEST_F ( MyTestFixture , a ) {
utest_fixture -> i = 13 ;
// teardown will succeed because i is 13...
}
UTEST_F ( MyTestFixture , b ) {
utest_fixture -> i = 83 ;
// teardown will fail because i is not 13!
}Beberapa hal yang perlu diperhatikan yang ditunjukkan di atas:
UTEST_F_SETUP dan UTEST_F_TEARDOWN - bahkan jika mereka tidak melakukan apa pun di dalam tubuh.Terkadang Anda ingin menggunakan perlengkapan yang sama dan menguji berulang kali, tetapi mungkin secara halus mengubah satu variabel di dalamnya. Di sinilah testcases yang diindeks masuk.
struct MyTestIndexedFixture {
bool x ;
bool y ;
};
UTEST_I_SETUP ( MyTestIndexedFixture ) {
if ( utest_index < 30 ) {
utest_fixture -> x = utest_index & 1 ;
utest_fixture -> y = ( utest_index + 1 ) & 1 ;
}
}
UTEST_I_TEARDOWN ( MyTestIndexedFixture ) {
EXPECT_LE ( 0 , utest_index );
}
UTEST_I ( MyTestIndexedFixture , a , 2 ) {
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}
UTEST_I ( MyTestIndexedFixture , b , 42 ) {
// this will fail when the index is >= 30
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}Catatan:
Menyesuaikan apa yang dimiliki Googletest, kami menyediakan dua varian dari masing -masing kondisi pemeriksaan kesalahan - menegaskan dan mengharapkan. Jika sebuah assert gagal, kasus uji akan menghentikan eksekusi, dan UTest.h akan melanjutkan dengan kasus uji berikutnya yang akan dijalankan. Jika suatu harapan gagal, sisa kasus uji masih akan dieksekusi, memungkinkan pemeriksaan lebih lanjut dilakukan.
Kami saat ini menyediakan makro berikut untuk digunakan dalam UNESTS:
Menegaskan bahwa x mengevaluasi ke benar (mis. Non-nol).
UTEST ( foo , bar ) {
int i = 1 ;
ASSERT_TRUE ( i ); // pass!
ASSERT_TRUE ( 42 ); // pass!
ASSERT_TRUE ( 0 ); // fail!
}Menegaskan bahwa x mengevaluasi ke false (mis. Nol).
UTEST ( foo , bar ) {
int i = 0 ;
ASSERT_FALSE ( i ); // pass!
ASSERT_FALSE ( 1 ); // fail!
}Menegaskan bahwa x dan y adalah sama.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
ASSERT_EQ ( a , b ); // pass!
ASSERT_EQ ( a , 42 ); // pass!
ASSERT_EQ ( 42 , b ); // pass!
ASSERT_EQ ( 42 , 42 ); // pass!
ASSERT_EQ ( a , b + 1 ); // fail!
}Menegaskan bahwa x dan y tidak sama.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_NE ( a , b ); // pass!
ASSERT_NE ( a , 27 ); // pass!
ASSERT_NE ( 69 , b ); // pass!
ASSERT_NE ( 42 , 13 ); // pass!
ASSERT_NE ( a , 42 ); // fail!
}Menegaskan bahwa x kurang dari y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LT ( a , b ); // pass!
ASSERT_LT ( a , 27 ); // pass!
ASSERT_LT ( 27 , b ); // pass!
ASSERT_LT ( 13 , 42 ); // pass!
ASSERT_LT ( b , a ); // fail!
}Menegaskan bahwa x kurang dari atau sama dengan y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LE ( a , b ); // pass!
ASSERT_LE ( a , 27 ); // pass!
ASSERT_LE ( a , 13 ); // pass!
ASSERT_LE ( 27 , b ); // pass!
ASSERT_LE ( 42 , b ); // pass!
ASSERT_LE ( 13 , 13 ); // pass!
ASSERT_LE ( 13 , 42 ); // pass!
ASSERT_LE ( b , a ); // fail!
}Menegaskan bahwa x lebih besar dari y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GT ( a , b ); // pass!
ASSERT_GT ( a , 27 ); // pass!
ASSERT_GT ( 27 , b ); // pass!
ASSERT_GT ( 42 , 13 ); // pass!
ASSERT_GT ( b , a ); // fail!
}Menegaskan bahwa x lebih besar dari atau sama dengan y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GE ( a , b ); // pass!
ASSERT_GE ( a , 27 ); // pass!
ASSERT_GE ( a , 13 ); // pass!
ASSERT_GE ( 27 , b ); // pass!
ASSERT_GE ( 42 , b ); // pass!
ASSERT_GE ( 13 , 13 ); // pass!
ASSERT_GE ( 42 , 13 ); // pass!
ASSERT_GE ( b , a ); // fail!
}Menegaskan bahwa string x dan y adalah sama.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STREQ ( a , a ); // pass!
ASSERT_STREQ ( b , b ); // pass!
ASSERT_STREQ ( a , b ); // fail!
}Menegaskan bahwa string x dan y tidak sama.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STRNE ( a , b ); // pass!
ASSERT_STRNE ( a , a ); // fail!
}Menegaskan bahwa string x dan y sama dengan panjang string x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
ASSERT_STRNEQ ( a , a ); // pass!
ASSERT_STRNEQ ( b , b ); // pass!
ASSERT_STRNEQ ( a , b ); // pass!
}Menegaskan bahwa string x dan y tidak sama dengan panjang string x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
ASSERT_STRNNE ( a , b ); // pass!
ASSERT_STRNNE ( a , a ); // fail!
}Menegaskan bahwa nilai titik mengambang x dan y berada dalam jarak epsilon satu sama lain.
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
ASSERT_NEAR ( a , b , 0.01f ); // pass!
ASSERT_NEAR ( a , b , 0.001f ); // fail!
}Menegaskan bahwa Exception_Type akan dilemparkan ketika kode X dieksekusi.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
ASSERT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
ASSERT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
ASSERT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}Mengharapkan bahwa X mengevaluasi ke true (yaitu bukan nol).
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE ( i ); // pass!
EXPECT_TRUE ( 42 ); // pass!
EXPECT_TRUE ( 0 ); // fail!
}Mengharapkan bahwa X mengevaluasi ke false (yaitu nol).
UTEST ( foo , bar ) {
int i = 0 ;
EXPECT_FALSE ( i ); // pass!
EXPECT_FALSE ( 1 ); // fail!
}Mengharapkan bahwa x dan y sama.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
EXPECT_EQ ( a , b ); // pass!
EXPECT_EQ ( a , 42 ); // pass!
EXPECT_EQ ( 42 , b ); // pass!
EXPECT_EQ ( 42 , 42 ); // pass!
EXPECT_EQ ( a , b + 1 ); // fail!
}Mengharapkan bahwa x dan y tidak sama.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_NE ( a , b ); // pass!
EXPECT_NE ( a , 27 ); // pass!
EXPECT_NE ( 69 , b ); // pass!
EXPECT_NE ( 42 , 13 ); // pass!
EXPECT_NE ( a , 42 ); // fail!
}Mengharapkan x kurang dari y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LT ( a , b ); // pass!
EXPECT_LT ( a , 27 ); // pass!
EXPECT_LT ( 27 , b ); // pass!
EXPECT_LT ( 13 , 42 ); // pass!
EXPECT_LT ( b , a ); // fail!
}Mengharapkan bahwa x kurang dari atau sama dengan y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LE ( a , b ); // pass!
EXPECT_LE ( a , 27 ); // pass!
EXPECT_LE ( a , 13 ); // pass!
EXPECT_LE ( 27 , b ); // pass!
EXPECT_LE ( 42 , b ); // pass!
EXPECT_LE ( 13 , 13 ); // pass!
EXPECT_LE ( 13 , 42 ); // pass!
EXPECT_LE ( b , a ); // fail!
}Mengharapkan x lebih besar dari y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GT ( a , b ); // pass!
EXPECT_GT ( a , 27 ); // pass!
EXPECT_GT ( 27 , b ); // pass!
EXPECT_GT ( 42 , 13 ); // pass!
EXPECT_GT ( b , a ); // fail!
}Mengharapkan bahwa x lebih besar dari atau sama dengan y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GE ( a , b ); // pass!
EXPECT_GE ( a , 27 ); // pass!
EXPECT_GE ( a , 13 ); // pass!
EXPECT_GE ( 27 , b ); // pass!
EXPECT_GE ( 42 , b ); // pass!
EXPECT_GE ( 13 , 13 ); // pass!
EXPECT_GE ( 42 , 13 ); // pass!
EXPECT_GE ( b , a ); // fail!
}Mengharapkan string x dan y sama.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STREQ ( a , a ); // pass!
EXPECT_STREQ ( b , b ); // pass!
EXPECT_STREQ ( a , b ); // fail!
}Mengharapkan string x dan y tidak sama.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STRNE ( a , b ); // pass!
EXPECT_STRNE ( a , a ); // fail!
}Mengharapkan bahwa string x dan y sama dengan panjang string x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
EXPECT_STRNEQ ( a , a ); // pass!
EXPECT_STRNEQ ( b , b ); // pass!
EXPECT_STRNEQ ( a , b ); // pass!
}Mengharapkan bahwa string x dan y tidak sama dengan panjang string x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
EXPECT_STRNNE ( a , b ); // pass!
EXPECT_STRNNE ( a , a ); // fail!
}Mengharapkan bahwa nilai-nilai floating-point x dan y berada dalam jarak epsilon satu sama lain.
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
EXPECT_NEAR ( a , b , 0.01f ); // pass!
EXPECT_NEAR ( a , b , 0.001f ); // fail!
}Mengharapkan bahwa Exception_Type akan dilemparkan ketika kode X dieksekusi.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
EXPECT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
EXPECT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
EXPECT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}Mengharapkan bahwa Exception_Type akan dilemparkan dengan Exception_Message pesan saat kode X dieksekusi.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error ( " bad bar " );
}
UTEST (foo, bar) {
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std::range_error, " bad bar " ); // pass!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 2 ), std::range_error, " bad bar2 " ); // fail!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std:: exception , " bad bar " ); // fail!
} Makro ini memungkinkan Anda menandai test case sebagai dilewati - mis. bahwa kasus uji tidak dapat dieksekusi. Tes akan berhenti berjalan saat Anda menjalankan makro, melaporkan msg sebagai alasan untuk dilewati, dan menandai tes sebagai 'dilewati' . Ini akan dilaporkan pada akhir eksekusi sebelum kegagalan, dan kasus uji yang dilewati tidak akan menyebabkan proses keluar dengan kode non-nol.
UTEST ( foo , bar ) {
UTEST_SKIP ( "Need to implement this test!" );
}Selain itu, untuk memberikan kemungkinan memiliki pesan khusus dalam tes kesalahan, semua makro dapat digunakan dengan akhiran yang disebut "_msg", yang menerima parameter tambahan, yang merupakan string dengan pesan khusus untuk dicetak jika terjadi kegagalan.
Misalnya:
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE_MSG ( i , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 42 , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 0 , "custom message" ); // fail! (with the following output)
} test.cpp:42: Failure
Expected : true
Actual : false
Message : custom message
[ FAILED ] foo.bar (8086ns)
Perpustakaan mendukung menegaskan jenis bilangan bulat, titik mengambang, atau pointer.
Ini adalah perangkat lunak gratis dan tidak terbebani yang dirilis ke dalam domain publik.
Siapa pun bebas untuk menyalin, memodifikasi, mempublikasikan, menggunakan, mengkompilasi, menjual, atau mendistribusikan perangkat lunak ini, baik dalam bentuk kode sumber atau sebagai biner yang dikompilasi, untuk tujuan apa pun, komersial atau non-komersial, dan dengan cara apa pun.
Dalam yurisdiksi yang mengakui undang -undang hak cipta, penulis atau penulis perangkat lunak ini mendedikasikan setiap dan semua minat hak cipta dalam perangkat lunak ke domain publik. Kami membuat dedikasi ini untuk kepentingan publik pada umumnya dan merugikan ahli waris dan penerus kami. Kami bermaksud pengabdian ini untuk menjadi tindakan pelepasan yang terbuka untuk selamanya dari semua hak saat ini dan di masa depan untuk perangkat lunak ini berdasarkan hukum hak cipta.
Perangkat lunak ini disediakan "sebagaimana adanya", tanpa jaminan apa pun, tersurat maupun tersirat, termasuk tetapi tidak terbatas pada jaminan dapat diperjualbelikan, kebugaran untuk tujuan tertentu dan nonpringement. Dalam hal apa pun penulis tidak akan bertanggung jawab atas klaim, kerusakan atau pertanggungjawaban lainnya, baik dalam tindakan kontrak, gugatan atau sebaliknya, timbul dari, di luar atau sehubungan dengan perangkat lunak atau penggunaan atau transaksi lain dalam perangkat lunak.
Untuk informasi lebih lanjut, silakan merujuk ke http://unlicense.org/