it-swarm-id.com

Unit Pengujian Kode C

Saya bekerja pada sistem tertanam musim panas ini ditulis dalam C. lurus. Itu adalah proyek yang sudah ada yang diambil alih oleh perusahaan tempat saya bekerja. Saya menjadi sangat terbiasa menulis unit test di Java menggunakan JUnit tetapi bingung bagaimana cara terbaik untuk menulis unit test untuk kode yang ada (yang perlu refactoring) serta kode baru yang ditambahkan ke sistem.

Apakah ada cara untuk membuat pengujian unit kode C semudah unit menguji kode Java dengan, misalnya, JUnit? Setiap wawasan yang akan diterapkan secara khusus untuk pengembangan yang disematkan (cross-compiling ke platform arm-linux) akan sangat dihargai.

812
Paul Osborne

Satu kerangka pengujian unit dalam C adalah Periksa ; daftar kerangka pengujian unit dalam C dapat ditemukan di sini dan direproduksi di bawah ini. Bergantung pada berapa banyak fungsi pustaka standar yang dimiliki runtime Anda, Anda mungkin bisa atau tidak bisa menggunakan salah satunya.

AceUnit

AceUnit (Advanced C dan Unit Tertanam) menagih dirinya sebagai kerangka uji unit kode C yang nyaman. Ia mencoba meniru JUnit 4.x dan menyertakan kemampuan seperti refleksi. AceUnit dapat digunakan di lingkungan kendala sumber daya, mis. pengembangan perangkat lunak tertanam, dan yang penting itu berjalan dengan baik di lingkungan di mana Anda tidak dapat menyertakan file header standar tunggal dan tidak dapat menjalankan fungsi C standar tunggal dari perpustakaan ANSI/ISO C. Ini juga memiliki port Windows. Itu tidak menggunakan garpu untuk menjebak sinyal, meskipun penulis telah menyatakan minatnya untuk menambahkan fitur seperti itu. Lihat beranda AceUnit .

GNU Autounit

Banyak di sepanjang baris yang sama dengan Periksa, termasuk forking untuk menjalankan tes unit dalam ruang alamat yang terpisah (pada kenyataannya, penulis asli Periksa meminjam ide dari GNU Autounit). GNU Autounit menggunakan GLib secara luas, yang berarti bahwa penautan dan semacamnya memerlukan opsi khusus, tetapi ini mungkin bukan masalah besar bagi Anda, terutama jika Anda sudah menggunakan GTK atau GLib. Lihat beranda GNU Autounit .

cUnit

Juga menggunakan GLib, tetapi tidak bercabang untuk melindungi ruang alamat pengujian unit.

CUnit

Standar C, dengan rencana untuk implementasi GUI Win32. Saat ini tidak bercabang atau melindungi ruang alamat pengujian unit. Dalam pengembangan awal. Lihat beranda CUnit .

CuTest

Kerangka kerja sederhana dengan hanya satu file .c dan satu file .h yang Anda masukkan ke pohon sumber Anda. Lihat beranda CuTest .

CppUnit

Kerangka pengujian unit utama untuk C++; Anda juga dapat menggunakannya untuk menguji kode C. Ini stabil, dikembangkan secara aktif, dan memiliki antarmuka GUI. Alasan utama untuk tidak menggunakan CppUnit untuk C adalah pertama bahwa itu cukup besar, dan kedua Anda harus menulis tes Anda dalam C++, yang berarti Anda memerlukan kompiler C++. Jika ini tidak terdengar seperti kekhawatiran, itu pasti layak dipertimbangkan, bersama dengan kerangka pengujian unit C++ lainnya. Lihat beranda CppUnit .

embUnit

embUnit (Embedded Unit) adalah kerangka kerja unit test lain untuk sistem embedded. Yang ini tampaknya digantikan oleh AceUnit. beranda Unit Tertanam .

MinUnit

