Mengapa menggunakan JUnit untuk pengujian?

131

Mungkin pertanyaan saya adalah pemula, tetapi saya tidak dapat benar-benar memahami keadaan yang akan saya gunakan ?

Apakah saya menulis aplikasi sederhana atau yang lebih besar saya mengujinya dengan System.outpernyataan dan sepertinya cukup mudah bagi saya.

Mengapa membuat kelas uji dengan JUnit, folder yang tidak perlu dalam proyek jika kita masih harus memanggil metode yang sama, memeriksa apa yang mereka kembalikan dan kita kemudian memiliki biaya tambahan untuk membubuhi keterangan segalanya?

Mengapa tidak menulis kelas dan mengujinya sekaligus dengan System.outtetapi tidak membuat kelas Tes?

PS. Saya belum pernah mengerjakan proyek besar yang baru saya pelajari.

Jadi apa tujuannya?

Artem Moskalev
sumber
1
Baca The Art of Unit Testing
rgeorge
7
Anda sadar bahwa setiap kali Anda mengubah apa pun dalam program Anda, semua pekerjaan Anda sebelumnya memeriksa output secara manual tidak valid dan Anda harus mengulanginya dari awal?
Thorbjørn Ravn Andersen
Bukan hanya "pengujian", tetapi juga "pengujian pintar" sangat penting. Ini adalah contoh yang bagus: wp.me/prMeE-11
akcasoy

Jawaban:

139

Itu bukan pengujian, itu "melihat secara manual pada output" (dikenal dalam biz sebagai LMAO). Lebih formal itu dikenal sebagai "mencari secara manual untuk output abnormal" (LMFAO). (Lihat catatan di bawah)

Setiap kali Anda mengubah kode, Anda harus menjalankan aplikasi dan LMFAO untuk semua kode yang terpengaruh oleh perubahan itu. Bahkan dalam proyek kecil, ini bermasalah dan rawan kesalahan.

Sekarang skala hingga 50k, 250k, 1m LOC atau lebih, dan LMFAO setiap kali Anda melakukan perubahan kode. Tidak hanya itu tidak menyenangkan, itu tidak mungkin: Anda telah meningkatkan kombinasi input, output, flag, kondisi, dan sulit untuk menggunakan semua cabang yang mungkin.

Lebih buruk lagi, LMFAO mungkin berarti mengunjungi halaman demi halaman aplikasi web, menjalankan laporan, meneliti jutaan baris log di lusinan file dan mesin, membaca email yang dihasilkan dan dikirim, memeriksa pesan teks, memeriksa jalur robot, mengisi sebotol soda, mengumpulkan data dari seratus layanan web, memeriksa jejak audit transaksi keuangan ... Anda mendapatkan idenya. "Output" tidak berarti beberapa baris teks, "output" berarti perilaku sistem agregat.

Terakhir, unit dan tes perilaku menentukan perilaku sistem. Tes dapat dijalankan oleh server integrasi berkelanjutan dan diperiksa kebenarannya. Tentu, begitu juga System.out, tetapi server CI tidak akan tahu jika salah satu dari mereka salah – dan jika itu benar, mereka adalah unit test, dan Anda mungkin juga menggunakan framework.

Tidak peduli seberapa bagus kita berpikir kita, manusia bukanlah kerangka kerja unit test yang baik atau server CI.


Catatan: LMAO sedang menguji, tetapi dalam arti yang sangat terbatas. Itu tidak dapat diulang dengan cara yang berarti di seluruh proyek atau sebagai bagian dari proses. Ini mirip dengan mengembangkan secara bertahap dalam REPL, tetapi tidak pernah memformalkan tes inkremental itu.

Dave Newton
sumber
3
-1 untuk kalimat pertama, yang sepenuhnya dan sama sekali tidak benar.
Michael Borgwardt
50

Kami menulis tes untuk memverifikasi kebenaran perilaku program.

Memverifikasi kebenaran perilaku program dengan memeriksa konten pernyataan keluaran menggunakan mata Anda adalah manual , atau lebih khusus, proses visual .

Anda bisa membantahnya

