Memulai dengan CppUTest

Memulai dengan CppUTest

Memulai dengan CppUTest

May 14, 2017

Diterbitkan oleh

Diterbitkan oleh

Bird

Bird

Kategori:

Kategori:

Email

Email

Ready to see Bird
in action?

Ready to see Bird
in action?

Getting Started with CppUTest

Di SparkPost, kami mencurahkan banyak waktu dan upaya untuk menguji kode kami. Platform kami ditulis dalam bahasa C, dan baru-baru ini saya meneliti pengintegrasian dengan kerangka kerja pengujian unit yang disebut "CppUTest", yang menyediakan pengujian gaya xUnit untuk C/C++. Kerangka kerja ini kuat, kaya fitur, dan sedang dalam pengembangan aktif, yang membuatnya menjadi pilihan yang tepat. Framework ini juga menyediakan lapisan integrasi C yang membuatnya mudah digunakan dengan kode C platform kami meskipun sebagian besar framework ini adalah C++. Tutorial ini membahas cara memulai dengan CppUTest pada proyek Anda sendiri.


Mengunduh CppUTest

The CppUTest project page is available here, and the repository is on github. It’s also included in the package management repositories for many linux distros, as well as homebrew on Mac OS. The examples that follow were executed on Mac OS X, but they’re derived from code written for Red Hat, the OS our platform runs on.

The basics are well documented on CppUTest’s halaman beranda. We’re going to breeze through that and get to some of the more interesting features.


Meletakkan Fondasi

Pertama-tama, mari kita tulis beberapa kode!

Proyek uji coba kita akan memiliki file 'main' dan akan menyertakan sebuah library utilitas bernama 'code'. Pustaka ini akan menyediakan fungsi sederhana yang menghasilkan nilai 1 (untuk saat ini). File-file tersebut akan ditata seperti ini:

├── src │ ├── code │ │ ├── code.cpp │ │ └── code.h │ └── main.cpp └── t ├── main.cpp └── test.cpp

Mari kita mulai dengan menulis file src/

// src/main.cpp #include <stdlib.h> #include <stdio.h> #include "code.h" int main(void) { test_func(); printf("hello world!\n"); exit(0); }

// src/code/code.cpp #include <stdlib.h> #include "code.h" int test_func () { return 1; }

// src/code/code.h #ifndef __code_h__ #define __code_h__ int test_func (); #endif

Now, let’s do the tests, which will live in the t/ directory.  The first thing to do is to set up a test runner which will run our test files. This is also the ‘main’  function that will execute once this is all compiled:

// t/main.cpp #include "CppUTest/CommandLineTestRunner.h" int main(int ac, char** av) { return CommandLineTestRunner::RunAllTests(ac, av); }

Sekarang kita dapat menulis modul pengujian pertama kita:

// t/test.cpp #include "CppUTest/TestHarness.h" #include "code.h" TEST_GROUP(AwesomeExamples) { }; TEST(AwesomeExamples, FirstExample) { int x = test_func(); CHECK_EQUAL(1, x); }

Next, we need to write makefiles.  We’ll need two: one for the project files under src/, and one for the tests.


File Pembuatan Proyek

Makefile proyek akan berada pada level yang sama dengan direktori 'src' dan 't' pada root proyek. Seharusnya akan terlihat seperti ini:

# Makefile SRC_DIR=./src CODE_DIR=$(SRC_DIR)/code OUT=example TEST_DIR=t test: make -C $(TEST_DIR) test_clean: make -C $(TEST_DIR) clean code.o: gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(KODE_DIR)/kode.o main: kode.o gcc -I$(KODE_DIR) $(KODE_DIR)/kode.o $(SRC_DIR)/main.cpp -o $(OUT) all: test main clean: test_clean rm $(SRC_DIR)/*.o $(KODE_DIR)/*.o $(OUT)

Note that this uses ‘make -C’  for the test targets – meaning that it will call ‘make’  again using the makefile in the test directory.

Pada titik ini kita dapat mengkompilasi kode 'src' dengan makefile dan melihat apakah kode tersebut berfungsi:

[]$ make main gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example []$ ./example hello world!


Tes Makefile

Untuk pengujian, ada beberapa hal yang sedikit lebih rumit karena kita perlu memuat dan mengintegrasikan dengan benar dengan pustaka CppUTest.

Repositori CppUTest menyediakan sebuah berkas bernama "MakefileWorker.mk". File ini menyediakan banyak fungsionalitas yang membuat pembangunan dengan CppUTest menjadi sederhana. File ini berada di bawah direktori "build" di repositori git. Untuk tutorial ini, kita akan mengasumsikan bahwa file tersebut telah disalin ke direktori 't/'. Ini dapat digunakan sebagai berikut:

# kita tidak ingin menggunakan jalur relatif, jadi kita atur variabel-variabel ini PROJECT_DIR=/path/to/project SRC_DIR=$(PROJECT_DIR)/src TEST_DIR=$(PROJECT_DIR)/t # tentukan di mana letak source code dan include INCLUDE_DIRS=$(SRC_DIR)/code SRC_DIRS=$(SRC_DIR)/code TEST_SRC_DIRS = $(TEST_DIR) # tentukan di mana kode uji berada TEST_SRC_DIRS = $(TEST_DIR) # apa yang akan disebut sebagai biner uji TEST_TARGET = contoh # di mana pustaka cpputest berada CPPUTEST_HOME = /usr/local # jalankan MakefileWorker.mk dengan variabel-variabel yang didefinisikan di sini termasuk MakefileWorker.mk

