JUnit: cara menghindari "tidak ada metode yang dapat dijalankan" di kelas test utils

118

Saya telah beralih ke JUnit4.4 dari JUnit3.8. Saya menjalankan tes saya menggunakan ant, semua tes saya berjalan dengan sukses tetapi kelas utilitas tes gagal dengan kesalahan "Tidak ada metode yang dapat dijalankan". Pola yang saya gunakan adalah memasukkan semua kelas dengan nama * Test * di bawah folder uji.

Saya memahami bahwa pelari tidak dapat menemukan metode apa pun yang dianotasi dengan atribut @Test. Tapi mereka tidak mengandung anotasi seperti itu karena kelas-kelas ini bukan tes. Anehnya saat menjalankan tes ini di gerhana, tidak ada keluhan tentang kelas-kelas ini.

Di JUnit3.8 itu sama sekali bukan masalah karena kelas utilitas ini tidak memperluas TestCase sehingga pelari tidak mencoba mengeksekusinya.

Saya tahu saya dapat mengecualikan kelas-kelas khusus ini di target junit dalam skrip semut. Tetapi saya tidak ingin mengubah file build pada setiap kelas utilitas baru yang saya tambahkan. Saya juga dapat mengganti nama kelas (tetapi memberikan nama yang baik ke kelas selalu merupakan bakat terlemah saya :-))

Apakah ada solusi elegan untuk masalah ini?

LiorH
sumber
Apakah pengujian Anda berfungsi di Eclipse / NetBeans / IDE favorit Anda?
guerda
Saya menggunakan eclipse. Sebenarnya tidak ada masalah disana, bagaimanapun juga eclipse tidak mencoba menjalankan kelas-kelas tersebut. Aku penasaran bagaimana?
LiorH
Saya tidak tahu apakah kami memahami pertanyaan Anda. Harap baca ulang pertanyaan Anda dan mungkin tambahkan beberapa informasi lagi.
guerda
1
@guerda: Pertanyaan itu tampaknya cukup jelas bagi saya. Tugas Ant-nya adalah menemukan kelas yang tidak berisi pengujian, karena filter mengambil kelas utilitas. Oleh karena itu jawaban saya, yang saya percaya masih relevan sepenuhnya.
Jon Skeet
LiorH: Terima kasih atas klarifikasinya, jadi jawaban saya sia-sia :)
guerda

Jawaban:

50

Dengan asumsi Anda mengendalikan pola yang digunakan untuk menemukan kelas pengujian, saya sarankan untuk mengubahnya agar cocok *Testdaripada *Test*. Cara TestHelperitu tidak akan cocok, tapi FooTestakan.

Jon Skeet
sumber
1
Saya tidak berpikir itu akan membantu, karena dia pindah ke JUnit 4.4 dan itu tidak masalah.
guerda
2
Anda sepertinya melewatkan inti dari jawaban saya. Dia memiliki filter nama untuk menentukan kelas yang akan dianggap sebagai ujian. Jika dia mengubah filter, dia dapat dengan mudah mengecualikan kelas helper.
Jon Skeet
1
Saran Anda valid, namun saya memeriksa kelas tes saya dan beberapa dimulai dengan Tes dan beberapa diakhiri dengan Tes. tidak ada perbedaan yang jelas antara kelas utilitas dan kelas pengujian yang sebenarnya. Apakah menurut Anda konvensi yang Anda sarankan adalah praktik yang baik? (yaitu utilitas dimulai dengan Tes, dan tes diakhiri dengan Tes)
LiorH
4
Ini hampir merupakan konvensi bahwa Anda mengakhiri kelas testcase dengan * Test. Anda mungkin perlu melakukan refactor dengan mengganti nama kelas pengujian secara tepat dan juga mengganti nama pembantu sehingga mereka tidak akan menggunakan konvensi sufiks tersebut.
Spoike
2
Saya setuju dengan Spoike - jika Anda tidak dapat membedakan dari nama kelas apakah itu tes atau pembantu, Anda harus mengganti nama kelas. Ketentuannya lebih kepada "kelas adalah pengujian jika dan hanya jika diakhiri dengan Test." Kelas utilitas mungkin atau mungkin tidak dimulai dengan Test - tidak masalah.
Jon Skeet
142

Beri anotasi kelas util Anda dengan @Ignore. Ini akan menyebabkan JUnit tidak mencoba dan menjalankannya sebagai pengujian.

JoelPM
sumber
6
Sebenarnya, tidak, seharusnya tidak. @Ignore adalah untuk menonaktifkan tes sementara.
Alice Young
1
Maaf, tapi itu ide yang buruk. Anda ingin mulai memberi anotasi kode produksi Anda dengan anotasi terkait pengujian hanya karena mungkin cocok dengan pola pengujian? Jawaban yang tepat adalah untuk memperbaiki nama kelas jika mereka memicu pencocokan pola untuk pengujian. Dan pastikan polanya hanya menemukan kelas yang diakhiri dengan Test. Itu pola yang diterima secara umum
Kevin M
Ya, ini buruk dan saya tidak menyadarinya sampai setelah memberikan suara positif lain yang tidak dapat saya hapus. Buat kelas dasar Anda abstrak, kemudian JUnit akan mengabaikannya. Lihat jawaban @ gmoore di bawah ini.
Ryan Shillington
83