inspeksi visual bekerja , saya memeriksa bahwa kode melakukan apa yang seharusnya dilakukan, untuk skenario ini dan begitu saya bisa melihat itu benar kita baik untuk pergi.

Sekarang pertama-tama, itu bagus untuk Anda tertarik pada apakah atau tidak kode berfungsi dengan benar. Itu hal yang baik. Anda di depan kurva! Sayangnya, ada masalah dengan ini sebagai pendekatan.

Masalah pertama dengan inspeksi visual adalah Anda mengalami kecelakaan pengelasan yang buruk karena tidak dapat memeriksa lagi kebenaran kode Anda.

Masalah kedua adalah bahwa sepasang mata yang digunakan erat dengan otak pemilik mata. Jika pembuat kode juga memiliki mata yang digunakan dalam proses inspeksi visual, proses verifikasi kebenaran memiliki ketergantungan pada pengetahuan tentang program yang diinternalisasi dalam otak inspektur visual.

Sulit bagi sepasang mata baru untuk masuk dan memverifikasi kebenaran kode hanya karena mereka tidak bermitra dengan otak pembuat kode asli. Pemilik sepasang mata kedua harus berkomunikasi dengan pembuat kode yang asli agar dapat sepenuhnya memahami kode yang dimaksud. Percakapan sebagai sarana berbagi pengetahuan terkenal tidak bisa diandalkan. Suatu titik yang diperdebatkan jika Original Coder tidak tersedia untuk mata pasangan yang baru. Dalam hal itu, sepasang mata yang baru harus membaca kode asli.

Membaca kode orang lain yang tidak dicakup oleh tes unit lebih sulit daripada membaca kode yang memiliki tes unit terkait. Paling-paling membaca kode orang lain adalah pekerjaan yang sulit, paling buruk ini adalah tugas yang paling bombastis dalam rekayasa perangkat lunak. Ada alasan bahwa pengusaha, ketika mengiklankan lowongan pekerjaan, menekankan bahwa suatu proyek adalah bidang baru (atau baru). Menulis kode dari awal lebih mudah daripada memodifikasi kode yang ada dan dengan demikian membuat pekerjaan yang diiklankan tampak lebih menarik bagi karyawan potensial.

Dengan pengujian unit kami membagi kode menjadi bagian-bagian komponennya. Untuk setiap komponen kami kemudian menetapkan kios kami yang menyatakan bagaimana program harus bersikap . Setiap tes unit menceritakan tentang bagaimana bagian program itu harus bertindak dalam skenario tertentu. Setiap pengujian unit seperti klausa dalam kontrak yang menjelaskan apa yang harus terjadi dari sudut pandang kode klien.

Ini kemudian berarti bahwa sepasang mata baru memiliki dua untaian dokumentasi langsung dan akurat pada kode yang dimaksud.

Pertama, mereka memiliki kode itu sendiri, implementasi, bagaimana kode itu dilakukan ; kedua mereka memiliki semua pengetahuan yang dijelaskan oleh pembuat kode asli dalam seperangkat pernyataan formal yang menceritakan kisah bagaimana kode ini seharusnya berperilaku.

Tes unit menangkap dan secara formal menggambarkan pengetahuan yang dimiliki penulis asli ketika mereka mengimplementasikan kelas. Mereka memberikan deskripsi tentang bagaimana kelas itu berperilaku ketika digunakan oleh klien.

Anda benar untuk mempertanyakan kegunaan melakukan ini karena dimungkinkan untuk menulis unit test yang tidak berguna, tidak mencakup semua kode yang dimaksud, menjadi basi atau ketinggalan zaman dan sebagainya. Bagaimana kita memastikan bahwa unit test tidak hanya meniru tetapi juga memperbaiki proses seorang penulis yang berpengetahuan luas dan teliti memeriksa laporan output kode mereka saat runtime? Tulis tes unit terlebih dahulu kemudian tulis kode untuk lulus tes. Ketika Anda selesai, biarkan komputer menjalankan tes, mereka cepat mereka hebat dalam melakukan tugas yang berulang-ulang mereka cocok untuk pekerjaan itu.

Pastikan kualitas pengujian dengan meninjau mereka setiap kali Anda menyentuh kode yang mereka uji dan menjalankan tes untuk setiap build. Jika tes gagal, segera perbaiki.