Satu set makro minimal dan hanya itu! Intinya adalah untuk menunjukkan betapa mudahnya unit menguji kode Anda. Lihat beranda MinUnit .

CUnit untuk Tn. Ando

Implementasi CUnit yang cukup baru, dan tampaknya masih dalam pengembangan awal. Lihat beranda CUnit untuk beranda Pak Ando .

Daftar ini terakhir diperbarui pada Maret 2008.

Lebih banyak kerangka kerja:

CMocka

CMocka adalah kerangka uji untuk C dengan dukungan untuk benda tiruan. Mudah digunakan dan diatur.

Lihat beranda CMocka .

Kriteria

Kriteria adalah kerangka kerja pengujian unit lintas-platform C yang mendukung registrasi pengujian otomatis, pengujian parameter, teori, dan yang dapat ditampilkan ke berbagai format, termasuk TAP dan JUnit XML. Setiap tes dijalankan dalam prosesnya sendiri, sehingga sinyal dan gangguan dapat dilaporkan atau diuji jika diperlukan.

Lihat beranda Kriteria untuk informasi lebih lanjut.

HUT

HWUT adalah alat Unit Test umum dengan dukungan besar untuk C. Ini dapat membantu untuk membuat Makefile, menghasilkan kasus uji besar-besaran yang dikodekan dalam 'tabel iterasi' minimal, berjalan di sepanjang mesin negara, menghasilkan C-stubs dan banyak lagi. Pendekatan umum cukup unik: Putusan didasarkan pada 'stdout baik/buruk stdout'. Namun, fungsi perbandingannya fleksibel. Dengan demikian, semua jenis skrip dapat digunakan untuk memeriksa. Ini dapat diterapkan ke bahasa apa pun yang dapat menghasilkan output standar.

Lihat beranda HWUT .

CGreen

Kerangka uji dan mengejek unit cross-bahasa modern, portabel, dan untuk C dan C++. Ini menawarkan notasi BDD opsional, perpustakaan mengejek, kemampuan untuk menjalankannya dalam satu proses (untuk mempermudah proses debug). Pelari uji yang menemukan fungsi tes secara otomatis tersedia. Tapi Anda bisa membuat program sendiri.

Semua fitur tersebut (dan banyak lagi) dijelaskan di manual CGreen .

Wikipedia memberikan daftar terperinci kerangka pengujian unit C di bawah Daftar kerangka pengujian unit: C

463
Adam Rosenfield

Secara pribadi saya suka Google Test framework .

Kesulitan nyata dalam pengujian kode C adalah memutus ketergantungan pada modul eksternal sehingga Anda dapat mengisolasi kode dalam unit. Ini bisa sangat bermasalah ketika Anda mencoba melakukan tes di sekitar kode lama. Dalam hal ini saya sering menemukan diri saya menggunakan tautan untuk menggunakan fungsi bertopik dalam tes.

Inilah yang dirujuk orang ketika mereka berbicara tentang " jahitan ". Di C, satu-satunya pilihan Anda adalah menggunakan pra-prosesor atau tautan untuk menghilangkan ketergantungan Anda.

Rangkaian uji khas di salah satu proyek C saya mungkin terlihat seperti ini:

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