Perhatikan bahwa CPPUTEST_HOME harus disetel ke tempat di mana pun CppUTest diinstal. Jika Anda telah menginstal paket distro, ini biasanya berada di bawah /usr/local pada sistem linux/mac. Jika Anda telah memeriksa repo Anda sendiri, ini ada di mana pun tempat pemeriksaan itu.

Semua opsi ini didokumentasikan di MakefileWorker.mk.

MakefileWorker.mk juga menambahkan beberapa target makefile, termasuk yang berikut ini:

  1. all - membangun tes yang ditunjukkan oleh makefile

  2. clean - menghapus semua objek dan file gcov yang dihasilkan untuk pengujian

  3. realclean - menghapus objek atau file gcov apa pun di seluruh pohon direktori

  4. flags - mencantumkan semua flag yang dikonfigurasi yang digunakan untuk mengkompilasi pengujian

  5. debug - daftar semua file sumber, objek, ketergantungan, dan 'hal-hal yang harus dibersihkan'


Cakupan Kode

Unit testing would not be complete without a coverage report. The go-to tool for this for projects using gcc is gcov, available as part of the standard suite of gcc utilities. Cpputest integrates easily with gcov, all you need to do is add this line ke makefile:

CPPUTEST_USE_GCOV = Y

Next, we need to make sure that the filterGcov.sh script from repo ini is in ‘/scripts/filterGcov.sh’ relative to wherever you set ‘CPPUTEST_HOME’ to be. It also needs to have execute perms.

Pada contoh Makefile, ini akan ditempatkan ke '/usr/local/scripts/filterGcov.sh'. Jika Anda menjalankan CppUTest dari repositori repo, semuanya akan bekerja tanpa modifikasi.


Dengan itu, Anda cukup menjalankan 'make gcov' dan analisis akan dihasilkan untuk Anda. Dalam kasus kita, kita harus menggunakan 'make -B' untuk membangun kembali file objek dengan gcov yang diaktifkan:

[]$ make -B gcov < compilation output > for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \ FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \ gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \ done for f in ; do \ gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \ done /usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt cat gcov_report.txt 100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp mkdir -p gcov mv *.gcov gcov mv gcov_* gcov See gcov directory for details

Ini akan mengeluarkan sejumlah file ke direktori 'gcov' yang baru. Ini adalah:

  1. code.cpp.gcov - file 'gcov' yang sebenarnya untuk kode yang sedang diuji

  2. gcov_error.txt - laporan kesalahan (dalam kasus kami, seharusnya kosong)

  3. gcov_output.txt - keluaran aktual dari perintah gcov yang dijalankan

  4. gcov_report.txt - ringkasan cakupan untuk setiap file yang diuji

  5. gcov_report.txt.html - versi html dari gcov_report


Deteksi Kebocoran Memori Cpputest

Cpputest memungkinkan Anda untuk secara otomatis mendeteksi memori yang bocor dengan mendefinisikan ulang keluarga fungsi "malloc/free" standar untuk menggunakan pembungkusnya sendiri. Hal ini memungkinkannya untuk dengan cepat menangkap kebocoran dan melaporkannya untuk setiap eksekusi pengujian. Ini diaktifkan secara default di MakefileWorker.mk, jadi sudah aktif dengan langkah-langkah yang diuraikan sejauh ini.

To illustrate, let’s leak some memory in test_func() !

Going back to code.c, we add a malloc()  ke function, like so:

int test_func() { malloc(1); return 1; }

Sekarang, setelah kompilasi ulang, kesalahan berikut ini dihasilkan:

test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample) Memory leak(s) found. Alloc num (4) Leak size: 1 Allocated at: ./code.c and line: 6. Type: "malloc" Memory: <0x7fc9e94056d0> Content: 0000: 00 |.| Total number of leaks: 1

Hal ini menunjukkan pengujian mana yang menyebabkan kebocoran, di mana kebocoran terjadi pada kode sumber, dan apa yang ada di dalam memori yang bocor. Sangat membantu!

Ada beberapa peringatan dengan fitur ini:

  1. Cpputest menggunakan makro preprocessor untuk mendefinisikan ulang secara dinamis semua panggilan ke fungsi-fungsi manajemen memori standar. Ini berarti hanya akan bekerja untuk pemanggilan dalam kode sumber yang sedang diuji karena itulah yang dikompilasi dengan penggantian CppUTest. Kebocoran pada pustaka yang terhubung tidak akan tertangkap.

  2. Terkadang memori yang dialokasikan untuk seluruh masa pakai proses tidak dimaksudkan untuk dibebaskan. Hal ini dapat membuat banyak kesalahan spam jika Anda menguji modul dengan perilaku ini. Untuk menonaktifkan deteksi kebocoran, Anda dapat melakukan ini:

CPPUTEST_USE_MEM_LEAK_DETECTION = N


Tertarik dengan yang lainnya?

Ini hanyalah puncak gunung es dari semua fitur yang terdapat dalam alat ini. Selain dasar-dasar yang dibahas di sini, repo ini juga memiliki kerangka kerja mocking, lapisan integrasi C langsung, dan kerangka kerja plugin, untuk menyebutkan beberapa yang penting. Repo ini juga berisi seluruh direktori skrip pembantu yang dapat membantu mengotomatiskan beberapa bagian rutin dalam bekerja dengan framework.

Saya harap informasi di sini dapat membantu Anda meningkatkan kualitas kode C/C++ Anda dengan alat yang hebat ini!

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> to the right person -> di right time.

By clicking "See Bird" you agree to Bird's Pemberitahuan Privasi.

Your new standard in Marketing, Pay & Sales. It's Bird

The right message -> to the right person -> di right time.

By clicking "See Bird" you agree to Bird's Pemberitahuan Privasi.