Apa perbedaan antara Kegagalan dan Kesalahan di JUnit?

93

Saya menjalankan tes JUnit pada basis kode yang besar, dan saya menyadari bahwa terkadang saya mendapatkan "Kesalahan" sementara di lain waktu saya mendapatkan "Kegagalan". Apa bedanya?

froadie
sumber

Jawaban:

116

Oke, saya baru saja memperhatikan sebuah pola dan berpikir saya telah menemukannya (perbaiki saya jika saya salah). Menurut saya, kegagalan adalah saat kasus pengujian Anda gagal - misalnya, pernyataan Anda salah. Kesalahan adalah kesalahan tak terduga yang terjadi saat mencoba menjalankan pengujian - pengecualian, dll.

froadie
sumber
5
Meskipun jika sesuatu yang diperpanjang java.lang.AssertionErrordilemparkan, itu akan ditampilkan sebagai kegagalan pengujian, bukan kesalahan pengujian. Anda harus mempertimbangkan untuk menerima jawaban Anda sendiri karena itu benar.
ponzao
Ya, itulah perbedaannya. Dan dari perspektif pragmatis "tidak ada perbedaan" - jika Anda mendapatkan kesalahan atau kegagalan, maka Anda perlu memperbaikinya. Jadi, mungkin ada kesalahan untuk menghitung "kegagalan" dan "kesalahan" secara terpisah di JUnit. JUnit 4 menggabungkan keduanya (seperti yang dijelaskan dalam jawaban di bawah).
Jeff Grigg
Dan jika pengecualian diharapkan, Anda harus memberi anotasi @Testdengan expected = SomeException.class.
Downhillski
@JeffGrigg ada perbedaan pragatis. Jika satu perilaku diandalkan dalam beberapa kasus pengujian, saya masih dapat menulis hanya satu kasus pengujian yang menegaskan perilaku tersebut, sambil membuang pengecualian waktu proses yang tidak tertangkap di semua kasus lainnya. Ini berarti bahwa kasus pengujian lainnya sedang menguji sesuatu yang lain meskipun mereka masih bergantung pada perilaku tertentu untuk berjalan. Ketika perilaku itu rusak, hanya satu kasus pengujian yang akan melaporkan kegagalan sementara yang lainnya melaporkan kesalahan, dan dari sini saya dapat melihat bahwa saya memiliki tepat satu bug untuk diperbaiki meskipun banyak kasus pengujian tidak lulus.
RonJRH
org.junit.Assert.assertEquals () jika gagal dianggap ERROR oleh laporan HTML JUnit4. Ini bertentangan dengan pernyataan Anda (yang saya sadari sampai sekarang). Bisakah Anda menjelaskan lebih lanjut tentang ini?
Krishnom
15

Jika pengujian Anda menampilkan pengecualian yang tidak digelembungkan melalui kerangka kerja Assertion di Junit, itu akan dilaporkan sebagai kesalahan. Misalnya, pengecualian NullPointer, atau ClassNotFound akan melaporkan kesalahan:

String s = null;
s.trim();

atau,

try {

    // your code
} catch(Exception e) {
    // log the exception
    throw new MyException(e);
}

Karena itu, berikut ini akan melaporkan kegagalan:

Assert.fail("Failure here");

atau,

Assert.assertEquals(1, 2);

atau bahkan:

throw new AssertionException(e);

Itu tergantung pada versi Junit yang Anda gunakan. Junit 4 akan membuat perbedaan antara kegagalan dan kesalahan, tetapi Junit 4 menyederhanakannya sebagai kegagalan saja.

Tautan berikut memberikan masukan yang lebih menarik:

http://www.devx.com/Java/Article/31983/1763/page/2

Neel
sumber
Ini tidak akurat. Perbedaan antara kegagalan pengujian dan kesalahan pengujian tidak hilang di JUnit 4. Saya baru saja mengujinya. Artikel terkait itu menyesatkan. Dikatakan "JUnit 4 membuatnya lebih sederhana dengan hanya menggunakan kegagalan" tetapi harus menekankan bahwa JUnit 4 mengubah java.lang.AssertionError menjadi kegagalan pengujian sehingga Anda tidak perlu menggunakan junit.framework.AssertionFailedError. Manfaatnya adalah Anda dapat mulai menulis pernyataan pengujian dalam kode produksi tanpa proyek yang ditautkan ke JUnit. Perbedaan antara kesalahan pengujian dan kegagalan pengujian juga sangat berguna dan akan menjadi langkah mundur jika dihapus.
RonJRH
RonJRH, apakah Anda dapat melihat kesalahan dalam laporan junit default Anda?
Neel
Ya Neel. Saya baru mencobanya. Tidak begitu yakin etik menautkan gambar di sini tetapi ini menunjukkan hasil pengujian saya: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH
6