Kami mengotomatiskan proses menjalankan tes sehingga mereka dijalankan setiap kali kami membangun proyek. Kami juga mengotomatiskan pembuatan laporan cakupan kode yang merinci persentase kode yang dicakup dan dilaksanakan oleh pengujian. Kami berusaha keras untuk mendapatkan persentase tinggi. Beberapa perusahaan akan mencegah perubahan kode dari diperiksa ke kontrol kode sumber jika mereka tidak memiliki tes unit yang cukup tertulis untuk menggambarkan perubahan perilaku pada kode. Biasanya sepasang mata kedua akan meninjau perubahan kode bersama dengan penulis perubahan. Peninjau akan melalui perubahan memastikan bahwa perubahan dapat dipahami dan dicakup oleh tes. Jadi proses peninjauan adalah manual, tetapi ketika tes (unit dan tes integrasi dan mungkin tes penerimaan pengguna) lulus proses review manual ini menjadi bagian dari proses build otomatis. Ini dijalankan setiap kali perubahan dicentang. A server melakukan tugas ini sebagai bagian dari proses pembangunan.

Pengujian yang dijalankan secara otomatis, menjaga integritas perilaku kode dan membantu mencegah perubahan di masa mendatang pada basis kode dari memecahkan kode .

Akhirnya, memberikan tes memungkinkan Anda untuk secara agresif memasukkan kembali kode faktor karena Anda dapat membuat perbaikan kode besar aman karena mengetahui bahwa perubahan Anda tidak merusak tes yang ada.

Ada peringatan untuk Pengembangan Test Driven dan itu adalah bahwa Anda harus menulis kode dengan mata agar dapat diuji. Ini melibatkan pengkodean ke antarmuka dan menggunakan teknik seperti Dependency Injection untuk instantiate objek yang berkolaborasi. Lihatlah karya Kent Beck yang menggambarkan TDD dengan sangat baik. Cari kode untuk antarmuka dan belajar

Rob Kielty
sumber
13

Ketika Anda menguji menggunakan sesuatu seperti System.out, Anda hanya menguji sebagian kecil dari kasus penggunaan yang mungkin. Ini tidak terlalu menyeluruh ketika Anda berurusan dengan sistem yang dapat menerima input berbeda dalam jumlah tak terbatas.

Tes unit dirancang untuk memungkinkan Anda menjalankan tes dengan cepat pada aplikasi Anda menggunakan sekumpulan input data yang sangat besar dan beragam. Selain itu, unit test terbaik juga memperhitungkan kasus batas, seperti input data yang terletak tepat di tepi apa yang dianggap valid.

Bagi manusia untuk menguji semua input yang berbeda ini bisa memakan waktu berminggu-minggu sedangkan itu membutuhkan waktu beberapa menit untuk mesin.

Pikirkan seperti ini: Anda juga tidak "menguji" sesuatu yang statis. Aplikasi Anda kemungkinan besar akan melalui perubahan konstan. Oleh karena itu, tes unit ini dirancang untuk dijalankan pada titik yang berbeda dalam siklus kompilasi atau penyebaran. Mungkin keuntungan terbesar adalah ini:

Jika Anda memecahkan sesuatu dalam kode Anda, Anda akan mengetahuinya sekarang , bukan setelah Anda ditempatkan, bukan ketika seorang penguji QA menangkap bug, bukan ketika klien Anda telah membatalkan. Anda juga akan memiliki peluang yang lebih baik untuk memperbaiki kesalahan dengan segera , karena jelas bahwa hal yang memecahkan bagian kode tersebut kemungkinan besar terjadi sejak kompilasi terakhir Anda. Dengan demikian, jumlah pekerjaan investigasi yang diperlukan untuk memperbaiki masalah sangat berkurang.

jmort253
sumber
9