Perhatikan bahwa Anda sebenarnya termasuk file C dan bukan file header . Ini memberi keuntungan akses ke semua anggota data statis. Di sini saya mengejek logger saya (yang mungkin di logger.o dan memberikan implementasi kosong. Ini berarti bahwa file uji mengkompilasi dan tautan secara independen dari sisa basis kode dan dijalankan secara terpisah.

Sedangkan untuk mengkompilasi silang kode, agar ini berfungsi, Anda memerlukan fasilitas yang baik pada target. Saya telah melakukan ini dengan lintas googletest yang dikompilasi ke Linux pada arsitektur PowerPC. Ini masuk akal karena di sana Anda memiliki Shell dan os lengkap untuk mengumpulkan hasil Anda. Untuk lingkungan yang kurang kaya (yang saya klasifikasikan sebagai apa saja tanpa OS penuh) Anda harus membangun dan menjalankannya pada Host. Anda harus tetap melakukan ini sehingga Anda dapat menjalankan tes secara otomatis sebagai bagian dari build.

Saya menemukan pengujian kode C++ umumnya jauh lebih mudah karena fakta bahwa OO kode secara umum jauh lebih sedikit digabungkan daripada prosedural (tentu saja ini sangat tergantung pada gaya pengkodean). Juga di C++ Anda dapat menggunakan trik seperti injeksi ketergantungan dan metode overriding untuk mendapatkan jahitan ke dalam kode yang dinyatakan dikemas.

Michael Feathers memiliki buku bagus tentang pengujian kode lama . Dalam satu bab ia membahas teknik untuk menangani kode non-OO yang sangat saya rekomendasikan.

Edit : Saya telah menulis posting blog tentang unit kode pengujian prosedur, dengan sumber tersedia di GitHub .

Edit : Ada buku baru yang keluar dari Programmer Pragmatis yang secara khusus membahas unit menguji kode C yang --- Saya sangat merekomendasikan .

152
mikelong

Minunit adalah kerangka kerja pengujian unit yang sangat sederhana. Saya menggunakannya untuk unit test c kode mikrokontroler untuk AVR.

128
Matteo Caprari

Saat ini saya menggunakan kerangka uji unit CuTest:

http://cutest.sourceforge.net/

Ini ideal untuk sistem tertanam karena sangat ringan dan sederhana. Saya tidak punya masalah menjalankannya pada platform target maupun pada desktop. Selain menulis tes unit, semua yang diperlukan adalah:

  • file header disertakan di mana pun Anda menelepon rutinitas CuTest
  • satu file 'C' tambahan untuk dikompilasi/dihubungkan ke dalam gambar
  • beberapa kode sederhana ditambahkan ke main untuk mengatur dan memanggil unit test - Saya hanya memiliki ini dalam fungsi main () khusus yang akan dikompilasi jika UNITTEST didefinisikan selama build.

Sistem perlu mendukung heap dan beberapa fungsi stdio (yang tidak dimiliki semua sistem embedded). Tetapi kodenya cukup sederhana sehingga Anda mungkin bisa bekerja di alternatif untuk persyaratan tersebut jika platform Anda tidak memilikinya.

Dengan beberapa penggunaan extern "C" {} blok yang bijaksana, ia juga mendukung pengujian C++.

40
Michael Burr

Saya mengatakan hampir sama dengan ratkok tetapi jika Anda memiliki twist tertanam ke unit test maka ...

nity - Kerangka kerja yang sangat direkomendasikan untuk pengujian kode C unit.

Contoh dalam buku yang disebutkan di utas ini TDD untuk embedded C ditulis menggunakan Unity (dan CppUTest).

36
Johan

Anda juga mungkin ingin melihat libtap , kerangka kerja pengujian C yang menghasilkan Test Anything Protocol (TAP) dan dengan demikian terintegrasi dengan baik dengan berbagai alat yang keluar untuk teknologi ini. Ini sebagian besar digunakan di dunia bahasa yang dinamis, tetapi mudah digunakan dan menjadi sangat populer.

Sebuah contoh:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}
32
Ovid

Ada kerangka pengujian unit yang elegan untuk C dengan dukungan untuk objek tiruan yang disebut cmocka . Ini hanya membutuhkan pustaka C standar, bekerja pada berbagai platform komputasi (termasuk tertanam) dan dengan kompiler yang berbeda.

Ini juga memiliki dukungan untuk format output pesan yang berbeda seperti Subunit, Test Anything Protocol dan laporan XML jUnit.

cmocka telah dibuat untuk juga berfungsi pada platform tertanam dan juga memiliki dukungan Windows.

Tes sederhana terlihat seperti ini:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

API sepenuhnya didokumentasikan dan beberapa contoh adalah bagian dari kode sumber.

