Berapa banyak tes per metode?
Yah maksimum teoritis dan sangat tidak praktis adalah kompleksitas N-Path (anggap semua tes mencakup cara yang berbeda melalui kode;)). Minimal adalah SATU! Per metode publik yaitu, ia tidak menguji detail implementasi, hanya perilaku eksternal suatu kelas (mengembalikan nilai & memanggil objek lain).
Anda mengutip:
* Dan pemikiran menguji setiap metode Anda dengan metode pengujiannya sendiri (dalam hubungan 1-1) akan menggelikan. *
dan kemudian bertanya:
Jadi, jika membuat tes untuk setiap metode adalah 'laughable', bagaimana / kapan Anda memilih untuk apa Anda menulis tes?
Tapi saya pikir Anda salah paham tentang penulis di sini:
Gagasan memiliki one test method
per one method in the class to test
adalah apa yang penulis sebut "menggelikan".
(Setidaknya bagi saya) Ini bukan tentang 'kurang' ini tentang 'lebih banyak'
Jadi izinkan saya ulangi seperti saya memahaminya:
Dan pemikiran menguji setiap metode Anda dengan HANYA SATU METODE (metode pengujian sendiri dalam hubungan 1-1) akan menggelikan.
Mengutip penawaran Anda lagi:
Ketika Anda menyadari bahwa ini semua tentang menentukan perilaku dan bukan menulis tes, sudut pandang Anda bergeser.
Ketika Anda berlatih TDD Anda tidak berpikir :
Saya punya metode calculateX($a, $b);
dan perlu tes testCalculcateX
yang menguji SEMUA tentang metode ini.
Apa yang dikatakan TDD kepada Anda adalah untuk berpikir tentang apa kode Anda HARUS LAKUKAN :
Saya perlu menghitung lebih besar dari dua nilai ( test case pertama! ) Tetapi jika $ a lebih kecil dari nol maka ia harus menghasilkan kesalahan ( case test kedua! ) Dan jika $ b lebih kecil dari nol seharusnya .... ( test case ketiga! ) dan seterusnya.
Anda ingin menguji perilaku, bukan hanya metode tunggal tanpa konteks.
Dengan begitu Anda mendapatkan test suite yang merupakan dokumentasi untuk kode Anda dan BENAR-BENAR menjelaskan apa yang diharapkan untuk dilakukan, mungkin bahkan mengapa :)
Bagaimana cara Anda memutuskan bagian kode mana yang Anda buat untuk pengujian unit?
Ya, segala sesuatu yang berakhir di repositori atau di dekat produksi memerlukan tes. Saya tidak berpikir penulis kutipan Anda tidak akan setuju dengan itu ketika saya mencoba untuk menyatakan di atas.
Jika Anda tidak memiliki tes untuk itu akan lebih sulit (lebih mahal) untuk mengubah kode, terutama jika bukan Anda yang membuat perubahan.
TDD adalah cara untuk memastikan bahwa Anda memiliki tes untuk SEMUA tetapi selama Anda MENULIS tes itu baik-baik saja. Biasanya menulisnya pada hari yang sama membantu karena Anda tidak akan melakukannya nanti, bukan? :)
Tanggapan terhadap komentar:
sejumlah metode yang layak tidak dapat diuji dalam konteks tertentu karena mereka tergantung atau tergantung pada metode lain
Ada tiga hal yang bisa disebut metode ini:
Metode publik dari kelas lain
Kita dapat mengejek kelas lain sehingga kita telah menetapkan status di sana. Kami mengendalikan konteks sehingga tidak masalah di sana.
* Metode yang dilindungi atau pribadi pada yang sama *
Apa pun yang bukan bagian dari API umum suatu kelas tidak diuji secara langsung, biasanya.
Anda ingin menguji perilaku dan bukan implementasi dan jika kelas melakukan semua itu berfungsi dalam satu metode publik besar atau dalam banyak metode yang lebih kecil yang dilindungi disebut implementasi . Anda ingin dapat MENGUBAH metode yang dilindungi tersebut tanpa menyentuh tes Anda. Karena tes Anda akan rusak jika kode Anda berubah perilaku! Untuk itulah tes Anda, untuk memberi tahu Anda ketika Anda memecahkan sesuatu :)
Metode publik di kelas yang sama
Itu tidak sering terjadi bukan? Dan jika memang suka dalam contoh berikut ada beberapa cara untuk menangani ini:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Bahwa setter ada dan bukan bagian dari metode eksekusi tanda tangan adalah topik lain;)
Apa yang bisa kita uji di sini adalah jika eksekusi tidak meledak ketika kita menetapkan nilai yang salah. Itu setBla
melempar pengecualian ketika Anda melewatkan string dapat diuji secara terpisah, tetapi jika kami ingin menguji bahwa kedua nilai yang diizinkan (12 & 14) tidak bekerja BERSAMA (untuk alasan apa pun) daripada satu kasus uji.
Jika Anda menginginkan test suite "baik", Anda dapat, di php, mungkin (!) Menambahkan @covers Stuff::execute
anotasi untuk memastikan Anda hanya menghasilkan cakupan kode untuk metode ini dan hal-hal lain yang baru saja setup perlu diuji secara terpisah (sekali lagi, jika kamu menginginkan itu).
Jadi intinya adalah: Mungkin Anda harus membuat beberapa dunia di sekitarnya terlebih dahulu tetapi Anda harus dapat menulis kasus uji yang bermakna yang biasanya hanya menjangkau satu atau mungkin dua fungsi nyata (setter tidak dihitung di sini). Sisanya dapat diejek atau di tes terlebih dahulu dan kemudian diandalkan (lihat @depends
)
* Catatan: Pertanyaannya dimigrasikan dari SO dan awalnya tentang PHP / PHPUnit, itu sebabnya contoh kode dan referensi dari dunia php, saya pikir ini juga berlaku untuk bahasa lain karena phpunit tidak berbeda jauh dari yang lain xUnit kerangka kerja pengujian.