Unit pengujian katalog Anti-pola

203

anti-pola : harus ada setidaknya dua elemen kunci yang hadir untuk secara formal membedakan anti-pola yang sebenarnya dari kebiasaan buruk yang sederhana, praktik buruk, atau ide buruk:

  • Beberapa pola tindakan, proses atau struktur yang berulang-ulang yang awalnya tampak bermanfaat, tetapi pada akhirnya menghasilkan konsekuensi yang lebih buruk daripada hasil yang bermanfaat, dan
  • Solusi refactored yang didokumentasikan dengan jelas, terbukti dalam praktik nyata dan dapat diulang.

Pilih anti-pola TDD yang terlalu banyak Anda lihat "di alam liar".
Posting blog oleh James Carr dan diskusi terkait pada testdrivendevelopment yahoogroup

Jika Anda menemukan yang 'tidak bernama' satu .. poskan juga. Satu pos per anti-pola tolong untuk membuat suara dihitung untuk sesuatu.

Minat saya adalah menemukan subset top-n sehingga saya bisa mendiskusikan mereka di kotak makan siang bertemu dalam waktu dekat.

Gishu
sumber
Aaron, Anda sepertinya sudah memahami semua ini :) Apakah ide yang baik untuk menambahkan tag-line atau slogan sebagai komentar sehingga kita dapat memiliki lebih sedikit scrolling .. bagaimana?
Gishu
1
Ini datang dengan cukup baik .. terima kasih teman n gals. Terus mereka datang .. salah satu posting SO paling informatif IMHO
Gishu
2
+1 suka utas ini !!! Dan sebagian besar dari ini benar dan juga menang!
Chii
Bagus utas, mengapa komunitas ini wiki ???
Quibblesome
2
Karena itu semacam polling - Anda tidak akan mau memanen rep hanya karena Anda memposting jenis anti-pola yang paling umum;)
Gishu

Jawaban:

70

Warga Kelas Kedua - kode tes tidak terlalu baik di refactored sebagai kode produksi, yang mengandung banyak kode duplikat, membuatnya sulit untuk mempertahankan tes.

Ilja Preuß
sumber
67

Free Ride / Piggyback - James Carr, Tim Ottinger
Daripada menulis metode uji kasus baru untuk menguji fitur / fungsionalitas lain yang berbeda , pernyataan baru (dan tindakan terkaitnya yaitu langkah-langkah Bertindak dari AAA) ikut serta dalam sebuah uji kasus yang ada .

Aaron Digulla
sumber
15
Ya, itu favorit saya. Saya selalu melakukannya. Oh ... tunggu ... Anda mengatakan bahwa ini adalah hal yang buruk . :-)
guidoism
1
Saya tidak begitu yakin ini anti-pola. Semua invarian harus truesetelah setiap panggilan mutator yang mungkin. Jadi, Anda akan ingin memeriksa bahwa setiap invarian adalah truesetelah setiap kombinasi dari mutator dan input data yang Anda uji. Tetapi Anda ingin mengurangi duplikasi, dan memastikan Anda memeriksa semua invarian, termasuk invarian yang saat ini tidak menyebabkan kegagalan pengujian. Jadi, Anda menempatkan semuanya dalam checkInvariants()fungsi verifikasi dan menggunakannya dalam setiap tes. Kode berubah dan invarian lain ditambahkan. Anda memasukkannya ke dalam fungsi juga, tentu saja. Tetapi ini adalah freerider.
Raedwald
2
@Raedwald - Seiring waktu, nama tes tidak lagi cocok dengan semua hal yang diuji. Anda juga memiliki beberapa pukulan karena tes terjalin; kegagalan tidak menunjukkan penyebab pasti kegagalan. misalnya contoh kanonik dari tes ini akan membaca sesuatu seperti Superset Buram dari semua langkah Atur >> Bertindak >> Menegaskan A >> Bertindak lebih lanjut >> Menegaskan B >> Bertindak lagi >> Menegaskan C. Sekarang idealnya jika A dan C adalah rusak, Anda akan melihat 2 kegagalan tes. Dengan tes di atas, Anda hanya akan melihat satu, lalu Anda memperbaiki A dan pada menjalankan berikutnya, itu akan memberi tahu Anda bahwa sekarang C rusak. sekarang bayangkan 5-6 tes berbeda menyatu bersama ..
Gishu
1
"nama tes tidak lagi cocok dengan semua hal yang diuji" Hanya jika tes tersebut dinamai untuk kondisi posting yang semula hadir. Jika Anda memberi nama untuk kombinasi nama-metode, kondisi pengaturan dan input data (argumen metode), tidak ada masalah.
Raedwald
"kegagalan tidak menunjukkan penyebab pasti kegagalan" tidak ada kegagalan pernyataan yang pernah mengindikasikan penyebab kegagalan. Itu membutuhkan beberapa perincian ke dalam detail implementasi: debugging untuk kegagalan regresi, pengetahuan Anda tentang status pengembangan untuk beberapa pekerjaan TDD.
Raedwald
64