Kasus khusus saya memiliki skenario berikut. Tes kami

public class VenueResourceContainerTest extends BaseTixContainerTest

semua meluas

BaseTixContainerTest

dan JUnit mencoba menjalankan BaseTixContainerTest. BaseTixContainerTest yang malang hanya mencoba menyiapkan wadah, menyiapkan klien, memesan pizza, dan bersantai ... man.

Seperti disebutkan sebelumnya, Anda dapat membuat anotasi kelas dengan

@Ignore

Tapi itu menyebabkan JUnit melaporkan pengujian itu sebagai dilewati (bukan diabaikan sepenuhnya).

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

Semacam itu membuatku kesal.

Jadi saya membuat BaseTixContainerTest abstrak, dan sekarang JUnit benar-benar mengabaikannya.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
gmoore
sumber
7
Jauh lebih baik daripada@Ignore
neworld
Saya mencoba pendekatan @Ignore dan berpikir, itu bagus, lalu saya membaca jawaban ini dan menampar dahi saya, "Tentu saja !"
dnuttle
38

Untuk mencegah JUnit membuat instance kelas basis pengujian Anda, buat saja

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore melaporkannya sebagai diabaikan yang saya simpan untuk pengujian yang diabaikan sementara .)

froh42
sumber
3
Pelari JUnit juga sering mencoba membuat instance kelas abstrak, lalu gagal dengan error instantiation.
Holly Cummins
Bekerja dengan sempurna untuk kelas uji dasar saya
ruX
3
Ini berfungsi karena namanya (tidak diakhiri dengan Test), bukan karena pengubah abstrak. Ubah nama kelas menjadi MyBaseClassTest dan itu akan mencoba untuk memberi contoh seperti yang disebutkan oleh @HollyCummins (dan gagal)
Hutch
Dalam kasus saya, seharusnya begitu protected abstract class.
Mystic Lin
18
  1. Jika ini adalah kelas pengujian dasar Anda misalnya AbstractTest dan semua pengujian Anda memperluasnya, maka definisikan kelas ini sebagai abstrak
  2. Jika itu adalah kelas Util maka lebih baik hapus * Tes dari kelas, ubah namanya menjadi MyTestUtil atau Utils dll.
Raghu K Nair
sumber
10

Hati-hati saat menggunakan pelengkapan kode IDE untuk menambahkan impor @Test .

Ini harus import org.junit.Testdan tidak import org.testng.annotations.Test, misalnya. Jika Anda melakukan yang terakhir, Anda akan mendapatkan kesalahan "tidak ada metode yang dapat dijalankan".

Sridhar Sarnobat
sumber
Ini harus menjadi komentar daripada jawaban.
Swaranga Sarma
3
Saya tidak mengerti kenapa. Ini solusi yang valid.
Sridhar Sarnobat
4
Ide Intellij 2017 mengotak-atik pikiran saya dengan mengimpor org.junit.jupiter.api.Test! tetapi terima kasih kepada Anda, masalah ini telah diselesaikan sekarang
AmiNadimi
Terima kasih banyak, saya bingung saat mendapatkan masalah "tidak ada metode yang dapat dijalankan".
Peter S.
7

Ant kini hadir dengan skipNonTestsatribut yang dirancang untuk melakukan persis seperti yang Anda cari. Tidak perlu mengubah kelas dasar Anda menjadi abstrak atau menambahkan anotasi padanya.

mc1arke.dll
sumber
2
Sepertinya skipNonTestsatribut tersebut hanya tersedia di ant 1.9+, yang memalukan, karena terlihat sangat berguna. Ini juga akan mengecualikan superclass uji abstrak.
Holly Cummins
4

Bagaimana dengan menambahkan metode pengujian kosong ke kelas-kelas ini?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
    assertTrue(true); // do nothing;
}
akuhn
sumber
8
tapi itu salah meningkatkan jumlah tes yang kami miliki :) bukan itu masalah besar
Sudarshan
1

Di kelas pengujian Anda jika menulis import org.junit.jupiter.api.Test; hapus dan tulis import org.junit.Test; Dalam hal ini, saya juga berhasil.

iluminatos
sumber
1
luar biasa, itu berhasil. saya dijalankan secara manual di baris perintah Windows. Namun, masalah lain adalah itu @BeforeAlldan @AfterAlltidak dijalankan.
BingLi224
tampaknya, JUnit4 bekerja (dengan @BeforeClassdan @AfterClass, tetapi JUnit5 tidak. Referensi: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224
0

Saya juga menghadapi masalah serupa ("tidak ada metode yang dapat dijalankan ..") saat menjalankan bagian kode sederhana yang paling sederhana (Menggunakan @Test, @Before, dll.) Dan tidak menemukan solusinya di mana pun. Saya menggunakan Junit4 dan Eclipse SDK versi 4.1.2. Mengatasi masalah saya dengan menggunakan Eclipse SDK 4.2.2 terbaru. Saya harap ini membantu orang-orang yang berjuang dengan masalah yang agak serupa.

Rahul Vig
sumber