CodeGym /Blog Java /rawak /Ujian Unit di Jawa dengan JUnit
John Squirrels
Tahap
San Francisco

Ujian Unit di Jawa dengan JUnit

Diterbitkan dalam kumpulan

Apakah ujian unit di Jawa?

Sebelum kita mempelajari JUnit dalam Java, mari kita tinjau secara ringkas apakah ujian unit dan mengapa ia begitu popular (jika anda sudah mengetahui perkara ini, langkau ke 'Bagaimana cara saya menulis Ujian JUnit di Java?'). Ujian unit dalam Java menjadikan pembangunan perisian berskala besar lebih cekap dan mudah. Ia boleh membantu kedua-dua individu dan pasukan mengurangkan waktu penyahpepijatan yang tidak terkira banyaknya dan menyelaraskan proses kerjasama dengan sangat baik. Ujian Unit dalam Java dengan JUnit - 1

https://junit.org/junit4/

Idea penting bagi ujian unit ialah: tulis ujian atom bagi ciri individu (dipanggil ujian unit) dan tambahkan lebih banyak ciri secara perlahan selepas menguji dan memastikan yang sebelumnya berfungsi. Ia adalah idea yang sangat mudah tetapi berkesan. Sebagai contoh bagaimana proses ini mungkin kelihatan, bayangkan anda sedang membina kalkulator saintifik maya. Di samping pengendali aritmetik ketara ( +, -, x, %), kalkulator ini akan mempunyai ciri lanjutan yang memerlukan subciri lain untuk berfungsi di dalamnya. Untuk mengira eksponen, kalkulator anda perlu boleh mendarab dengan betul. Jadi pendekatan ujian unit untuk membina dan menguji kalkulator ini ialah:
  • Tulis fungsi tambah. Uji dengan teliti, tukar, ulangi sehingga ia berfungsi.
  • Lakukan perkara yang sama untuk fungsi tolak, darab, bahagi.
  • Gunakan operator asas ini untuk menulis fungsi operator yang lebih maju seperti eksponen, kemudian uji fungsi tersebut juga.
Ini memastikan bahawa ciri yang membina subciri lain yang lebih kecil bukan sahaja berfungsi dengan betul dalam hak mereka sendiri tetapi tidak mempunyai subciri yang rosak di dalamnya. Sebagai contoh, jika saya sedang menguji fungsi eksponen dan ada sesuatu yang tidak kena, saya tahu bahawa pepijat mungkin tiada dalam subciri pendaraban, kerana fungsi pendaraban telah diuji secara meluas. Ini sangat menghapuskan jumlah kod yang saya perlukan untuk menjejak balik dan memeriksa untuk mencari pepijat. Mudah-mudahan, contoh remeh ini menjelaskan cara proses pemikiran di sekitar Pengujian Unit distrukturkan. Tetapi bagaimanakah ujian unit berinteraksi dengan seluruh proses pembangunan perisian? Bagaimana jika anda mempunyai ciri yang lebih kompleks, yang perlu boleh bekerja dan berkomunikasi bersama? Ujian unit tidak mencukupi untuk memastikan ciri kompleks tersebut boleh berfungsi dengan baik bersama-sama. Sebenarnya, ia hanyalah langkah pertama dari Empat Tahap Pengujian Perisian (saya menggunakan huruf besar kerana saya merujuk kepada piawaian industri atau pendekatan yang paling biasa untuk menguji perisian). Tiga langkah terakhir ialahUjian Integrasi , Ujian Sistem dan Ujian Penerimaan. Ini semua mungkin bermakna apa yang anda fikir mereka lakukan, tetapi izinkan saya menjelaskan: Ujian integrasi ialah perkara yang akan kami lakukan untuk memastikan ciri-ciri seperti yang dinyatakan di atas, "ciri kompleks," berinteraksi dengan betul antara satu sama lain. (cth, memastikan kalkulator boleh mengendalikan "3 + 7 * 4 - 2") Ujian sistem sedang menguji reka bentuk keseluruhan sistem tertentu; selalunya terdapat beberapa sistem ciri kompleks yang berfungsi bersama dalam produk, jadi anda mengumpulkannya ke dalam sistem dan mengujinya secara individu. (cth jika anda sedang membina kalkulator grafik, anda mula-mula membina 'sistem' aritmetik untuk menangani nombor, menguji sehingga ia berfungsi seperti yang dimaksudkan, dan kemudian anda akan membina dan menguji 'sistem' grafik untuk menangani pengeluaran, seperti ia akan dibina daripada sistem aritmetik). Ujian penerimaan ialah ujian peringkat pengguna; ia melihat sama ada semua sistem boleh berfungsi secara serentak untuk mencipta produk siap sedia untuk diterima oleh pengguna (cth, pengguna menguji kalkulator). Pembangun perisian kadangkala boleh mengabaikan langkah terakhir proses ini, kerana syarikat selalunya meminta pekerja lain menggunakan ujian pengguna (beta) secara berasingan.