Selamat Jalan

Tes tetap berada di jalur senang (yaitu hasil yang diharapkan) tanpa menguji batas dan pengecualian.

JUnit Antipatterns

Geoglyph
sumber
Penyebab: Entah keterbatasan waktu yang berlebihan atau kemalasan yang mencolok. Solusi Refactored: Dapatkan waktu untuk menulis lebih banyak tes untuk menghilangkan positif palsu. Penyebab terakhir membutuhkan cambuk. :)
Spoike
59

Pahlawan Lokal

Kasing uji yang bergantung pada sesuatu yang spesifik untuk lingkungan pengembangan yang ditulisnya agar dapat dijalankan. Hasilnya adalah tes lulus pada kotak pengembangan, tetapi gagal ketika seseorang mencoba menjalankannya di tempat lain.

Ketergantungan Tersembunyi

Terkait erat dengan pahlawan lokal, tes unit yang membutuhkan beberapa data yang ada telah diisi di suatu tempat sebelum tes berjalan. Jika data itu tidak diisi, tes akan gagal dan meninggalkan sedikit indikasi kepada pengembang apa yang diinginkannya, atau mengapa ... memaksa mereka untuk menggali melalui kode hektar untuk mencari tahu dari mana data yang digunakan seharusnya berasal.


Sayangnya melihat ini terlalu sering dengan file .dll kuno yang bergantung pada file .ini yang samar dan bervariasi yang terus-menerus tidak sinkron pada sistem produksi yang diberikan, apalagi masih ada di mesin Anda tanpa konsultasi ekstensif dengan tiga pengembang yang bertanggung jawab untuk dll. Mendesah.

annakata
sumber
Itu adalah contoh yang bagus dari akronim pengembang WOMPC. "Bekerja di PC saya!" (Biasanya dikatakan untuk mendapatkan penguji dari belakang Anda.)
Joris Timmermans
58

Gang Rantai

Beberapa tes yang harus dijalankan dalam urutan tertentu, yaitu satu tes mengubah keadaan global sistem (variabel global, data dalam database) dan tes berikutnya tergantung padanya.

Anda sering melihat ini dalam tes basis data. Alih-alih melakukan rollback teardown(), tes melakukan perubahan mereka ke database. Penyebab umum lainnya adalah bahwa perubahan pada negara global tidak dibungkus blok try / akhirnya yang bersih jika tes gagal.

Aaron Digulla
sumber
yang satu ini benar-benar tidak menyenangkan .. Istirahat tes harus gagasan independen. Tapi saya sudah membacanya di beberapa tempat .. tebak 'TDD populer' cukup kacau
Gishu
56

The Mockery
Terkadang mengejek bisa baik, dan berguna. Tetapi terkadang pengembang dapat kehilangan diri mereka sendiri dan dalam upaya mereka untuk mengejek apa yang tidak diuji. Dalam hal ini, tes unit berisi begitu banyak ejekan, stub, dan / atau palsu sehingga sistem yang sedang diuji bahkan tidak diuji sama sekali, sebaliknya data yang dikembalikan dari ejekan adalah apa yang sedang diuji.

Sumber: Pos James Carr.

Gishu
sumber
2
Saya percaya penyebabnya adalah karena kelas Anda yang diuji memiliki dependensi yang terlalu banyak. Alternatif Refactored adalah mengekstrak kode yang dapat diisolasi.
Spoike
@Seperti; Jika Anda menggunakan arsitektur berlapis yang sangat tergantung pada peran kelas; beberapa lapisan cenderung memiliki lebih banyak ketergantungan daripada yang lain.
krosenvold
Baru-baru ini saya melihat, di blog yang disegani, penciptaan setup entitas tiruan dikembalikan dari repositori tiruan. WTF? Mengapa tidak hanya instantiate entitas nyata di tempat pertama. Saya sendiri, saya baru saja terbakar oleh antarmuka tiruan di mana implementasi saya melempar NotImplementedExceptions di sekitar.
Thomas Eyde
40

The Silent Catcher - Kelly?
Tes yang lolos jika pengecualian dilempar .. bahkan jika pengecualian yang sebenarnya terjadi adalah yang berbeda dari yang dimaksudkan pengembang.
Lihat Juga: Penangkap Rahasia

