Ujian Mutasi dengan PITest

1. Gambaran keseluruhan

Pengujian perisian merujuk kepada teknik yang digunakan untuk menilai fungsi aplikasi perisian. Dalam artikel ini, kita akan membincangkan beberapa metrik yang digunakan dalam industri pengujian perisian, seperti liputan kod dan pengujian mutasi , dengan minat khusus tentang bagaimana melakukan ujian mutasi menggunakan perpustakaan PITest .

Demi kesederhanaan, kami akan mendasarkan demonstrasi ini pada fungsi palindrome asas - Perhatikan bahawa palindrome adalah rentetan yang membaca sama ke belakang dan ke depan.

2. Pergantungan Maven

Seperti yang anda lihat dalam konfigurasi dependensi Maven, kami akan menggunakan JUnit untuk menjalankan ujian kami dan perpustakaan PITest untuk memperkenalkan mutan ke dalam kod kami - jangan risau, kami akan melihat dalam sekejap apa itu mutan. Anda sentiasa dapat mencari versi ketergantungan terkini ke repositori pusat maven dengan mengikuti pautan ini.

 org.pitest pitest-parent 1.1.10 pom  

Untuk menghidupkan dan menjalankan perpustakaan PITest, kami juga perlu memasukkan plugin pitest-maven dalam fail konfigurasi pom.xml kami :

 org.pitest pitest-maven 1.1.10   com.baeldung.testing.mutation.*   com.baeldung.mutation.test.*    

3. Penyediaan Projek

Sekarang setelah konfigurasi Maven dikonfigurasi, mari kita lihat fungsi palindrome yang jelas ini:

public boolean isPalindrome(String inputString) { if (inputString.length() == 0) { return true; } else { char firstChar = inputString.charAt(0); char lastChar = inputString.charAt(inputString.length() - 1); String mid = inputString.substring(1, inputString.length() - 1); return (firstChar == lastChar) && isPalindrome(mid); } } 

Yang kami perlukan sekarang adalah ujian JUnit yang mudah untuk memastikan bahawa pelaksanaan kami berjalan dengan cara yang diinginkan:

@Test public void whenPalindrom_thenAccept() { Palindrome palindromeTester = new Palindrome(); assertTrue(palindromeTester.isPalindrome("noon")); } 

Sejauh ini, kami bersedia menjalankan kes ujian kami dengan jayanya sebagai ujian JUnit.

Selanjutnya, dalam artikel ini, kita akan memfokuskan pada liputan kod dan mutasi menggunakan pustaka PITest.

4. Perlindungan Kod

Liputan kod telah digunakan secara meluas dalam industri perisian, untuk mengukur berapa persen jalan pelaksanaan yang telah dilakukan selama ujian otomatis.

Kami dapat mengukur liputan kod yang berkesan berdasarkan jalan pelaksanaan menggunakan alat seperti Eclemma yang terdapat di Eclipse IDE.

Setelah menjalankan TestPalindrome dengan liputan kod, kita dapat dengan mudah mencapai skor liputan 100% - Perhatikan bahawa isPalindrome bersifat rekursif, jadi cukup jelas bahawa pemeriksaan panjang input kosong akan dilindungi pula.

Malangnya, metrik liputan kod kadang-kadang agak tidak berkesan , kerana skor liputan kod 100% hanya bermaksud bahawa semua garis dilaksanakan sekurang-kurangnya sekali, tetapi ia tidak mengatakan apa-apa mengenai ketepatan ujian atau kes kes penggunaan , dan itulah sebabnya ujian mutasi sebenarnya penting.

5. Liputan Mutasi

Ujian mutasi adalah teknik pengujian yang digunakan untuk meningkatkan kecukupan ujian dan mengenal pasti kecacatan dalam kod. Ideanya adalah untuk mengubah kod pengeluaran secara dinamik dan menyebabkan ujian gagal.

Ujian yang baik akan gagal

Setiap perubahan dalam kode disebut mutan , dan menghasilkan versi program yang diubah, yang disebut mutasi .

Kami mengatakan bahawa mutasi terbunuh jika boleh menyebabkan kegagalan dalam ujian. Kami juga mengatakan bahawa mutasi dapat bertahan jika mutan tidak dapat mempengaruhi tingkah laku ujian.

Sekarang mari kita jalankan ujian menggunakan Maven, dengan pilihan matlamat ditetapkan ke: org.pitest: pitest-maven: mutationCoverage .