Saya menambahkan beberapa System.out lain TIDAK bisa melakukan:

  • Jadikan setiap kasus uji independen (Sangat penting)

    JUnit dapat melakukannya: setiap kali contoh kasus uji baru akan dibuat dan @Beforedipanggil.

  • Pisahkan kode pengujian dari sumber

    JUnit bisa melakukannya.

  • Integrasi dengan CI

    JUnit dapat melakukannya dengan Ant dan Maven.

  • Atur dan gabungkan test case dengan mudah

    JUnit dapat melakukan @Ignoredan menguji suite.

  • Mudah untuk memeriksa hasilnya

    JUnit menawarkan banyak metode Assert ( assertEquals, assertSame...)

  • Mock and stub membuat Anda fokus pada modul tes.

    JUnit dapat melakukannya: Menggunakan tiruan dan rintisan membuat Anda mengatur perlengkapan yang benar, dan fokus pada logika modul uji.

卢 声 远 Shengyuan Lu
sumber
9

Tes unit memastikan bahwa kode berfungsi sebagaimana dimaksud. Mereka juga sangat membantu untuk memastikan bahwa kode masih berfungsi sebagaimana dimaksud jika Anda harus mengubahnya nanti untuk membangun fungsionalitas baru untuk memperbaiki bug. Memiliki cakupan tes yang tinggi dari kode Anda memungkinkan Anda untuk terus mengembangkan fitur tanpa harus melakukan banyak tes manual.

Pendekatan manual Anda System.outbagus tapi bukan yang terbaik. Ini adalah pengujian satu kali yang Anda lakukan. Di dunia nyata, persyaratan terus berubah dan sebagian besar waktu Anda membuat banyak modifikasi ke fungsi dan kelas yang ada. Jadi ... tidak setiap kali Anda menguji bagian kode yang sudah ditulis.

ada juga beberapa fitur yang lebih canggih seperti di JUnit

Pernyataan pernyataan

JUnit menyediakan metode untuk menguji kondisi tertentu, metode ini biasanya dimulai dengan konfirmasi dan memungkinkan Anda menentukan pesan kesalahan, hasil yang diharapkan dan hasil aktual

Beberapa metode ini adalah

  1. fail([message])- Biarkan tes gagal. Dapat digunakan untuk memeriksa bahwa bagian tertentu dari kode tidak tercapai. Atau memiliki tes gagal sebelum kode tes diterapkan.
  2. assertTrue(true)/ assertTrue(false)- Akan selalu benar / salah. Dapat digunakan untuk menentukan hasil tes, jika tes belum dilaksanakan.
  3. assertTrue([message,] condition)- Memeriksa apakah boolean conditionbenar.
  4. assertEquals([message,] expected, actual)- Menguji apakah dua nilai sama (sesuai dengan equalsmetode jika diterapkan, jika tidak menggunakan ==perbandingan referensi). Catatan: Untuk array, itu adalah referensi yang diperiksa, dan bukan isinya, gunakan assertArrayEquals([message,] expected, actual)untuk itu.
  5. assertEquals([message,] expected, actual, delta)- Menguji apakah dua nilai float atau double berada dalam jarak tertentu dari satu sama lain, dikendalikan oleh deltanilai tersebut.
  6. assertNull([message,] object) - Memeriksa apakah objek tersebut null

dan seterusnya. Lihat Javadoc lengkap untuk semua contoh di sini .

Suites

Dengan Test suites, Anda dapat menggabungkan beberapa kelas uji menjadi satu unit sehingga Anda dapat menjalankan semuanya sekaligus. Contoh sederhana, menggabungkan kelas uji MyClassTestdan MySecondClassTestmenjadi satu Suite yang disebut AllTests:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, MySecondClassTest.class })
public class AllTests { } 
Arvind
sumber
6

Keuntungan utama JUnit adalah ia otomatis daripada Anda secara manual harus memeriksa dengan hasil cetak Anda. Setiap tes yang Anda tulis tetap dengan sistem Anda. Ini berarti bahwa jika Anda membuat perubahan yang memiliki efek samping yang tidak terduga, tes Anda akan menangkapnya dan gagal daripada Anda harus ingat untuk menguji semuanya secara manual setelah setiap perubahan.

n00begon
sumber
4

JUnit adalah kerangka pengujian unit untuk Bahasa Pemrograman Java. Ini penting dalam pengembangan yang didorong oleh pengujian, dan merupakan salah satu dari keluarga kerangka pengujian unit yang dikenal sebagai xUnit.