[Test]
[ExpectedException(typeof(Exception))]
public void ItShouldThrowDivideByZeroException()
{
   // some code that throws another exception yet passes the test
}
Gishu
sumber
Yang rumit dan berbahaya (yaitu membuat Anda berpikir Anda menguji kode yang selalu meledak setiap kali dijalankan). Itu sebabnya saya mencoba untuk lebih spesifik tentang kelas pengecualian dan sesuatu yang unik di dalam pesan.
Joshua Cheek
34


Tes unit Inspektur A yang melanggar enkapsulasi dalam upaya mencapai cakupan kode 100%, tetapi mengetahui begitu banyak tentang apa yang terjadi pada objek sehingga setiap upaya untuk refactor akan merusak tes yang ada dan memerlukan perubahan apa pun untuk tercermin dalam unit uji.


'bagaimana cara menguji variabel anggota saya tanpa mempublikasikannya ... hanya untuk pengujian unit?'

Gishu
sumber
2
Penyebab: Ketergantungan absurd pada pengujian kotak putih. Ada alat untuk menghasilkan tes semacam ini seperti Pex di .NET. Solusi Refactored: Sebagai gantinya uji perilaku dan jika Anda benar-benar perlu memeriksa nilai batas maka biarkan alat otomatis menghasilkan sisanya.
Spoike
1
Sebelum Moq datang, saya harus meninggalkan kerangka mengejek demi tulisan tangan mengejek saya. Terlalu mudah untuk mengikat tes saya dengan implementasi yang sebenarnya, membuat refactoring hampir mustahil. Saya tidak bisa membedakannya, selain dengan Moq, saya jarang melakukan kesalahan seperti ini.
Thomas Eyde
34

Pengaturan Berlebihan - James Carr
. Tes yang membutuhkan pengaturan besar untuk memulai pengujian. Kadang-kadang beberapa ratus baris kode digunakan untuk mempersiapkan lingkungan untuk satu pengujian, dengan beberapa objek yang terlibat, yang dapat membuatnya sulit untuk benar-benar memastikan apa yang diuji karena "noise" dari semua pengaturan yang terjadi. (Src: posting James Carr )

Gishu
sumber
Saya mengerti bahwa pengaturan tes yang berlebihan biasanya mengarah ke a) kode yang kurang terstruktur atau b) ejekan yang tidak memadai, benar?
Topher Hunt
Ya, setiap situasi bisa berbeda. Bisa jadi karena kopling tinggi. Tapi biasanya itu adalah kasus spesifikasi yang terlalu tinggi, menentukan (harapan palsu) masing-masing dan setiap kolaborator dalam skenario - ini pasangan tes untuk implementasi dan membuat mereka rapuh. Jika panggilan ke kolaborator adalah detail yang terkait dengan tes, itu tidak boleh dalam tes. Ini juga membantu agar tes ini singkat dan mudah dibaca.
Gishu
32

Probe Anal

Tes yang harus menggunakan cara-cara gila, ilegal atau tidak sehat untuk melakukan tugasnya seperti: Membaca bidang pribadi menggunakan setAccessible Java (benar) atau memperluas kelas untuk mengakses bidang / metode yang dilindungi atau harus memasukkan tes dalam paket tertentu untuk mengakses paket bidang / metode global.

Jika Anda melihat pola ini, kelas yang diuji menggunakan terlalu banyak data yang disembunyikan.

Perbedaan antara ini dan Inspektur adalah bahwa kelas yang diuji mencoba menyembunyikan bahkan hal-hal yang perlu Anda uji. Jadi tujuan Anda bukan untuk mencapai cakupan pengujian 100% tetapi untuk dapat menguji apa pun. Pikirkan kelas yang hanya memiliki bidang pribadi, run()metode tanpa argumen dan tidak ada getter sama sekali. Tidak ada cara untuk menguji ini tanpa melanggar aturan.


Komentar oleh Michael Borgwardt: Ini bukan benar-benar sebuah antipattern pengujian, ini pragmatisme untuk menangani kekurangan dalam kode yang diuji. Tentu saja lebih baik untuk memperbaiki kekurangan-kekurangan itu, tetapi itu tidak mungkin dalam kasus perpustakaan pihak ke-3.

Aaron Digulla: Saya agak setuju. Mungkin entri ini benar-benar lebih cocok untuk wiki "JUnit HOWTO" dan bukan antipattern. Komentar?

