Berlawanan dengan jawaban yang lain, penting untuk dicatat bahwa beberapa cara pengujian dapat menjadi rapuh ketika sistem yang diuji (SUT) di-refactored, jika pengujiannya adalah whitebox.
Jika saya menggunakan kerangka kerja mengejek yang memverifikasi urutan metode yang dipanggil pada tiruan (ketika urutan tidak relevan karena panggilan bebas efek samping); maka jika kode saya lebih bersih dengan panggilan metode tersebut dalam urutan yang berbeda dan saya refactor, maka pengujian saya akan rusak. Secara umum, mengejek dapat menyebabkan kerapuhan pada tes.
Jika saya memeriksa keadaan internal SUT saya dengan mengekspos anggota pribadi atau yang dilindungi (kita bisa menggunakan "teman" dalam visual basic, atau meningkatkan tingkat akses "internal" dan menggunakan "internalsvisibleto" dalam c #; dalam banyak bahasa OO, termasuk banyak c # a " test-specific-subclass " dapat digunakan) lalu tiba-tiba keadaan internal kelas akan menjadi masalah - Anda mungkin akan refactoring kelas sebagai kotak hitam, tetapi tes kotak putih akan gagal. Misalkan satu bidang digunakan kembali untuk mengartikan hal yang berbeda (bukan praktik yang baik!) Ketika SUT berubah status - jika kita membaginya menjadi dua bidang, kita mungkin perlu menulis ulang tes yang rusak.
Subclass uji-spesifik juga dapat digunakan untuk menguji metode yang dilindungi - yang dapat berarti bahwa refactor dari sudut pandang kode produksi merupakan perubahan besar dari sudut pandang kode uji. Memindahkan beberapa baris ke dalam atau keluar dari metode yang dilindungi mungkin tidak memiliki efek samping produksi, tetapi hancurkan tes.
Jika saya menggunakan " kait uji " atau kode kompilasi khusus uji atau kondisional lainnya, mungkin sulit untuk memastikan bahwa tes tidak rusak karena ketergantungan yang rapuh pada logika internal.
Jadi untuk mencegah agar tes tidak digabungkan dengan detail internal SUT yang intim, mungkin membantu untuk:
- Gunakan bertopik daripada tiruan, jika memungkinkan. Untuk info lebih lanjut lihat blog Fabio Periera tentang tes tautologis , dan blog saya tentang tes tautologis .
- Jika menggunakan tiruan, hindari memverifikasi urutan metode yang dipanggil, kecuali itu penting.
- Cobalah untuk menghindari memverifikasi keadaan internal SUT Anda - gunakan API eksternal jika memungkinkan.
- Cobalah untuk menghindari logika khusus tes dalam kode produksi
- Cobalah untuk menghindari penggunaan subclass khusus-tes.
Semua poin di atas adalah contoh kopling kotak putih yang digunakan dalam pengujian. Jadi untuk benar-benar menghindari tes melanggar refactoring, gunakan pengujian kotak hitam SUT.
Penafian: Untuk tujuan membahas refactoring di sini, saya menggunakan kata ini sedikit lebih luas untuk memasukkan perubahan implementasi internal tanpa efek eksternal yang terlihat. Beberapa puritan mungkin tidak setuju dan merujuk secara eksklusif ke buku Martin Fowler dan Kent Beck Refactoring - yang menggambarkan operasi atom refactoring.
Dalam praktiknya, kami cenderung mengambil langkah-langkah tanpa-melanggar yang sedikit lebih besar daripada operasi atom yang dijelaskan di sana, dan khususnya perubahan yang membuat kode produksi berperilaku identik dari luar mungkin tidak meninggalkan tes yang lulus. Tapi saya pikir itu adil untuk memasukkan "algoritma pengganti untuk algoritma lain yang memiliki perilaku identik" sebagai refactor, dan saya pikir Fowler setuju. Martin Fowler sendiri mengatakan bahwa refactoring dapat membatalkan tes:
Saat Anda menulis tes mockist, Anda menguji panggilan keluar SUT untuk memastikannya berbicara dengan baik kepada pemasoknya. Tes klasik hanya peduli tentang kondisi akhir - bukan bagaimana status itu diturunkan. Tes Mockist dengan demikian lebih digabungkan dengan implementasi metode. Mengubah sifat panggilan ke kolaborator biasanya menyebabkan tes mockist rusak.
[...]
Menggabungkan ke implementasi juga mengganggu refactoring, karena perubahan implementasi lebih mungkin untuk memecahkan tes daripada dengan pengujian klasik.
Fowler - Mengolok-olok bukan bertopik