Saya menyiapkan kelas dengan beberapa pengujian dan daripada menggunakan, @Beforesaya ingin memiliki metode penyiapan yang hanya dijalankan sekali sebelum semua pengujian. Apakah itu mungkin dengan Junit 4.8?
Meskipun saya setuju dengan @assylias bahwa menggunakan @BeforeClassadalah solusi klasik tidak selalu nyaman. Metode yang dianotasi @BeforeClassharus statis. Sangat merepotkan untuk beberapa tes yang membutuhkan contoh kasus uji. Misalnya pengujian berbasis Spring yang digunakan @Autowireduntuk bekerja dengan layanan yang ditentukan dalam konteks pegas.
Dalam hal ini saya pribadi menggunakan setUp()metode biasa yang dianotasi dengan @Beforeanotasi dan mengelola bendera custom static(!) Saya boolean:
privatestaticboolean setUpIsDone =false;.....@Beforepublicvoid setUp(){if(setUpIsDone){return;}// do the setup
setUpIsDone =true;}
Menambah komentar Kenny Cason mengapa itu harus statis. Ini harus statis karena JUnit membuat instance baru dari kelas pengujian untuk setiap metode @Test. Variabel instance akan disetel ulang ke nilai defaultnya (salah) untuk setiap instance jika tidak statis. Lihat info lebih lanjut: martinfowler.com/bliki/JunitNewInstance.html
dustin.schultz
2
Ini berfungsi kecuali dalam kasus di mana setUp()metode dalam superclass - telah memposting jawaban di bawah ini mencoba untuk menyelesaikan ini.
Steve Chambers
4
Saya ragu untuk mengatakan ini kepada seseorang dengan perwakilan 84k, tetapi BeforeClass sebenarnya tidak menjawab pertanyaan: BeforeClass dijalankan di awal setiap kelas pengujian. Tapi OP meminta satu yang berjalan "hanya sekali sebelum semua tes". Solusi yang Anda usulkan dapat melakukan ini, tetapi Anda harus membuat semua kelas pengujian Anda memperpanjang kelas "CommonTest" ...
mike rodent
1
@mikerodent, IMHO OP menanyakan tentang semua tes dalam test case-nya, tidak semua tes secara keseluruhan. Jadi, komentar Anda kurang relevan. BTW, jangan khawatir untuk mengatakan apa pun kepada siapa pun meskipun reputasinya tinggi. Setidaknya inilah yang saya lakukan :). Dan reputasi saya jauh lebih rendah pada Agustus 2012 ketika saya menjawab pertanyaan itu.
AlexR
Tidak berfungsi untuk kasus saya, variabel yang diinisialisasi dalam pengaturan disetel ulang setelah setiap pengujian, jadi tidak ada gunanya melakukan init hanya sekali.
@mikerodent Saya memahami pertanyaan sebagai "semua tes di kelas" - tetapi Anda benar itu mungkin bukan yang diinginkan OP.
assylias
29
JUnit 5 sekarang memiliki anotasi @BeforeAll:
Menunjukkan bahwa metode yang dianotasi harus dijalankan sebelum semua metode @Test di kelas atau hierarki kelas saat ini; analog dengan @BeforeClass milik JUnit 4. Metode seperti itu harus statis.
Anotasi siklus hidup JUnit 5 tampaknya akhirnya benar! Anda dapat menebak anotasi mana yang tersedia tanpa perlu melihat (mis. @BeforeEach @AfterAll)
Ini memiliki masalah yang sama @BeforeClass, itu perlu static. Solusi IMO @ AlexR lebih bagus.
zengr
@ zengr cenderung setuju dengan Anda: seperti yang telah saya katakan kepada AlexR, solusinya mengharuskan semua kelas pengujian untuk subkelas dari kelas CommonTest jika hanya untuk dijalankan sekali. Tapi sesederhana mungkin, dan IMHO Anda mungkin tidak boleh menggunakan solusi kerangka kerja "mewah" yang disediakan ketika mekanisme sederhana tersedia dari bahasa. Kecuali jika ada alasan bagus tentunya. Juga, menggunakan hal sederhana seperti miliknya, dengan nama jenis "melakukan apa yang tertulis di kaleng" yang bagus, membantu keterbacaan.
mike rodent
Karena itu, sekali lagi IMHO, tampaknya ada lebih banyak pembenaran untuk memiliki anotasi "Lagi pula": akan sangat sulit dan dibuat-buat untuk merancang mekanisme untuk mendeteksi ketika semua tes dilakukan. Sebaliknya, tentu saja, para puritan mungkin akan berkata bahwa Anda tidak perlu melakukan "pembersihan akhir", yaitu setiap "tearDown" harus membiarkan semua sumber daya dalam keadaan bersih ... dan mereka mungkin benar!
mike rodent
Apakah ini berfungsi dengan Maven di mana ada beberapa modul, masing-masing dengan pengujiannya?
Mark Boon
@mike rodent, dalam kasus saya menyiapkan dan menghancurkan file uji di sistem file sebelum / setelah setiap pengujian tampaknya menyebabkan kebuntuan pada file. Untuk saat ini, saya telah sampai pada solusi AlexR untuk mengatur sekali. Saya memiliki dua flag statis, sudahSetup dan dirty. setup () memanggil cleanup () jika kondisi kotor terdeteksi pada awalnya, atau jika kegagalan pengaturan mengarah ke status kotor. Untuk membersihkan setelah menjalankan tes, saya menjalankannya lagi. Berantakan, tidak ideal sama sekali, tidak dalam proses pembuatan kami. Masih mencari cara yang lebih baik (jUnit 4.12).
Rebeccah
9
Saat setUp()berada di superclass dari kelas tes (misalnya di AbstractTestBasebawah), jawaban yang diterima dapat dimodifikasi sebagai berikut:
publicabstractclassAbstractTestBase{privatestaticClass<?extendsAbstractTestBase> testClass;.....publicvoid setUp(){if(this.getClass().equals(testClass)){return;}// do the setup - once per concrete test class.....
testClass =this.getClass();}}
Ini seharusnya bekerja untuk satu setUp()metode non-statis tetapi saya tidak dapat menghasilkan yang setara tearDown()tanpa tersesat ke dunia refleksi yang kompleks ... Bounty menunjuk kepada siapa saja yang bisa!
Sunting:
Saya baru tahu saat men-debug bahwa kelas tersebut dibuat sebelum setiap tes juga. Saya kira anotasi @BeforeClass adalah yang terbaik di sini.
Anda juga dapat menyiapkan konstruktor, bagaimanapun juga, kelas pengujian adalah kelas. Saya tidak yakin apakah ini praktik yang buruk karena hampir semua metode lain diberi anotasi, tetapi berhasil. Anda bisa membuat konstruktor seperti itu:
public UT (){// initialize once here}@Test// Some test here...
Ctor akan dipanggil sebelum pengujian karena tidak statis.
dengan @BeforeAllMethods/ @AfterAllMethodsannotation Anda dapat menjalankan metode apa pun di kelas Test dalam konteks instance, di mana semua nilai yang dimasukkan tersedia.
Tambahkan ke kelas abstrak Basis Anda (maksud saya kelas abstrak tempat Anda menginisialisasi driver dalam metode setUpDriver () ) bagian kode ini:
privatestaticboolean started =false;static{if(!started){
started =true;try{
setUpDriver();//method where you initialize your driver}catch(MalformedURLException e){}}}
Dan sekarang, jika kelas pengujian Anda akan diperluas dari kelas abstrak Dasar -> metode setUpDriver () akan dijalankan sebelum @Test pertama hanya SATU kali per proses.
Jawaban:
Meskipun saya setuju dengan @assylias bahwa menggunakan
@BeforeClass
adalah solusi klasik tidak selalu nyaman. Metode yang dianotasi@BeforeClass
harus statis. Sangat merepotkan untuk beberapa tes yang membutuhkan contoh kasus uji. Misalnya pengujian berbasis Spring yang digunakan@Autowired
untuk bekerja dengan layanan yang ditentukan dalam konteks pegas.Dalam hal ini saya pribadi menggunakan
setUp()
metode biasa yang dianotasi dengan@Before
anotasi dan mengelola bendera customstatic
(!) Sayaboolean
:sumber
setUp()
metode dalam superclass - telah memposting jawaban di bawah ini mencoba untuk menyelesaikan ini.Anda dapat menggunakan ini
BeforeClass
penjelasan :sumber
TheClassYouWant.class
selain panggilan getClass () Anda? Ini adalah Java yang sebenarnya:String.class.getName()
.JUnit 5 sekarang memiliki anotasi @BeforeAll:
Anotasi siklus hidup JUnit 5 tampaknya akhirnya benar! Anda dapat menebak anotasi mana yang tersedia tanpa perlu melihat (mis. @BeforeEach @AfterAll)
sumber
@BeforeClass
, itu perlustatic
. Solusi IMO @ AlexR lebih bagus.Saat
setUp()
berada di superclass dari kelas tes (misalnya diAbstractTestBase
bawah), jawaban yang diterima dapat dimodifikasi sebagai berikut:Ini seharusnya bekerja untuk satu
setUp()
metode non-statis tetapi saya tidak dapat menghasilkan yang setaratearDown()
tanpa tersesat ke dunia refleksi yang kompleks ... Bounty menunjuk kepada siapa saja yang bisa!sumber
Sunting: Saya baru tahu saat men-debug bahwa kelas tersebut dibuat sebelum setiap tes juga. Saya kira anotasi @BeforeClass adalah yang terbaik di sini.
Anda juga dapat menyiapkan konstruktor, bagaimanapun juga, kelas pengujian adalah kelas. Saya tidak yakin apakah ini praktik yang buruk karena hampir semua metode lain diberi anotasi, tetapi berhasil. Anda bisa membuat konstruktor seperti itu:
Ctor akan dipanggil sebelum pengujian karena tidak statis.
sumber
Coba solusi ini: https://stackoverflow.com/a/46274919/907576 :
dengan
@BeforeAllMethods
/@AfterAllMethods
annotation Anda dapat menjalankan metode apa pun di kelas Test dalam konteks instance, di mana semua nilai yang dimasukkan tersedia.sumber
Solusi kotor saya adalah:
Saya menggunakannya sebagai basis dasar untuk semua testCases saya.
sumber
Jika Anda tidak ingin memaksakan deklarasi variabel yang disetel dan diperiksa pada setiap subtes, maka menambahkan ini ke SuperTest bisa dilakukan:
sumber
Saya memecahkan masalah ini seperti ini:
Tambahkan ke kelas abstrak Basis Anda (maksud saya kelas abstrak tempat Anda menginisialisasi driver dalam metode setUpDriver () ) bagian kode ini:
Dan sekarang, jika kelas pengujian Anda akan diperluas dari kelas abstrak Dasar -> metode setUpDriver () akan dijalankan sebelum @Test pertama hanya SATU kali per proses.
sumber
Gunakan metode @PostConstruct Spring untuk melakukan semua pekerjaan inisialisasi dan metode ini berjalan sebelum @Test mana pun dijalankan
sumber