Aaron Digulla
sumber
Bukankah ini sama dengan Inspektur?
Gishu
1
Hmm .. baris ini 'kelas yang diuji mencoba menyembunyikan bahkan hal-hal yang perlu Anda uji' menunjukkan perebutan kekuasaan antara kelas dan tes. Jika harus diuji .. itu harus dapat diakses publik entah bagaimana .. melalui perilaku kelas / antarmuka .. ini entah bagaimana bau melanggar enkapsulasi
Gishu
2
npellow: Maven2 memiliki plugin untuk itu, bukan?
Aaron Digulla
1
Ini bukan benar-benar antipattern tes, itu pragmatisme untuk menangani kekurangan dalam kode yang diuji. Tentu saja lebih baik untuk memperbaiki kekurangan-kekurangan itu, tetapi itu tidak mungkin dalam kasus perpustakaan pihak ke-3.
Michael Borgwardt
1
IDK, pasti ada semacam efek samping. Saya akan menguji efek sampingnya. Tidak yakin apa yang Anda maksud tentang pengujian API pihak ketiga, saya berpendapat Anda harus membungkusnya dengan kode Anda sendiri yang dapat Anda uji digunakan dengan benar, kemudian uji integrasi kode itu terhadap API pihak ketiga. Tidak akan menguji kode pihak ketiga.
Joshua Cheek
26

Tes Tanpa Nama - Nick Pellow

Tes yang ditambahkan untuk mereproduksi bug tertentu dalam pelacak bug dan yang menurut penulis tidak menjamin nama sendiri. Alih-alih meningkatkan tes yang ada, kurang, tes baru dibuat disebut testForBUG123.

Dua tahun kemudian, ketika tes itu gagal, Anda mungkin perlu terlebih dahulu mencoba dan menemukan BUG-123 di pelacak bug Anda untuk mengetahui maksud tes.

npellow
sumber
7
Benar sekali. Tho yang sedikit lebih membantu daripada tes yang disebut "TestMethod"
NikolaiDante
8
kecuali bugtracker berubah, dan Anda kehilangan pelacak lama dan pengidentifikasi masalahnya ... jadi PROJECT-123 tidak lagi berarti apa-apa ....
Chii
25

Lambat Poke

Tes unit yang berjalan sangat lambat. Ketika pengembang menendang, mereka punya waktu untuk pergi ke kamar mandi, merokok, atau lebih buruk lagi, menendang tes sebelum mereka pulang pada akhir hari. (Src: posting James Carr )

alias tes yang tidak akan berjalan sesering yang seharusnya

Gishu
sumber
Beberapa tes berjalan lambat sesuai sifatnya. Jika Anda memutuskan untuk tidak menjalankan ini sesering yang lain, maka pastikan bahwa mereka setidaknya berjalan pada server CI sesering mungkin.
Chris Vest
Ini adalah pertanyaan yang jelas tetapi apa cara paling umum untuk memperbaikinya?
Topher Hunt
Ini awalnya tampak bermanfaat, kan?
Kev
1
@TopherHunt Biasanya tes lambat karena mereka memiliki beberapa ketergantungan mahal (yaitu filesystem, database). Caranya adalah dengan menganalisis dependensi sampai Anda melihat masalah, lalu dorong dependensi ke atas callstack. Saya menulis studi kasus di mana siswa saya mengambil unit-test suite mereka dari 77 detik menjadi 0,01 detik dengan memperbaiki ketergantungan mereka: github.com/JoshCheek/fast_tests
Joshua Cheek
20

Kupu-kupu

Anda harus menguji sesuatu yang berisi data yang berubah sepanjang waktu, seperti struktur yang berisi tanggal saat ini, dan tidak ada cara untuk memakukan hasilnya ke nilai tetap. Bagian buruknya adalah Anda sama sekali tidak peduli dengan nilai ini. Itu hanya membuat tes Anda lebih rumit tanpa menambahkan nilai apa pun.

Kelelawar sayapnya dapat menyebabkan badai di sisi lain dunia. - Edward Lorenz, The Butterfly Effect

Aaron Digulla
sumber
Apa anti-pola di sini: Seperti apa tes ini? Apakah ada perbaikan? Apakah ada keuntungan yang dapat diperdebatkan untuk pengujian-kode untuk faktor keluar dari ketergantungan seperti System.DateTime.Now, selain memiliki tes unit yang lebih sederhana atau lebih deterministik?
Merlyn Morgan-Graham
1
Di Jawa, contohnya adalah memanggil toString()objek yang tidak menimpa metode. Itu akan memberi Anda ID objek yang tergantung pada alamat memori. Atau toString()berisi kunci utama objek dan yang berubah setiap kali Anda menjalankan tes. Ada tiga cara untuk memperbaikinya: 1. Ubah kode yang Anda uji, 2. gunakan regexp untuk menghapus bagian variabel dari hasil pengujian atau 3. gunakan alat yang kuat untuk menimpa layanan sistem untuk membuatnya mengembalikan hasil yang dapat diprediksi.
Aaron Digulla
Penyebab yang mendasari anti-pola ini adalah bahwa kode yang sedang diuji tidak peduli seberapa besar upaya untuk mengujinya. Jadi keinginan pengembang adalah sayap kupu-kupu yang menyebabkan masalah di tempat lain.
Aaron Digulla
19