Bagaimanakah saya menulis ujian JUnit di Jawa?

Kini setelah anda mempunyai idea yang lebih jelas tentang faedah dan had ujian unit, mari lihat beberapa kod! Kami akan menggunakan rangka kerja ujian Java popular yang dipanggil JUnit (satu lagi yang popular ialah TestNG, yang anda juga boleh gunakan jika anda suka. Mereka sangat serupa, secara sintaksis; TestNG diinspirasikan oleh JUnit). Anda boleh memuat turun dan memasang JUnit di sini . Untuk kod contoh ini, kita akan meneruskan contoh 'kalkulator saintifik' yang saya nyatakan sebelum ini; ia agak mudah untuk membungkus kepala anda, dan kod ujian adalah sangat mudah. Amalan konvensional ialah menulis kelas ujian berasingan untuk setiap kelas anda, jadi itulah yang akan kami lakukan. Mari kita anggap bahawa pada ketika ini, kita mempunyai Math.javafail dengan semua fungsi matematik di dalamnya (termasuk Math.add), dan kita sedang menulisMathTests.javafail dalam pakej yang sama. Sekarang mari kita sediakan penyata import dan badan kelas: (SOALAN TEMUDUGA JUnit MUNGKIN: Anda mungkin ditanya di mana hendak meletakkan ujian JUnit anda dan sama ada anda perlu mengimport fail sumber anda atau tidak. Jika anda menulis kelas ujian anda dalam pakej yang sama seperti kelas utama anda, maka anda tidak memerlukan sebarang pernyataan import untuk fail sumber anda dalam kelas ujian. Jika tidak, pastikan anda mengimport fail sumber anda!)

import org.junit.jupiter.Test;    //gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; //less typing :) 

public class MathTests {
	//...
}
Pernyataan import pertama memberi kita @Testpengepala. Kami menulis ' @Test' terus di atas setiap definisi fungsi ujian, supaya JUnit tahu bahawa ini adalah ujian unit tunggal yang boleh dijalankan secara berasingan. Kemudian, saya akan menunjukkan kepada anda bagaimana anda boleh menjalankan ujian unit tertentu menggunakan pengepala ini. Pernyataan import kedua menjimatkan kami sedikit menaip. Fungsi JUnit utama yang kami gunakan untuk menguji fungsi kami ialah Assert.assertEquals(), yang mengambil dua parameter (nilai sebenar dan nilai dijangka) dan memastikan ia adalah sama. Mempunyai penyataan import kedua ini membolehkan kami hanya menaip ' assertEquals(...' dan bukannya perlu menentukan setiap kali pakej mana ia merupakan sebahagian daripadanya. Sekarang mari kita tulis kes ujian yang sangat mudah untuk mengesahkan bahawa 2 + 2 sememangnya 4!

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test
	public void add_twoPlusTwo_returnsFour(){
	final int expected = 4;
	final int actual = Math.add(2, 2);
	assertEquals(“2+2 is 4”, actual, expected);
	}
}
Mari kita semak setiap lima baris fungsi ujian dan perkara yang mereka lakukan: Baris 5: @TestPengepala ini menentukan bahawa definisi fungsi di bawah add_twoPlusTwo_returnsFour()sememangnya fungsi ujian yang JUnit boleh jalankan secara berasingan. Baris 6: Ini ialah tandatangan fungsi untuk kes ujian kami. Kes ujian sentiasa sangat tunggal; mereka hanya menguji satu contoh khusus, seperti 2+2=4. Adalah konvensyen untuk menamakan kes ujian anda dalam bentuk “ [function]_[params]_returns[expected](),” di mana [function]ialah nama fungsi yang anda uji, [params]adalah contoh parameter khusus yang anda uji dan [expected]merupakan nilai pulangan yang dijangkakan bagi fungsi tersebut. Fungsi ujian hampir selalu mempunyai jenis pulangan ' void' kerana titik utama keseluruhan fungsi adalah untuk dijalankanassertEquals, yang akan mengeluarkan ke konsol sama ada ujian anda lulus atau tidak; anda tidak memerlukan sebarang data lain untuk dikembalikan ke mana-mana sahaja. Baris 7: Kami mengisytiharkan finalpembolehubah '' jenis pulangan Math.add (int), dan menamakannya sebagai 'dijangka' mengikut konvensyen. Nilainya adalah jawapan yang kita jangkakan (4). Baris 8: Kami mengisytiharkan finalpembolehubah '' jenis pulangan Math.add (int), dan namakannya 'sebenar' mengikut konvensyen. Nilainya adalah hasil daripada Math.add(2, 2). Baris 9: Garis emas. Ini adalah garis yang membandingkan sebenar dan dijangka dan memberitahu kami bahawa kami lulus ujian hanya jika mereka sama. Parameter pertama yang diluluskan "2+2 ialah 4" ialah perihalan fungsi ujian.

