Saya ingin belajar sendiri untuk menggunakan pendekatan TDD dan saya punya proyek yang ingin saya kerjakan untuk sementara waktu. Itu bukan proyek besar jadi saya pikir itu akan menjadi kandidat yang baik untuk TDD. Namun, saya merasa ada sesuatu yang salah. Izinkan saya memberi contoh:
Pada tingkat tinggi, proyek saya merupakan tambahan untuk Microsoft OneNote yang memungkinkan saya melacak dan mengelola Proyek dengan lebih mudah. Sekarang, saya juga ingin menjaga logika bisnis untuk ini sebagai dipisahkan dari OneNote mungkin jika saya memutuskan untuk membangun penyimpanan kustom saya sendiri dan kembali suatu hari nanti.
Pertama saya mulai dengan tes penerimaan kata dasar sederhana untuk menguraikan apa yang saya ingin fitur pertama saya lakukan. Itu terlihat seperti ini (mematikannya untuk singkatnya):
- Klik pengguna membuat proyek
- Jenis pengguna dalam judul proyek
- Verifikasi bahwa proyek dibuat dengan benar
Melewati hal-hal UI dan beberapa perencanaan perantara saya datang ke unit test pertama saya:
[TestMethod]
public void CreateProject_BasicParameters_ProjectIsValid()
{
var testController = new Controller();
Project newProject = testController(A.Dummy<String>());
Assert.IsNotNull(newProject);
}
Sejauh ini baik. Merah, hijau, refactor, dll. Baiklah sekarang sebenarnya perlu menyimpan barang. Memotong beberapa langkah di sini saya berakhir dengan ini.
[TestMethod]
public void CreateProject_BasicParameters_ProjectMatchesExpected()
{
var fakeDataStore = A.Fake<IDataStore>();
var testController = new Controller(fakeDataStore);
String expectedTitle = fixture.Create<String>("Title");
Project newProject = testController(expectedTitle);
Assert.AreEqual(expectedTitle, newProject.Title);
}
Saya masih merasa baik pada saat ini. Saya belum memiliki penyimpanan data yang konkret, tetapi saya membuat antarmuka seperti yang saya perkirakan akan terlihat.
Saya akan melewati beberapa langkah di sini karena posting ini sudah cukup lama, tetapi saya mengikuti proses yang sama dan akhirnya saya mendapatkan tes ini untuk penyimpanan data saya:
[TestMethod]
public void SaveNewProject_BasicParameters_RequestsNewPage()
{
/* snip init code */
testDataStore.SaveNewProject(A.Dummy<IProject>());
A.CallTo(() => oneNoteInterop.SavePage()).MustHaveHappened();
}
Ini bagus sampai saya mencoba mengimplementasikannya:
public String SaveNewProject(IProject project)
{
Page projectPage = oneNoteInterop.CreatePage(...);
}
Dan ada masalah di mana "..." berada. Saya menyadari sekarang pada titik INI bahwa CreatePage memerlukan ID bagian. Saya tidak menyadari hal ini kembali ketika saya berpikir pada level controller karena saya hanya peduli dengan pengujian bit yang relevan dengan controller. Namun, jauh-jauh di sini saya sekarang menyadari bahwa saya harus meminta pengguna untuk lokasi menyimpan proyek. Sekarang saya harus menambahkan ID lokasi ke datastore, lalu menambahkan satu ke proyek, lalu menambahkan satu ke controller, dan menambahkannya ke SEMUA tes yang sudah ditulis untuk semua hal itu. Ini menjadi sangat cepat dan membosankan dan saya merasa seperti saya akan menangkap ini lebih cepat jika saya membuat sketsa desain sebelumnya daripada membiarkannya dirancang selama proses TDD.
Bisakah seseorang tolong jelaskan kepada saya jika saya melakukan kesalahan dalam proses ini? Apakah ada jenis refactoring yang bisa dihindari? Atau ini biasa? Jika itu umum, adakah cara untuk membuatnya lebih tidak menyakitkan?
Terima kasih semuanya!
sumber
Jawaban:
Meskipun TDD (benar) disebut-sebut sebagai cara untuk merancang dan mengembangkan perangkat lunak Anda, masih merupakan ide yang baik untuk memikirkan desain dan arsitektur sebelumnya. IMO, "membuat sketsa desain sebelumnya" adalah permainan yang adil. Namun, sering kali ini akan berada pada level yang lebih tinggi daripada keputusan desain yang akan Anda tuntun melalui TDD.
Memang benar bahwa ketika segalanya berubah, Anda biasanya harus memperbarui tes. Tidak ada cara untuk menghilangkan ini sepenuhnya, tetapi ada beberapa hal yang dapat Anda lakukan untuk membuat tes Anda kurang rapuh dan meminimalkan rasa sakit.
Sebisa mungkin, jauhkan detail implementasi dari tes Anda. Ini berarti hanya menguji melalui metode publik, dan jika memungkinkan mendukung verifikasi berbasis interaksi negara . Dengan kata lain, jika Anda menguji hasil sesuatu daripada langkah - langkah untuk sampai ke sana, tes Anda seharusnya tidak terlalu rapuh.
Minimalkan duplikasi dalam kode pengujian Anda, sama seperti yang Anda lakukan dalam kode produksi. Posting ini adalah referensi yang bagus. Dalam contoh Anda, sepertinya menyakitkan untuk menambahkan
ID
properti ke konstruktor Anda karena Anda memanggil konstruktor secara langsung dalam beberapa tes yang berbeda. Sebagai gantinya, cobalah mengekstraksi pembuatan objek ke metode atau menginisialisasi sekali untuk setiap tes dalam metode inisialisasi tes.sumber
Mungkin tidak
Di satu sisi, TDD bekerja dengan baik, memberi Anda tes otomatis saat Anda membangun fungsionalitas, dan segera rusak ketika Anda harus mengubah antarmuka.
Di sisi lain, mungkin jika Anda mulai dengan fitur tingkat tinggi (SaveProject) alih-alih fitur tingkat rendah (CreateProject), Anda akan melihat parameter yang hilang lebih cepat.
Kemudian lagi, mungkin Anda tidak akan melakukannya. Ini adalah eksperimen yang tidak dapat diulang.
Tetapi jika Anda mencari pelajaran untuk waktu berikutnya: mulailah dari atas. Dan pikirkan desainnya sebanyak yang Anda mau dulu.
sumber
https://frontendmasters.com/courses/angularjs-and-code-testability/ Dari sekitar 2:22:00 sampai akhir (sekitar 1 jam). Maaf bahwa videonya tidak gratis, tetapi saya belum menemukan yang gratis menjelaskannya dengan baik.
Salah satu presentasi terbaik dari penulisan kode yang dapat diuji adalah dalam pelajaran ini. Ini adalah kelas AngularJS, tetapi bagian pengujian ada di sekitar kode java, terutama karena apa yang dia bicarakan tidak ada hubungannya dengan bahasa, dan segala sesuatu yang berkaitan dengan menulis kode yang dapat diuji baik di tempat pertama.
Keajaibannya adalah menulis kode yang dapat diuji, daripada menulis tes kode. Ini bukan tentang menulis kode yang berpura-pura menjadi pengguna.
Dia juga menghabiskan waktu menulis spec dalam bentuk pernyataan uji.
sumber