The Flickering Test (Sumber: Romilly Cocking)

Tes yang kadang-kadang gagal, bukan pada waktu tertentu, dan umumnya disebabkan oleh kondisi lomba dalam tes. Biasanya terjadi ketika menguji sesuatu yang tidak sinkron, seperti JMS.

Mungkin super set ke anti-pola ' Tunggu dan Lihat ' dan ' The Sleeper '.

Build gagal, oh well, jalankan build lagi. - Pengembang Anonim

Stuart
sumber
@Stuart - video yang harus dilihat menggambarkan ini adalah "Car Stalled - Try Now!" videosift.com/video/... Pola ini juga bisa disebut "Coba Sekarang!", atau hanya - "Tes Flakey"
npellow
1
Saya pernah menulis tes untuk PRGN yang memastikan distribusi yang tepat. Kadang-kadang, itu akan gagal secara acak. Sosok pergi. :-)
Chris Vest
1
Bukankah ini ujian yang bagus untuk dimiliki? Jika tes gagal, Anda harus melacak sumber masalahnya. Saya berkelahi dengan seseorang tentang tes yang gagal antara 9p dan tengah malam. Dia mengatakan itu acak / terputus-putus. Itu akhirnya ditelusuri ke bug yang berhubungan dengan zona waktu. Sosok pergi.
Trenton
@Christian Vest Hansen: tidak bisakah Anda menaburnya?
Andrew Grimm
@trenton Ini hanya tes yang bagus untuk dimiliki jika pengembang dapat diganggu untuk melacaknya, alih-alih hanya mengabaikannya (yang dapat mereka hindari, karena ia menghabiskan sebagian besar waktu).
Will Sheppard
19

Tunggu dan lihat

Tes yang menjalankan beberapa kode pengaturan dan kemudian perlu 'menunggu' waktu tertentu sebelum dapat 'melihat' apakah kode yang diuji berfungsi seperti yang diharapkan. Sebuah testMethod yang menggunakan Thread.sleep () atau yang setara pasti merupakan tes "Tunggu dan Lihat".

Biasanya, Anda dapat melihat ini jika tes ini menguji kode yang menghasilkan peristiwa eksternal ke sistem seperti email, permintaan http atau menulis file ke disk.

Tes semacam itu juga bisa menjadi Pahlawan Lokal karena akan GAGAL saat dijalankan pada kotak yang lebih lambat atau server CI yang kelebihan beban.

Anti-Pola Tunggu dan Lihat tidak harus disamakan dengan The Sleeper .

npellow
sumber
Hmm .. yah saya menggunakan yang seperti ini. bagaimana lagi saya bisa menguji kode multi-threaded?
Gishu
@ Gishu, apakah Anda benar-benar ingin unit menguji beberapa utas berjalan secara bersamaan? Saya mencoba hanya menguji unit apa pun metode run () tidak secara terpisah. Cara mudah untuk melakukan ini adalah dengan memanggil run () - yang akan memblokir, daripada memulai () dari unit test.
npellow
@Gishu menggunakan CountDownLatches, Semaphores, Ketentuan atau sejenisnya, agar utas saling memberi tahu kapan mereka dapat beralih ke tingkat berikutnya.
Chris Vest
Contoh: madcoderspeak.blogspot.com/2008/11/... Tombol Brew evt. Pengamat jajak pendapat pada interval dan meningkatkan peristiwa yang berubah .. dalam hal ini saya menambahkan penundaan sehingga jajak pendapat mendapat kesempatan untuk berjalan sebelum tes keluar.
Gishu
Saya pikir tautan kartunnya rusak.
Andrew Grimm
17

Fixture Bersama yang Tidak Pantas - Tim Ottinger
Beberapa test case dalam fixture test bahkan tidak menggunakan atau membutuhkan pengaturan / penghancuran. Sebagian karena inersia pengembang untuk membuat fixture tes baru ... lebih mudah hanya menambahkan satu lagi test case ke tumpukan

Gishu
sumber
1
Mungkin juga bahwa kelas yang diuji mencoba melakukan terlalu banyak.
Mike Two
16

Raksasa

Sebuah unit test yang, meskipun secara valid menguji objek yang sedang diuji, dapat menjangkau ribuan garis dan berisi banyak kasus uji. Ini bisa menjadi indikator bahwa sistem yang diuji adalah Obyek Tuhan (posting James Carr).