Bagaimana jika fungsi saya perlu membuang pengecualian?

Jika contoh ujian khusus anda harus membuang pengecualian dan bukannya menegaskan bahawa nilai sebenar dan jangkaan adalah sama, maka JUnit mempunyai cara untuk menjelaskan perkara ini dalam pengepala @Test. Mari kita lihat contoh di bawah. Dengan mengandaikan kita mempunyai fungsi Math.javadipanggil Math.divide, kita ingin memastikan bahawa input tidak boleh dibahagikan dengan 0. Sebaliknya, cuba memanggil Math.divide(a, 0)mana-mana nilai 'a' harus membuang pengecualian ( ArithmeticException.class). Kami menentukan demikian dalam pengepala seperti itu:

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test (expectedExceptions = ArithmeticException.class)
	public void divide_byZero_throwsException() throws ArithmeticException{
	Math.divide(1, 0);
	}
}
Anda boleh mempunyai lebih daripada satu pengecualian untuk expectedExceptions, cuma pastikan anda menggunakan kurungan dan koma untuk menyenaraikan kelas pengecualian anda, seperti itu:

expectedException = {FirstException.class, SecondException.class, … }

Bagaimanakah saya menjalankan ujian JUnit saya di Jawa?

Cara menambah JUnit pada IntelliJ: https://stackoverflow.com/questions/19330832/setting-up-junit-with-intellij-idea Anda boleh menjalankan projek anda seperti biasa anda menjalankan ujian. Menjalankan semua ujian dalam kelas ujian akan menjalankannya dalam susunan abjad. Dalam JUnit 5, anda boleh menambah keutamaan kepada ujian dengan menambahkan @Orderteg. Satu contoh:

@TestMethodOrder(OrderAnnotation.class)
public class Tests {
…
@Test
@Order(2)
public void a_test() { … }

@Test
@Order (1)
public void b_test() { … }
…
}
Walaupun a_test()datang sebelum b_test()mengikut abjad dan dalam kod, b_test()akan dijalankan sebelum a_test()di sini, kerana 1 datang sebelum 2 dalam Tertib. Jadi itu sahaja untuk asas-asas JUnit. Sekarang, mari kita selesaikan beberapa Soalan Temuduga JUnit biasa, dan ketahui lebih lanjut tentang JUnit sepanjang perjalanan!

Soalan Temuduga JUnit (Maklumat Tambahan)

Di sini saya telah mengumpulkan soalan temuduga JUnit yang paling popular. Jika anda mempunyai sesuatu untuk ditambahkan — jangan ragu untuk melakukan ini dalam ulasan di bawah. S: Apakah kaedah yang boleh anda panggil dalam kaedah ujian anda untuk gagal secara automatik dalam ujian? A: fail(“huraian ralat di sini!”); S: Anda sedang menguji kelas Anjing; untuk menguji objek Anjing, anda perlu membuat seketika sebelum anda boleh menjalankan ujian ke atasnya. Jadi anda menulis fungsi setUp() untuk membuat instantiate Anjing. Anda hanya mahu menjalankan fungsi ini sekali sahaja semasa semua ujian. Apakah yang mesti anda letakkan terus di atas tandatangan fungsi setUp() supaya JUnit tahu untuk menjalankan setUp() sebelum menjalankan ujian? A: @BeforeClass (@BeforeAll dalam JUnit 5) S:Apakah tandatangan fungsi bagi fungsi setUp() yang diterangkan di atas? A: kekosongan statik awam. Sebarang fungsi dengan @BeforeClass (@BeforeAll dalam JUnit 5) atau @AfterClass (@AfterAll dalam JUnit 5) perlu statik. S: Anda telah selesai menguji kelas Anjing. Anda menulis fungsi void tearDown() yang membersihkan data dan mencetak maklumat untuk konsol selepas setiap ujian. Anda mahu fungsi ini dijalankan selepas setiap ujian tunggal. Apakah yang mesti anda letakkan terus di atas tandatangan fungsi tearDown() supaya JUnit tahu untuk menjalankan tearDown() selepas menjalankan setiap ujian? A: @After (@AfterEach pada JUnit 5)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION