Haruskah hasil yang diharapkan dari unit test hardcode, atau dapatkah mereka bergantung pada variabel yang diinisialisasi? Apakah hasil hardcoded atau dihitung meningkatkan risiko memperkenalkan kesalahan dalam unit test? Apakah ada faktor lain yang belum saya pertimbangkan?
Misalnya, yang mana dari dua ini adalah format yang lebih dapat diandalkan?
[TestMethod]
public void GetPath_Hardcoded()
{
MyClass target = new MyClass("fields", "that later", "determine", "a folder");
string expected = "C:\\Output Folder\\fields\\that later\\determine\\a folder";
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
[TestMethod]
public void GetPath_Softcoded()
{
MyClass target = new MyClass("fields", "that later", "determine", "a folder");
string expected = "C:\\Output Folder\\" + string.Join("\\", target.Field1, target.Field2, target.Field3, target.Field4);
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
EDIT 1: Menanggapi jawaban DXM, apakah opsi 3 solusi yang disukai?
[TestMethod]
public void GetPath_Option3()
{
string field1 = "fields";
string field2 = "that later";
string field3 = "determine";
string field4 = "a folder";
MyClass target = new MyClass(field1, field2, field3, field4);
string expected = "C:\\Output Folder\\" + string.Join("\\", field1, field2, field3, field4);
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
c#
unit-testing
Makanan Tangan
sumber
sumber
Jawaban:
Saya pikir hasil nilai yang dihitung menghasilkan kasus uji yang lebih kuat dan fleksibel. Juga dengan menggunakan nama variabel yang baik dalam ekspresi yang menghitung hasil yang diharapkan, jauh lebih jelas dari mana hasil yang diharapkan berasal dari tempat pertama.
Karena itu, dalam contoh spesifik Anda, saya TIDAK akan mempercayai metode "Softcoded" karena menggunakan SUT Anda (sistem yang diuji) sebagai input untuk perhitungan Anda. Jika ada bug di MyClass di mana bidang tidak disimpan dengan benar, pengujian Anda akan benar-benar lulus karena perhitungan nilai yang Anda harapkan akan menggunakan string yang salah seperti target.GetPath ().
Saran saya adalah untuk menghitung nilai yang diharapkan di tempat yang masuk akal, tetapi pastikan bahwa perhitungan tidak bergantung pada kode apa pun dari SUT itu sendiri.
Sebagai Tanggapan atas pembaruan OP terhadap respons saya:
Ya, berdasarkan pengetahuan saya tetapi pengalaman yang agak terbatas dalam melakukan TDD, saya akan memilih opsi # 3.
sumber
Bagaimana jika kodenya adalah sebagai berikut:
Contoh kedua Anda tidak akan menangkap bug, tetapi contoh pertama akan melakukannya.
Secara umum, saya akan merekomendasikan terhadap soft-coding karena dapat menyembunyikan bug. Sebagai contoh:
Bisakah Anda menemukan masalahnya? Anda tidak akan membuat kesalahan yang sama dalam versi kode-keras. Lebih sulit untuk mendapatkan perhitungan yang benar daripada nilai-nilai yang dikodekan. Itu sebabnya saya lebih suka bekerja dengan nilai-nilai kode-keras daripada yang kode-lunak.
Tapi ada beberapa pengecualian. Bagaimana jika kode Anda harus dijalankan di Windows dan Linux? Path tidak hanya harus berbeda, tetapi juga harus menggunakan separator path yang berbeda! Menghitung jalur menggunakan fungsi yang abstrak perbedaan antara mungkin masuk akal dalam konteks itu.
sumber
Menurut pendapat saya, kedua saran Anda kurang ideal. Cara ideal untuk melakukannya adalah yang ini:
Dengan kata lain, tes harus bekerja secara eksklusif berdasarkan input dan output objek, dan tidak didasarkan pada keadaan internal objek. Objek harus diperlakukan sebagai kotak hitam. (Saya mengabaikan masalah lain, seperti ketidaksesuaian menggunakan string. Bergabunglah dengan bukan Path.Combine, karena ini hanya sebuah contoh.)
sumber
target.Dispose(); Assert.IsTrue(target.IsDisposed);
(contoh yang sangat sederhana.)Ada dua aspek dalam diskusi:
1. Menggunakan target itu sendiri untuk test case
Pertanyaan pertama adalah harus / dapatkah Anda menggunakan kelas itu sendiri untuk mengandalkan dan menyelesaikan bagian dari pekerjaan dalam test stub? - Jawabannya adalah TIDAK karena, secara umum, Anda tidak boleh membuat asumsi tentang kode yang Anda uji. Jika ini tidak dilakukan dengan benar, seiring waktu bug menjadi kebal terhadap beberapa unit pengujian.
2. Hardcoding
haruskah Anda kode keras ? Sekali lagi jawabannya adalah Tidak . karena seperti perangkat lunak apa pun - pengkodean keras informasi menjadi sulit ketika berbagai hal berevolusi. Misalnya, ketika Anda ingin jalur di atas dimodifikasi lagi, Anda harus menulis unit tambahan atau terus memodifikasi. Metode yang lebih baik adalah menyimpan input dan tanggal evaluasi yang berasal dari konfigurasi terpisah yang dapat dengan mudah disesuaikan.
misalnya di sini adalah bagaimana saya akan memperbaiki rintisan tes.
sumber
Ada banyak konsep yang mungkin, buat beberapa contoh untuk melihat perbedaannya
Untuk meringkas: Secara umum tes hardcoded pertama Anda paling masuk akal bagi saya karena sederhana, langsung ke titik dll. Jika Anda memulai hardcoding jalan terlalu banyak hanya memasukkannya dalam metode setup.
Untuk pengujian terstruktur lebih lanjut di masa depan saya akan pergi untuk memeriksa sumber data sehingga Anda bisa menambahkan lebih banyak baris data jika Anda membutuhkan lebih banyak situasi pengujian.
sumber
Kerangka kerja pengujian modern memungkinkan Anda memberikan parameter untuk metode Anda. Saya akan memanfaatkannya:
Ada beberapa keuntungan untuk ini, dalam pandangan saya:
sumber