JUnit mempromosikan ide "pengujian pertama, lalu mengkode", yang menekankan pada pengaturan data uji untuk sepotong kode yang dapat diuji terlebih dahulu dan kemudian dapat diimplementasikan. Pendekatan ini seperti "uji sedikit, kode sedikit, uji sedikit, kode sedikit ..." yang meningkatkan produktivitas programmer dan stabilitas kode program yang mengurangi stres programmer dan waktu yang dihabiskan untuk debugging.

Fitur JUnit adalah kerangka kerja open source yang digunakan untuk menulis & menjalankan tes.

Memberikan Anotasi untuk mengidentifikasi metode pengujian.

Memberikan Pernyataan untuk menguji hasil yang diharapkan.

Menyediakan pelari Uji untuk menjalankan tes.

Tes JUnit memungkinkan Anda untuk menulis kode lebih cepat yang meningkatkan kualitas

JUnit sederhana dan elegan. Itu tidak terlalu rumit & membutuhkan waktu lebih sedikit.

Tes JUnit dapat dijalankan secara otomatis dan mereka memeriksa hasil mereka sendiri dan memberikan umpan balik langsung. Tidak perlu menyisir secara manual laporan hasil pengujian.

Tes JUnit dapat diatur menjadi suite tes yang berisi kasus uji dan bahkan suite tes lainnya.

Junit menunjukkan kemajuan tes di bar yang berwarna hijau jika tes berjalan dengan baik dan berubah menjadi merah ketika tes gagal.

AKKI
sumber
2

Saya memiliki perspektif yang sedikit berbeda tentang mengapa JUnit diperlukan.

Anda sebenarnya dapat menulis sendiri semua test case tetapi rumit. Inilah masalahnya:

  1. Alih-alih, System.outkami dapat menambah if(value1.equals(value2))dan mengembalikan 0 atau -1 atau pesan kesalahan. Dalam hal ini, kita membutuhkan kelas uji "utama" yang menjalankan semua metode ini dan memeriksa hasil serta mempertahankan kasus uji mana yang gagal dan mana yang lulus.

  2. Jika Anda ingin menambahkan beberapa tes lagi, Anda perlu menambahkannya ke kelas tes "utama" ini juga. Perubahan pada kode yang ada. Jika Anda ingin mendeteksi secara otomatis kasus uji dari kelas tes, maka Anda perlu menggunakan refleksi.

  3. Semua tes dan kelas utama Anda untuk menjalankan tes tidak terdeteksi oleh gerhana dan Anda harus menulis konfigurasi debug / run khusus untuk menjalankan tes ini. Anda masih tidak melihat output berwarna hijau / merah yang cantik.

Inilah yang sedang dilakukan JUnit:

  1. Ini memiliki assertXXX()metode yang berguna untuk mencetak pesan kesalahan yang bermanfaat dari kondisi dan mengkomunikasikan hasil ke kelas "utama".

  2. Kelas "utama" disebut pelari yang disediakan oleh JUnit, jadi kita tidak perlu menulis apa pun. Dan mendeteksi metode pengujian secara otomatis dengan refleksi. Jika Anda menambahkan tes baru dengan @Testanotasi maka tes tersebut secara otomatis terdeteksi.

  3. JUnit memiliki integrasi gerhana dan juga integrasi maven / gradle, sehingga mudah untuk menjalankan tes dan Anda tidak perlu menulis konfigurasi run khusus.

Saya bukan ahli JUnit, jadi itulah yang saya pahami sekarang, akan menambah lebih banyak di masa depan.

Sreekar
sumber
Saya kira pada bagian pertama Anda menulis apa yang akan kita lakukan jika JUnit tidak ada di sana untuk membuat unit pengujian sedikit lebih baik daripada pernyataan system.out.println. Mungkin JUnit adalah hasil dari upaya semacam itu oleh beberapa programmer dan mereka merasa perlu untuk menulis kerangka pengujian terpisah untuk melakukan otomatisasi ini, jadi JUnit lahir, mungkin.
Saurabh Patil
1