Tanda pasti untuk yang satu ini adalah tes yang mencakup lebih dari beberapa baris kode. Seringkali, tes ini sangat rumit sehingga mulai mengandung bug dari perilaku sendiri atau serpihan.

Gishu
sumber
15

Saya akan percaya ketika saya melihat beberapa flashing GUI
. Fiksasi / obsesi yang tidak sehat dengan menguji aplikasi melalui GUI-nya 'seperti pengguna yang sebenarnya'

Menguji aturan bisnis melalui GUI adalah bentuk penggabungan yang mengerikan . Jika Anda menulis ribuan tes melalui GUI, dan kemudian mengubah GUI Anda, ribuan tes gagal.
Sebaliknya, uji hanya hal-hal GUI melalui GUI, dan gabungkan GUI ke sistem dummy daripada sistem nyata, ketika Anda menjalankan tes tersebut. Uji aturan bisnis melalui API yang tidak melibatkan GUI. - Bob Martin

"Anda harus mengerti bahwa melihat adalah percaya, tetapi juga tahu bahwa percaya adalah melihat." - Denis Waitley

Gishu
sumber
1
Jika Anda berpikir menginstal GUI salah, saya melihat seseorang yang menulis tes jUnit yang memulai GUI dan membutuhkan interaksi pengguna untuk melanjutkan. Itu menggantung sisa test suite. Begitu banyak untuk otomatisasi uji!
Spoike
Saya tidak setuju. Menguji GUI memang sulit, tetapi mereka juga merupakan sumber kesalahan. Tidak mengujinya hanya malas.
Ray
3
intinya di sini adalah bahwa Anda tidak harus menguji GUI melainkan bahwa Anda tidak boleh menguji hanya melalui GUI. Anda dapat melakukan pengujian 'tanpa kepala' dengan GUI. Jaga agar GUI setipis mungkin - gunakan rasa MVP - Anda bisa lolos tanpa mengujinya sama sekali. Jika Anda menemukan bahwa Anda memiliki bug yang muncul di lapisan GUI yang tipis sepanjang waktu, tutuplah dengan tes .. tetapi sebagian besar waktu, saya tidak merasa sepadan dengan usaha. Kesalahan 'kabel' GUI biasanya lebih mudah untuk memperbaiki ...
Gishu
@Spoike: Tes manual yang dipandu tidak buruk, juga tidak menggunakan jUnit (atau kerangka pengujian unit lainnya) untuk menggerakkan pengujian otomatis yang bukan tes unit. Anda seharusnya tidak menempatkan mereka dalam proyek yang sama, atau memperlakukan mereka seperti tes unit (misalnya berjalan terus-menerus, atau setelah setiap build)
Merlyn Morgan-Graham
1
@ MerlynMorgan-Graham Saya setuju, dan saya tidak bermaksud bahwa Anda tidak boleh menguji GUI. Keyakinan yang dipegang oleh anggota tim bahwa tidak masalah mencampur tes manual dengan yang otomatis, mengganggu saya. Saya menemukan kemudian, itu adalah cara terbaik untuk membuat semua orang yang tidak terbiasa dengan TDD berhenti menggunakannya. Saya menemukan bahwa pencampuran tes fungsional (yang volatile) dengan tes unit (yang seharusnya stabil) buruk jika Anda ingin mengikuti proses TDD.
Spoike
14

The Sleeper, alias Gunung Vesuvius - Nick Pellow

Tes yang diperuntukkan bagi GAGAL pada waktu dan tanggal tertentu di masa depan. Ini sering disebabkan oleh batas yang salah saat memeriksa kode pengujian yang menggunakan objek Tanggal atau Kalender. Terkadang, tes mungkin gagal jika dijalankan pada waktu yang sangat spesifik, seperti tengah malam.

'The Sleeper' tidak perlu bingung dengan anti-pola ' Tunggu dan Lihat '.

Kode itu akan diganti jauh sebelum tahun 2000 - Banyak pengembang pada tahun 1960

npellow
sumber
Saya lebih suka menyebutnya Volcano yang tidak aktif :) .. tapi saya tahu apa yang Anda bicarakan .. mis. Tanggal yang dipilih sebagai tanggal di masa depan untuk ujian pada saat penulisan akan menjadi tanggal sekarang / masa lalu ketika tanggal tersebut berlalu .. melanggar tes. Bisakah Anda memposting contoh .. hanya untuk menggambarkan ini.
Gishu
@Gishu - +1. Saya berpikiran sama, tetapi tidak bisa memutuskan di antara keduanya. Saya memperbarui judul untuk membuat ini sedikit lebih jelas;)
npellow
11