Kami dapat memeriksa laporan dalam format HTML dalam direktori target / pit-test / YYYYMMDDHHMI :

  • Liputan talian 100%: 7/7
  • Liputan mutasi 63%: 5/8

Jelas, ujian kami menyapu semua jalan pelaksanaan, dengan itu, skor liputan garis adalah 100%. Sebaliknya, perpustakaan PITest memperkenalkan 8 mutan , 5 daripadanya terbunuh - Disebabkan gagal - tetapi 3 berjaya.

Kami boleh menyemak laporan com.baeldung.testing.mutation / Palindrome.java.html untuk maklumat lebih lanjut mengenai mutan yang dibuat:



Ini adalah mutator yang aktif secara lalai ketika menjalankan ujian liputan mutasi:

  • INCREMENTS_MUTATOR
  • VOID_METHOD_CALL_MUTATOR
  • RETURN_VALS_MUTATOR
  • MATH_MUTATOR
  • NEGATE_CONDITIONALS_MUTATOR
  • INVERT_NEGS_MUTATOR
  • SYARAT_BOUNDARY_MUTATOR

Untuk maklumat lebih lanjut mengenai mutator PITest, anda boleh menyemak pautan halaman dokumentasi rasmi .

Skor liputan mutasi kami mencerminkan kekurangan kes ujian , kerana kami tidak dapat memastikan bahawa fungsi palindrom kami menolak input rentetan non-palindromik dan dekat-palindromik.

6. Meningkatkan Skor Mutasi

Sekarang kita tahu apa itu mutasi, kita perlu meningkatkan skor mutasi kita dengan membunuh mutan yang masih hidup .

Mari kita ambil mutasi pertama - bersyarat yang ditolak - pada baris 6 sebagai contoh. Mutan bertahan kerana walaupun kita mengubah coretan kod:

if (inputString.length() == 0) { return true; }

Kepada:

if (inputString.length() != 0) { return true; }

Ujian akan lulus, dan itulah sebabnya mutasi itu bertahan . Ideanya adalah untuk melaksanakan ujian baru yang akan gagal, sekiranya mutan diperkenalkan . Perkara yang sama boleh dilakukan untuk mutan yang tinggal.

@Test public void whenNotPalindrom_thanReject() { Palindrome palindromeTester = new Palindrome(); assertFalse(palindromeTester.isPalindrome("box")); } @Test public void whenNearPalindrom_thanReject() { Palindrome palindromeTester = new Palindrome(); assertFalse(palindromeTester.isPalindrome("neon")); }

Sekarang kita dapat menjalankan ujian menggunakan plugin liputan mutasi, untuk memastikan bahawa semua mutasi terbunuh , seperti yang dapat kita lihat dalam laporan PITest yang dihasilkan di direktori sasaran.

  • Liputan talian 100%: 7/7
  • Liputan mutasi 100%: 8/8

7. Konfigurasi Ujian PITest

Mutation testing may be resources-extensive sometimes, so we need to put proper configuration in place to improve tests effectiveness. We can make use of the targetClasses tag, to define the list of classes to be mutated. Mutation testing cannot be applied to all classes in a real world project, as it will be time-consuming, and resource critical.

It is also important to define the mutators you plan to use during mutation testing, in order to minimize the computing resources needed to perform the tests:

  com.baeldung.testing.mutation.*   com.baeldung.mutation.test.*   CONSTRUCTOR_CALLS VOID_METHOD_CALLS RETURN_VALS NON_VOID_METHOD_CALLS  

Moreover, the PITest library offers a variety of options available to customize your testing strategies, you can specify the maximum number of mutants introduced by class using the maxMutationsPerClass option for example. More details about PITest options in the official Maven quickstart guide.

8. Conclusion

Note that code coverage is still an important metric, but sometimes it is not sufficient enough to guarantee a well-tested code. So in this article we've walked through mutation testing as a more sophisticated way to ensure tests quality and endorse test cases, using the PITest library.

Kami juga telah melihat bagaimana menganalisis laporan PITest asas sambil meningkatkan skor liputan mutasi .

Walaupun pengujian mutasi menunjukkan kecacatan dalam kod, ia harus digunakan dengan bijak, kerana ini adalah proses yang sangat mahal dan memakan waktu .

Anda boleh melihat contoh yang diberikan dalam artikel ini dalam projek GitHub yang dipautkan .