Anda tidak dapat menulis kasus uji apa pun tanpa menggunakan kerangka kerja pengujian atau Anda harus menulis kerangka pengujian untuk memberikan keadilan bagi kasus uji Anda. Berikut adalah beberapa info tentang JUnit Framework selain dari itu Anda dapat menggunakan kerangka kerja TestNG.

Apa itu Junit?

Junit banyak digunakan kerangka pengujian bersama dengan Bahasa Pemrograman Java. Anda dapat menggunakan kerangka kerja otomatisasi ini untuk pengujian unit dan pengujian UI. Ini membantu kami menentukan aliran eksekusi kode kami dengan Anotasi yang berbeda. Junit dibangun berdasarkan ide "pengujian pertama dan kemudian pengkodean" yang membantu kita meningkatkan produktivitas kasus uji dan stabilitas kode.

Fitur Penting dari Pengujian Junit -

  1. Ini adalah kerangka pengujian open source yang memungkinkan pengguna untuk menulis dan menjalankan test case secara efektif.
  2. Menyediakan berbagai jenis anotasi untuk mengidentifikasi metode pengujian.
  3. Menyediakan Berbagai Jenis Pernyataan untuk memverifikasi hasil pelaksanaan uji kasus.
  4. Ini juga memberikan pelari tes untuk menjalankan tes secara efektif.
  5. Ini sangat sederhana dan karenanya menghemat waktu.
  6. Ini menyediakan cara untuk mengatur test case Anda dalam bentuk test suit.
  7. Ini memberikan hasil uji kasus dengan cara yang sederhana dan elegan.
  8. Anda dapat mengintegrasikan jUnit dengan Eclipse, Android Studio, Maven & Ant, Gradle dan Jenkins
anuja jain
sumber
0

JUNIT adalah metode yang biasanya diterima oleh pengembang java. Di mana mereka dapat memberikan input yang diharapkan serupa ke fungsi dan memutuskan sesuai bahwa kode tertulis ditulis dengan sempurna atau jika uji kasus gagal maka pendekatan yang berbeda mungkin juga perlu diimplementasikan. JUNIT akan membuat pengembangan cepat dan akan memastikan 0 cacat pada fungsi.

mohit sarsar
sumber
0

JUNIT: MENGATASI DAN MENYESUAIKAN

Inilah perspektif saya tentang JUNIT.

JUNIT dapat digunakan untuk,
1) Mengamati perilaku sistem ketika unit baru ditambahkan dalam sistem itu.
2) Lakukan penyesuaian dalam sistem untuk menyambut unit "baru" dalam sistem.
Apa? Persis.

Kehidupan nyata misalnya.

Ketika kerabat Anda mengunjungi kamar asrama kampus Anda,
1) Anda akan berpura-pura lebih bertanggung jawab.
2) Anda akan menyimpan semua hal di mana mereka seharusnya, seperti sepatu di rak sepatu tidak di kursi, pakaian di lemari bukan di kursi.
3) Anda akan menyingkirkan semua barang selundupan.
4) Anda akan mulai membersihkan di setiap perangkat yang Anda miliki.

Dalam istilah pemrograman

Sistem:
UNIT kode Anda : fungsionalitas baru.
Karena kerangka kerja JUNIT digunakan untuk bahasa JAVA, maka JUNIT = JAVA UNIT (Mungkin).

Misalkan Anda sudah memiliki kode antipeluru dengan baik, tetapi persyaratan baru datang dan Anda harus menambahkan persyaratan baru dalam kode Anda. Persyaratan baru ini dapat memecahkan kode Anda untuk beberapa input (testcase).

Cara mudah untuk mengadaptasi perubahan ini adalah dengan menggunakan unit testing (JUNIT).
Untuk itu Anda harus menulis beberapa testcases untuk kode Anda ketika Anda sedang membangun basis kode Anda. Dan setiap kali persyaratan baru datang, Anda hanya menjalankan semua test case untuk melihat apakah ada test case gagal. Jika Tidak, maka Anda adalah artis ** BadA dan Anda siap untuk menyebarkan kode baru.
Jika ada testcases gagal maka Anda mengubah kode Anda dan menjalankan testcases lagi sampai Anda mendapatkan status hijau.

Rohit Singh
sumber