Bagaimana cara menulis Tes Unit?

136

Saya memiliki kelas Java. Bagaimana saya bisa mengujinya ?


Dalam kasus saya, saya memiliki kelas melakukan penjumlahan biner. Dibutuhkan dua byte[]larik, menjumlahkannya, dan mengembalikan larik biner baru.

Tsundoku
sumber
7
Anda dapat menggunakan alat seperti jUnit dan menulis kasus uji (metode pengujian) untuk kelas java Anda. Kemudian aktifkan pengujian jUnit sebagai bagian dari proses build (ant / maven). Menggunakan jUnit sama sekali tidak sulit, bagian yang sulit adalah membuat skenario pengujian sebanyak yang dapat Anda pikirkan sehingga Anda dapat mendeteksi bug lebih awal dan sering.
CoolBeans

Jawaban:

133
  1. Tentukan keluaran yang diharapkan dan diinginkan untuk kasus normal, dengan masukan yang benar.

  2. Sekarang, implementasikan pengujian dengan mendeklarasikan sebuah kelas, beri nama apa saja (Biasanya seperti TestAddingModule), dan tambahkan metode testAdd ke dalamnya (misalnya seperti di bawah):

    • Tulis metode, dan di atasnya tambahkan anotasi @Test.
    • Dalam metode ini, jalankan jumlah biner Anda dan assertEquals(expectedVal,calculatedVal).
    • Uji metode Anda dengan menjalankannya (di Eclipse, klik kanan, pilih Run as → JUnit test).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
      
  3. Tambahkan casing lain sesuai keinginan.

    • Uji apakah jumlah biner Anda tidak memunculkan pengecualian yang tidak terduga jika ada bilangan bulat yang melimpah.
    • Uji apakah metode Anda menangani masukan Null dengan baik (contoh di bawah).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1() 
      {
          int y = 1;
          assertEquals(0, myClass.add(null,y));
      }
      
jayunit100
sumber
1. apakah notasi @Test diperlukan? 2. mengapa tidak menguji input null dengan assertNotNull? 3. Di mana hasil tes unit ditangkap? bagaimana hasil ditunjukkan kepada pengguna?
pengguna137717
10
Ya, @Testdiperlukan notasi. Ini dilakukan untuk memberi sinyal kepada runner pengujian unit bahwa metode ini mewakili pengujian unit dan harus dijalankan. Metode yang tidak dianotasi @Testtidak akan dijalankan oleh runner pengujian.
Ali Shah Ahmed
untuk pengujian kedua - bukankah harus menambahkan a nullke yhanya memberi Anda y?
Adjit
Terima kasih! Saya ingin tahu mengapa tidak perlu menambahkan staticpengubah metode pengujian.
Liang Zhang
111

Saya menyediakan posting ini untuk IntelliJ dan Eclipse .

Gerhana:

Untuk membuat tes unit untuk proyek Anda, silakan ikuti langkah-langkah berikut (Saya menggunakan Eclipse untuk menulis tes ini):

1- Klik New -> Java Project.

Buat Proyek

2- Tuliskan nama proyek Anda dan klik selesai.

Buat Proyek

3- Klik kanan pada proyek Anda. Kemudian, klik New -> Class.

Buat Kelas

4- Tuliskan nama kelas Anda dan klik selesai.

Buat Kelas

Kemudian, selesaikan kelas seperti ini:

public class Math {
    int a, b;
    Math(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int add() {
        return a + b;
    }
}

5- Klik File -> New -> JUnit Test Case.

Buat Tes JUnite

6- Periksa setUp () dan klik selesai. SetUp () akan menjadi tempat Anda menginisialisasi pengujian Anda.

Periksa Pengaturan ()

7- Klik OK.

Tambahkan JUnit

8- Di sini, saya hanya menambahkan 7 dan 10. Jadi, saya berharap jawabannya adalah 17. Selesaikan kelas tes Anda seperti ini:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
    Math math;
    @Before
    public void setUp() throws Exception {
        math = new Math(7, 10);
    }
    @Test
    public void testAdd() {
        Assert.assertEquals(17, math.add());
    }
}

9- Tulis klik pada kelas pengujian Anda di penjelajah paket dan klik Run as -> JUnit Test.

Jalankan Uji JUnit

10- Ini adalah hasil tes.

Hasil Tes

IntelliJ: Perhatikan bahwa saya menggunakan komunitas IntelliJ IDEA 2020.1 untuk tangkapan layar. Juga, Anda perlu menyiapkan jre Anda sebelum langkah-langkah ini. Saya menggunakan JDK 11.0.4.

1- Klik kanan pada folder utama proyek Anda-> baru -> direktori. Anda harus menyebutnya 'tes'. masukkan deskripsi gambar di sini 2- Klik kanan pada folder tes dan buat paket yang sesuai. Saya sarankan membuat nama kemasan yang sama dengan kelas aslinya. Kemudian, Anda klik kanan pada direktori pengujian -> tandai direktori sebagai -> root sumber pengujian. masukkan deskripsi gambar di sini 3- Dalam paket yang tepat di direktori pengujian, Anda perlu membuat kelas Java (saya sarankan untuk menggunakan Test.java). masukkan deskripsi gambar di sini 4- Di kelas yang dibuat, ketik '@Test'. Kemudian, di antara opsi yang diberikan IntelliJ kepada Anda, pilih Tambahkan 'JUnitx' ke classpath. 5- Tulis metode tes Anda di kelas tes Anda. Tanda tangan metode seperti:masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

@Test
public void test<name of original method>(){
...
}

Anda dapat melakukan pernyataan Anda seperti di bawah ini:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

Ini adalah impor yang saya tambahkan:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

masukkan deskripsi gambar di sini

Ini tes yang saya tulis: masukkan deskripsi gambar di sini

Anda dapat memeriksa metode Anda seperti di bawah ini:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

Untuk menjalankan pengujian unit Anda, klik kanan pada pengujian dan klik Run. masukkan deskripsi gambar di sini

Jika tes Anda lolos, hasilnya akan seperti di bawah ini: masukkan deskripsi gambar di sini

Saya harap ini membantu. Anda dapat melihat struktur proyek di GitHub https://github.com/m-vahidalizadeh/problem_solving_project .

Mohammad
sumber
13
Suka jawaban Anda, itu adalah "cara" terbaik!
alisa
4
Saya senang jawaban saya membantu. Terima kasih atas komentarmu.
Mohammad
2
Seperti inilah tampilan tutorial; bersih, ringkas, contoh lengkap. Baik sekali.
Jack Of Blades
1
Terima kasih banyak Jack. Saya senang Anda merasa terbantu.
Mohammad
18

Ini adalah pertanyaan yang sangat umum dan ada banyak cara untuk menjawabnya.

Jika ingin menggunakan JUnit untuk membuat pengujian, Anda perlu membuat kelas testcase, kemudian membuat metode pengujian individual yang menguji fungsionalitas tertentu dari kelas / modul yang sedang diuji (kelas testcase tunggal biasanya dikaitkan dengan kelas "produksi" tunggal yang sedang diuji) dan di dalam metode ini menjalankan berbagai operasi dan membandingkan hasilnya dengan apa yang benar. Sangat penting untuk mencoba dan menutupi sebanyak mungkin kasus sudut.

Dalam contoh spesifik Anda, Anda bisa misalnya menguji yang berikut ini:

  1. Penjumlahan sederhana antara dua bilangan positif. Tambahkan mereka, lalu verifikasi hasilnya adalah apa yang Anda harapkan.
  2. Penambahan antara bilangan positif dan negatif (yang mengembalikan hasil dengan tanda argumen pertama).
  3. Penambahan antara bilangan positif dan negatif (yang mengembalikan hasil dengan tanda argumen kedua).
  4. Penjumlahan di antara dua bilangan negatif.
  5. Penambahan yang menghasilkan luapan.

Untuk memverifikasi hasil, Anda dapat menggunakan berbagai metode assertXXX dari kelas org.junit.Assert (untuk kenyamanan, Anda dapat melakukan 'import static org.junit.Assert. *'). Metode ini menguji kondisi tertentu dan gagal dalam pengujian jika tidak divalidasi (dengan pesan tertentu, opsional).

Contoh kelas kasus uji dalam kasus Anda (tanpa konten metode yang ditentukan):

import static org.junit.Assert.*;

public class AdditionTests {
    @Test
    public void testSimpleAddition() { ... }


    @Test
    public void testPositiveNegativeAddition() { ... }


    @Test
    public void testNegativePositiveAddition() { ... }


    @Test
    public void testNegativeAddition() { ... }


    @Test
    public void testOverflow() { ... }
}

Jika Anda tidak terbiasa menulis pengujian unit tetapi menguji kode Anda dengan menulis pengujian ad-hoc yang kemudian Anda validasi "secara visual" (misalnya, Anda menulis metode utama sederhana yang menerima argumen yang dimasukkan menggunakan keyboard dan kemudian mencetak hasilnya - dan kemudian Anda terus memasukkan nilai dan memvalidasi diri Anda sendiri jika hasilnya benar), maka Anda dapat mulai dengan menulis pengujian seperti itu dalam format di atas dan memvalidasi hasil dengan metode assertXXX yang benar daripada melakukannya secara manual. Dengan cara ini, Anda dapat menjalankan kembali pengujian dengan lebih mudah dibandingkan jika Anda harus melakukan pengujian manual.