Pohon Mati

Sebuah tes dimana sebuah rintisan dibuat, tetapi tes itu tidak ditulis.

Saya sebenarnya melihat ini dalam kode produksi kami:

class TD_SomeClass {
  public void testAdd() {
    assertEquals(1+1, 2);
  }
}

Aku bahkan tidak tahu harus berpikir apa tentang itu.

Yang Mulia Gonzo
sumber
8
:) - juga dikenal sebagai Backdoor Proses Kepatuhan Proses.
Gishu
1
Kami memiliki contoh tentang hal ini baru-baru ini dalam pengujian dan metode-pengujian yang telah diulang berulang kali. Setelah beberapa iterasi, tes menjadi panggilan ke metode-di-tes. Dan karena metodenya sekarang kembali batal, tidak ada pernyataan untuk ditegaskan. Jadi pada dasarnya, tes itu hanya memastikan metode tidak membuang pengecualian. Tidak masalah jika itu benar-benar melakukan sesuatu yang bermanfaat atau benar. Saya menemukannya dalam ulasan kode dan bertanya, "Jadi ... apa yang akan kami uji di sini?"
Marvo
11

dapatkan sedikit dari ini hari ini:

Lantai basah :
Tes menciptakan data yang bertahan di suatu tempat, tetapi tes tidak membersihkan saat selesai. Ini menyebabkan tes (tes yang sama, atau mungkin tes lain) gagal pada tes berikutnya .

Dalam kasus kami, tes meninggalkan file tergeletak di dir "temp", dengan izin dari pengguna yang menjalankan tes pertama kali. Ketika pengguna yang berbeda mencoba menguji pada mesin yang sama: boom. Dalam komentar di situs James Carr, Joakim Ohlrogge menyebut ini sebagai "Pekerja Ceroboh", dan itu adalah bagian dari inspirasi untuk "Generous Leftovers". Saya suka nama saya untuk itu lebih baik (kurang menghina, lebih akrab).

Zac Thompson
sumber
Anda dapat menggunakan aturan-folder-sementara junit untuk menghindari lantai yang basah.
DaveFar
Jenis ini berhubungan dengan pola anti Integrasi Berkelanjutan. Dalam CI, setiap pengembang harus memiliki ruang kerja dan sumber dayanya sendiri, dan mesin yang dibangun haruslah lingkungannya sendiri juga. Maka Anda menghindari hal-hal seperti masalah izin (atau mungkin Anda akhirnya menyembunyikannya sehingga hanya muncul dalam produksi.)
Marvo
11

The Cuckoo - Frank Carver
Sebuah unit test yang duduk dalam sebuah case uji dengan beberapa yang lain, dan menikmati proses setup yang sama (berpotensi panjang) seperti tes lain dalam case test, tetapi kemudian membuang beberapa atau semua artefak dari setup dan menciptakan sendiri.
Gejala Lanjutan: Jadwal yang Tidak Pantas Dibagikan

Gishu
sumber
10

The Secret Catcher - Frank Carver
Sebuah tes yang pada pandangan pertama tampaknya tidak melakukan pengujian, karena tidak adanya penegasan. Tapi "Iblis ada dalam perincian" .. tes ini benar-benar mengandalkan pengecualian yang akan dilempar dan mengharapkan kerangka pengujian untuk menangkap pengecualian dan melaporkannya kepada pengguna sebagai kegagalan.

[Test]
public void ShouldNotThrow()
{
   DoSomethingThatShouldNotThrowAnException();
}
Gishu
sumber
2
Ini sebenarnya bisa menjadi tes yang valid, menurut saya - terutama sebagai tes regresi.
Ilja Preuß
maaf lagi bingung dengan Silent catcher ... unit test harus menyatakan maksud dengan jelas tentang apa yang sedang diuji daripada mengatakan 'ini harus bekerja' .. (+1 tp ada sesuatu yang lebih baik daripada tidak sama sekali. esp jika Anda dalam regresi warisan negara)
Gishu
1
Dalam jenis tes ini, saya setidaknya menangkap Pengecualian dan menetapkannya ke variabel. Maka saya tegaskan untuk tidak nol.
Thomas Eyde
4
Beberapa kerangka kerja memiliki Assert.DoesNotThrow(SomeDelegateType act)pernyataan gaya yang dapat digunakan secara khusus dalam kasus-kasus seperti ini. Saya menemukan ini kurang kotor daripada memiliki test case yang berhasil ketika konstruktor mengembalikan non-nol, tetapi gagal ketika konstruktor melempar. Konstruktor tidak akan pernah mengembalikan nol. (Catatan: hanya berlaku untuk bahasa di mana konstruktor dijamin untuk mengembalikan non-null)
Merlyn Morgan-Graham
10