Untuk memulai dengan cmocka, Anda harus membaca artikel di LWN.net: Pengujian unit dengan objek tiruan di C

cmocka 1.0 telah dirilis Februari 2015.

26
asn

Saya tidak jauh-jauh menguji aplikasi C warisan sebelum saya mulai mencari cara untuk mengejek fungsi. Saya sangat membutuhkan tiruan untuk mengisolasi file C yang ingin saya uji dari orang lain. Saya mencoba cmock dan saya pikir saya akan mengadopsinya.

Cmock memindai file header dan menghasilkan fungsi tiruan berdasarkan prototipe yang ditemukannya. Mocks akan memungkinkan Anda untuk menguji file C dalam isolasi yang sempurna. Yang harus Anda lakukan adalah menautkan file pengujian Anda dengan tiruan alih-alih file objek nyata Anda.

Keuntungan lain dari cmock adalah ia akan memvalidasi parameter yang diteruskan ke fungsi yang diolok-olok, dan itu akan memungkinkan Anda menentukan nilai pengembalian yang seharusnya diberikan oleh tiruan itu. Ini sangat berguna untuk menguji berbagai aliran eksekusi di fungsi Anda.

Tes terdiri dari fungsi testA (), testB () yang tipikal di mana Anda membangun harapan, memanggil fungsi untuk menguji dan memeriksa pernyataan.

Langkah terakhir adalah menghasilkan pelari untuk pengujian Anda dengan satu. Cmock terikat pada kerangka uji kesatuan. Unity mudah dipelajari seperti halnya kerangka kerja unit test lainnya.

Layak dicoba dan cukup mudah untuk dipahami:

http://sourceforge.net/apps/trac/cmock/wiki

Pembaruan 1

Kerangka kerja lain yang saya selidiki adalah Cmockery.

http://code.google.com/p/cmockery/

Ini adalah kerangka kerja C murni yang mendukung pengujian dan mengejek unit. Ia tidak memiliki ketergantungan pada Ruby (bertentangan dengan Cmock) dan ia memiliki sedikit ketergantungan pada lib eksternal.

Dibutuhkan sedikit lebih banyak pekerjaan manual untuk mengatur tiruan karena tidak menghasilkan kode. Itu tidak mewakili banyak pekerjaan untuk proyek yang sudah ada karena prototipe tidak akan banyak berubah: setelah Anda mengejek Anda, Anda tidak perlu mengubahnya untuk sementara waktu (ini kasus saya). Pengetikan ekstra memberikan kontrol penuh terhadap ejekan. Jika ada sesuatu yang tidak Anda sukai, Anda cukup mengubah tiruan Anda.

Tidak perlu pelari ujian khusus. Anda hanya perlu membuat array tes dan meneruskannya ke fungsi run_tests. Sedikit lebih banyak pekerjaan manual di sini juga, tetapi saya pasti menyukai gagasan tentang kerangka kerja mandiri yang mandiri.

Plus itu mengandung beberapa trik C bagus yang saya tidak tahu.

Secara keseluruhan Cmockery membutuhkan sedikit lebih banyak pemahaman tentang cemoohan untuk memulai. Contohnya akan membantu Anda mengatasi hal ini. Sepertinya bisa melakukan pekerjaan dengan mekanik yang lebih sederhana.

20
Philippe A.

Sebagai seorang pemula C, saya menemukan slide yang disebut Pengembangan yang didorong oleh tes di C sangat membantu. Pada dasarnya, ini menggunakan assert() standar bersama dengan && untuk mengirim pesan, tanpa ketergantungan eksternal. Jika seseorang terbiasa dengan kerangka kerja pengujian tumpukan penuh, ini mungkin tidak akan berhasil :)

15
chelmertz

Saya tidak menggunakan framework, saya hanya menggunakan autotools "check" target support. Terapkan "utama" dan gunakan pernyataan (s).

Dir test saya Makefile.am terlihat seperti:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp
12
navicore