Dari "Pengujian Unit Pragmatis di Java 8 dengan JUnit":

Assertion (atau asserts) di JUnit adalah panggilan metode statis yang Anda masukkan ke pengujian. Setiap pernyataan adalah kesempatan untuk memverifikasi bahwa beberapa kondisi benar. Jika kondisi yang ditegaskan tidak berlaku, pengujian berhenti di sana, dan JUnit melaporkan kegagalan pengujian.

(Mungkin juga saat JUnit menjalankan pengujian Anda, pengecualian akan muncul dan tidak tertangkap. Dalam kasus ini, JUnit melaporkan error pengujian.)

Matias Elorriaga
sumber
5

Tes di bawah ini menjelaskan perbedaan antara Test Error vs Test failure .

Saya telah mengomentari baris yang melempar kesalahan pengujian dan kegagalan pengujian.

    @Test
    public void testErrorVsTestFailure() {

        final String sampleString = null;

        assertEquals('j', sampleString.charAt(0) );
        //above line throws test error as you are trying to access charAt() method on null reference

        assertEquals(sampleString, "jacob");
        //above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
        }

Jadi Junit menunjukkan kesalahan pengujian setiap kali Anda mendapatkan pengecualian, dan pengujian gagal saat nilai hasil yang Anda harapkan tidak sesuai dengan nilai sebenarnya

Deen John
sumber
2

Kelas sumber: JUnitReportReporter.java

public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......

            for (ITestResult tr : (Set) entry.getValue()) {
                TestTag testTag = new TestTag();

                boolean isSuccess = tr.getStatus() == 1;
                if (!(isSuccess)) {
                    if (tr.getThrowable() instanceof AssertionError)
                        ++errors;
                    else {
                        ++failures;
                    }
                }
}

Seperti yang Anda lihat di bawah garis dalam metode di atas

tr.getThrowable () instance dari AssertionError

jumlah kesalahan bertambah ketika itu adalah instance dari AssertionError, sebaliknya (semua Throwable) dihitung sebagai kegagalan.

Roushan
sumber
1

Anda benar bahwa kegagalan berasal dari AssertionErrors yang muncul oleh metode pernyataan JUnit, atau dengan melemparkan AssertionError, atau dengan memberikan pengecualian yang Anda nyatakan dalam @Testanotasi Anda , dan Kesalahan berasal dari Pengecualian tak terduga lainnya. Tetapi ada perbedaan penting di antara keduanya:

Kegagalan berarti pengujian Anda berjalan dengan benar, dan mengidentifikasi kerusakan pada kode Anda.

Kesalahan bisa berarti bug dalam kode Anda, tetapi yang bahkan belum Anda uji. Ini juga bisa berarti bahwa bug sedang dalam pengujian itu sendiri.

Singkatnya, kegagalan berarti Anda perlu menulis ulang kode yang sedang diuji. Kesalahan berarti mungkin tes unit yang perlu Anda tulis ulang. Ini mungkin berarti ini bahkan jika kegagalan ada dalam kode Anda, seperti a NullPointerException, karena Anda mendeteksi cacat yang bahkan tidak Anda uji, jadi mungkin bijaksana untuk mengujinya.

MiguelMunoz
sumber
0

Ironisnya, junit dan kerangka kerja terkait pengujian lainnya (testng, hamcrest) menyediakan operasi assert yang memverifikasi kondisi dan jika gagal, maka "under-the-hood" java.lang.AssertionError sedang dilempar, yang btw memperluas java.lang.Error.

Namun tidak mungkin bertentangan dengan jawaban di atas yang tentunya sepenuhnya valid. Jadi untuk menandai aliran pengujian tertentu sebagai kegagalan, seseorang dapat melempar AssertionError, namun saya tidak yakin itu benar-benar didokumentasikan dalam manual yang sesuai, karena lebih sesuai untuk menggunakan API fail () khusus. Jenis Throwable lainnya akan dianggap sebagai kesalahan, bukan kegagalan.

agolubev81.dll
sumber
0

Pada dasarnya, kegagalan mengacu pada pernyataan yang tidak terpenuhi sementara kesalahan disebabkan oleh eksekusi uji yang tidak normal . dan menurut saya setiap IDE memiliki ikon simbolik dengan warna berbeda untuk lulus , gagal , dan dengan uji kesalahan .

Untuk informasi lebih lanjut, periksa ini .

Soufiane Roui
sumber