Seramme
sumber
8

Seperti yang @CoolBeans sebutkan, lihat jUnit . Berikut adalah tutorial singkat untuk membantu Anda memulai juga dengan jUnit 4.x

Terakhir, jika Anda benar-benar ingin mempelajari lebih lanjut tentang pengujian dan pengembangan yang digerakkan oleh pengujian (TDD), saya sarankan Anda untuk membaca buku karya Kent Beck: Test-Driven Development By Example .

vladmore
sumber
6

Jawaban lain telah menunjukkan kepada Anda bagaimana menggunakan JUnit untuk menyiapkan kelas pengujian. JUnit bukan satu-satunya framework pengujian Java. Berkonsentrasi pada detail teknis menggunakan kerangka kerja namun mengurangi konsep terpenting yang seharusnya memandu tindakan Anda, jadi saya akan membicarakannya.

  • Pengujian (dari semua jenis dari semua jenis hal) membandingkan perilaku sebenarnya dari sesuatu (Sistem Sedang Diuji, SUT) dengan perilaku yang diharapkan .

  • Pengujian otomatis dapat dilakukan dengan menggunakan program komputer. Karena perbandingan itu dilakukan oleh program komputer yang tidak fleksibel dan tidak cerdas, perilaku yang diharapkan harus diketahui dengan tepat dan tidak ambigu.

  • Apa program atau bagian dari program (kelas atau metode) diharapkan lakukan adalah spesifikasinya . Oleh karena itu, pengujian perangkat lunak mengharuskan Anda memiliki spesifikasi untuk SUT. Ini mungkin deskripsi eksplisit, atau spesifikasi implisit di kepala Anda tentang apa yang diharapkan.

  • Oleh karena itu, pengujian unit otomatis memerlukan spesifikasi kelas atau metode yang tepat dan tidak ambigu yang Anda uji.

  • Tetapi Anda membutuhkan spesifikasi itu ketika Anda mulai menulis kode itu. Jadi bagian dari pengujian sebenarnya dimulai sebelum Anda menulis bahkan satu baris SUT. Teknik pengujian Test Driven Development (TDD) mengambil ide itu secara ekstrim, dan meminta Anda membuat kode pengujian unit sebelum Anda menulis kode yang akan diuji.

  • Kerangka kerja pengujian unit menguji SUT Anda menggunakan pernyataan . Penegasan adalah ekspresi logis (ekspresi dengan booleantipe hasil; predikat ) yang harus ada truejika SUT berperilaku dengan benar. Oleh karena itu, spesifikasi harus dinyatakan (atau diungkapkan kembali) sebagai pernyataan.

  • Teknik yang berguna untuk menyatakan spesifikasi sebagai asersi adalah pemrograman berdasarkan kontrak . Spesifikasi ini terkait dengan kondisi pasca . Postcondition adalah pernyataan tentang status SUT yang terlihat secara publik setelah kembali dari metode atau konstruktor. Beberapa metode memiliki kondisi pos yang invarian , yang merupakan predikat yang benar sebelum dan sesudah eksekusi metode. Sebuah kelas juga dapat dikatakan memiliki invarian, yang merupakan kondisi pos dari setiap konstruktor dan metode kelas, dan karenanya harus selalu benar. Kondisi pascakondisi (Dan invarian) hanya diekspresikan dalam keadaan publisitas terlihat: publicdan protectedbidang, nilai yang dikembalikan olehpublicdan protectedmetode (seperti getter), dan status objek yang terlihat secara publik diteruskan (dengan referensi) ke metode.


Banyak pemula memposting pertanyaan di sini menanyakan bagaimana mereka dapat menguji beberapa kode, menyajikan kode tetapi tanpa menyebutkan spesifikasi untuk kode itu. Seperti yang diperlihatkan oleh diskusi ini, tidak mungkin bagi siapa pun untuk memberikan jawaban yang baik untuk pertanyaan semacam itu, karena paling-paling calon penjawab harus menebak spesifikasinya, dan mungkin melakukannya dengan tidak benar. The Penanya pertanyaan jelas tidak memahami pentingnya spesifikasi, dan dengan demikian merupakan pemula yang perlu memahami dasar-dasar yang telah saya jelaskan di sini sebelum mencoba untuk menulis beberapa kode uji.

Raedwald
sumber