Ada CUnit

Dan Unit Tertanam adalah kerangka kerja pengujian unit untuk Sistem C Tertanam. Desainnya disalin dari JUnit dan CUnit dan banyak lagi, dan kemudian diadaptasi untuk Embedded C System. Unit Tertanam tidak memerlukan std C libs. Semua objek dialokasikan ke area const.

Dan Tessy mengotomatiskan pengujian unit perangkat lunak tertanam.

12
prakash

Kami menulis CHEAT (dihosting pada GitHub ) untuk kemudahan penggunaan dan portabilitas.

Tidak memiliki dependensi dan tidak memerlukan instalasi atau konfigurasi. Hanya file header dan test case yang diperlukan.

#include <cheat.h>

CHEAT_TEST(mathematics_still_work,
    cheat_assert(2 + 2 == 4);
    cheat_assert_not(2 + 2 == 5);
)

Tes dikompilasi menjadi yang dapat dieksekusi yang mengurus menjalankan tes dan melaporkan hasilnya.

$ gcc -I . tests.c
$ ./a.out
..
---
2 successful of 2 run
SUCCESS

Ini memiliki warna yang cantik juga.

12
Tuplanolla

Buku Michael Feather "Bekerja Efektif dengan Legacy Code" menyajikan banyak teknik khusus untuk pengujian unit selama pengembangan C.

Ada teknik yang berkaitan dengan injeksi ketergantungan yang khusus untuk C yang belum saya lihat di tempat lain.

11

CppUTest - Kerangka kerja yang sangat direkomendasikan untuk pengujian kode C unit.

Contoh dalam buku yang disebutkan di utas ini TDD untuk embedded C ditulis menggunakan CppUTest.

7
ratkok

selain bias jelas saya

http://code.google.com/p/seatest/

adalah cara sederhana yang bagus untuk menguji kode C unit. meniru xUnit

6
Keith Nicholas

Saya menggunakan CxxTest untuk lingkungan c/c ++ yang disematkan (terutama C++).

Saya lebih suka CxxTest karena memiliki skrip Perl/python untuk membangun test runner. Setelah kemiringan kecil untuk menyiapkannya (masih lebih kecil karena Anda tidak harus menulis test runner), cukup mudah digunakan (termasuk sampel dan dokumentasi yang bermanfaat). Pekerjaan yang paling banyak adalah mengatur 'perangkat keras' yang diakses oleh kode sehingga saya dapat menguji unit/modul secara efektif. Setelah itu mudah untuk menambahkan unit uji unit baru.

Seperti disebutkan sebelumnya itu adalah kerangka uji unit C/C++. Jadi Anda akan memerlukan kompiler C++.

Panduan Pengguna CxxTestCxxTest Wiki

6
Zing-

Setelah membaca Minunit saya pikir cara yang lebih baik adalah mendasarkan tes dalam menegaskan makro yang saya gunakan banyak seperti teknik program defensif. Jadi saya menggunakan ide yang sama tentang Minunit yang dicampur dengan pernyataan standar. Anda dapat melihat kerangka kerja saya (nama yang bagus bisa NoMinunit) di blog k0ga

Google memiliki kerangka pengujian yang sangat baik. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

Dan ya, sejauh yang saya lihat itu akan berfungsi dengan C polos, yaitu tidak memerlukan fitur C++ (mungkin memerlukan kompiler C++, tidak yakin).

4
Paweł Hajdan
4
Landon Kuhn

Cmockery adalah proyek yang baru diluncurkan yang terdiri dari pustaka C yang sangat mudah digunakan untuk menulis unit test.

4

Pertama, lihat di sini: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

Perusahaan saya memiliki perpustakaan C yang digunakan pelanggan kami. Kami menggunakan CxxTest (pustaka uji unit C++) untuk menguji kode. CppUnit juga akan berfungsi. Jika Anda terjebak dalam C, saya akan merekomendasikan RCUNIT (tapi CUnit juga bagus).