Perusak Lingkungan

Tes 'unit' yang untuk berbagai 'persyaratan' mulai tumpah ke lingkungannya, menggunakan dan mengatur variabel / port lingkungan. Menjalankan dua tes ini secara bersamaan akan menyebabkan pengecualian 'port tidak tersedia' dll.

Tes ini akan berselang, dan membuat pengembang mengatakan hal-hal seperti 'jalankan saja lagi'.

Salah satu solusi yang pernah saya lihat adalah memilih nomor port secara acak untuk digunakan. Ini mengurangi kemungkinan konflik, tetapi jelas tidak menyelesaikan masalah. Jadi jika Anda bisa, selalu mengejek kodenya sehingga tidak benar-benar mengalokasikan sumber daya yang tidak dapat dibagi.

gcrain
sumber
@ grain .. tes harus deterministik. IMO pendekatan yang lebih baik adalah dengan menggunakan port 'terkenal di tim' untuk pengujian dan pembersihan sebelum dan sesudah pengujian dengan benar sehingga selalu tersedia ...
Gishu
1
@ gishu - masalahnya bukan karena tidak ada metode setup () dan teardown () untuk menangani penggunaan port ini. masalahnya misalnya menjalankan server CI, dan beberapa versi pengujian berjalan pada saat yang sama, mencoba menggunakan nomor port yang sama, yang di-hardcoded-in-the-test
gcrain
10

Tes Turing

Sebuah testcase secara otomatis dihasilkan oleh beberapa alat mahal yang memiliki banyak, banyak pernyataan yang diperoleh dari kelas yang diuji menggunakan beberapa analisis aliran data yang terlalu pintar setengahnya. Membuai pengembang menjadi rasa percaya diri yang salah bahwa kode mereka diuji dengan baik, membebaskan mereka dari tanggung jawab merancang dan mempertahankan tes berkualitas tinggi. Jika mesin dapat menulis tes untuk Anda, mengapa mesin itu tidak bisa mengeluarkan jari dan menulis aplikasi itu sendiri?

Halo bodoh - Komputer terpintar di dunia hingga murid baru (dari komik Amiga lama).

bhumphrey
sumber
10

Tes Tiang Kaki Empat Puluh

Takut terlalu dekat dengan kelas yang mereka coba uji, tes ini bertindak dari kejauhan, dipisahkan oleh lapisan abstraksi yang tak terhitung jumlahnya dan ribuan baris kode dari logika yang mereka periksa. Karena itu mereka sangat rapuh, dan rentan terhadap segala macam efek samping yang terjadi pada perjalanan epik ke dan dari kelas yang diminati.

bhumphrey
sumber
9

Serupa

Untuk menguji sesuatu, Anda harus menyalin bagian dari kode yang sedang diuji ke kelas baru dengan nama dan paket yang sama dan Anda harus menggunakan sihir classpath atau classloader kustom untuk memastikan itu terlihat terlebih dahulu (sehingga salinan Anda diambil naik).

Pola ini menunjukkan sejumlah dependensi tersembunyi yang tidak sehat yang tidak dapat Anda kendalikan dari tes.

Saya melihat wajahnya ... wajah saya! Itu seperti cermin tetapi membuat darah saya membeku.

Aaron Digulla
sumber
7

Mother Hen - Frank Carver
Pengaturan umum yang jauh lebih banyak dari yang dibutuhkan oleh test case yang sebenarnya. Misalnya membuat semua jenis struktur data kompleks yang dihuni dengan nilai-nilai yang tampaknya penting dan unik ketika tes hanya menegaskan ada atau tidak adanya sesuatu.
Gejala Lanjutan: Jadwal yang Tidak Pantas Dibagikan

Saya tidak tahu apa fungsinya ... Saya tetap menambahkannya, untuk berjaga-jaga. - Pengembang Anonim

Gishu
sumber
7

Ujilah Semuanya

Saya tidak percaya ini belum disebutkan sampai sekarang, tetapi tes tidak boleh melanggar Prinsip Tanggung Jawab Tunggal .

Saya telah menemukan ini berkali-kali, tes yang melanggar aturan ini menurut definisi adalah mimpi buruk untuk dipertahankan.

thegreendroid
sumber
6

Pemukul baris

Pada tes tampilan pertama mencakup semuanya dan alat cakupan kode mengkonfirmasikannya dengan 100%, tetapi pada kenyataannya tes hanya mengenai kode tanpa analisis output.

kode cakupan-vs-terjangkau

Ruslan Dzhabbarov
sumber