3
Kevin
2
Tony Bai

API Sanity Checker - kerangka uji untuk pustaka C/C++:

Generator otomatis pengujian unit dasar untuk pustaka C/C++ bersama. Ia mampu menghasilkan input data yang masuk akal (dalam kebanyakan, tetapi sayangnya tidak semua kasus) parameter dan menyusun kasus uji sederhana ("kewarasan" atau "kualitas dangkal") untuk setiap fungsi dalam API melalui analisis deklarasi di header file.

Kualitas tes yang dihasilkan memungkinkan untuk memeriksa tidak adanya kesalahan kritis dalam kasus penggunaan sederhana. Alat ini mampu membangun dan menjalankan tes yang dihasilkan dan mendeteksi crash (segfault), batal, semua jenis sinyal yang dipancarkan, kode pengembalian program yang tidak nol dan program menggantung.

Contoh:

2
linuxbuild

Saya menggunakan RCUNIT untuk melakukan beberapa pengujian unit untuk kode tertanam pada PC sebelum menguji pada target. Abstraksi antarmuka perangkat keras yang baik adalah penting karena endianness dan register yang dipetakan memori akan membunuh Anda.

2
Gerhard

Jika Anda terbiasa dengan JUnit maka saya merekomendasikan CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

Itu dengan asumsi Anda memiliki c ++ compiler untuk melakukan tes unit. jika tidak maka saya harus setuju dengan Adam Rosenfield bahwa cek adalah yang Anda inginkan.

2
Kwondri

LibU ( http://koanlogic.com/lib ) memiliki modul unit test yang memungkinkan dependensi test suite/case yang eksplisit, isolasi tes, eksekusi paralel dan formatter laporan yang dapat disesuaikan (format default adalah xml dan txt ).

Perpustakaan ini berlisensi BSD dan berisi banyak modul bermanfaat lainnya - jaringan, debugging, struktur data yang umum digunakan, konfigurasi, dll. - jika Anda memerlukannya di proyek Anda ...

1
bongo

Saya terkejut bahwa tidak ada yang disebutkan Cutter (http://cutter.sourceforge.net/) Anda dapat menguji C dan C++, itu terintegrasi dengan mulus dengan autotools dan memiliki tutorial yang sangat bagus tersedia.

1
Kris

Salah satu teknik yang digunakan adalah mengembangkan kode uji unit dengan kerangka C++ xUnit (dan kompiler C++), sambil mempertahankan sumber untuk sistem target sebagai modul C.

Pastikan Anda mengkompilasi sumber C secara teratur di bawah cross-compiler Anda, secara otomatis dengan unit test Anda jika memungkinkan.

1
quamrana

Jika Anda masih mencari kerangka uji, CUnitWin32 adalah satu untuk platform Win32/NT.

Ini memecahkan satu masalah mendasar yang saya hadapi dengan kerangka kerja pengujian lainnya. Yaitu variabel global/statis dalam keadaan deterministik karena setiap tes dijalankan sebagai proses terpisah.

0
Dushara

Jika Anda menargetkan platform Win32 atau mode kernel NT, Anda harus melihat cfix .

0
Johannes Passing

Saya baru saja menulis Libcut karena frustrasi dengan perpustakaan pengujian unit C yang ada. Ini memiliki tipe merangkai primitif otomatis (tidak perlu untuk test_eq_int, test_eq_long, test_eq_short, dll ...; hanya dua set berbeda untuk primitif dan string) dan terdiri dari satu file header. Ini contoh singkatnya:

#include <libcut.h>

LIBCUT_TEST(test_abc) {
    LIBCUT_TEST_EQ(1, 1);
    LIBCUT_TEST_NE(1, 0);
    LIBCUT_TEST_STREQ("abc", "abc");
    LIBCUT_TEST_STRNE("abc", "def");
}

LIBCUT_MAIN(test_abc);

Hanya bekerja dengan C11.

0
kirbyfan64sos