Cara menyusun tes unit untuk aplikasi GUI menggunakan C # dan NUnit


16

Saya diminta untuk melakukan proyek sampingan kecil untuk memasok aplikasi sederhana ke salah satu pelanggan kami. Biasanya saya akan mengerjakan kode back-end di mana saya memiliki semua kebutuhan pengujian saya tahu, dan saya belum memiliki kesenangan meragukan menulis tes untuk GUI, jadi agak tidak jelas bagi saya bagaimana saya harus mengatur kode pengujian dan alat untuk EXE.

Naluri pertama saya adalah hanya memasukkan tes dengan kode aplikasi, namun itu akan membutuhkan penyediaan sejumlah dependensi khusus tes, yang saya perintahkan untuk tidak dikirimkan ke pelanggan. Saya juga tidak dapat memeras uang tunai untuk alat uji tujuan dibangun, jadi saya harus menggunakan tools yang saya miliki di tangan ( StoryQ , RhinoMocks , dan NUnit), yang benar-benar harus lebih dari cukup untuk menguji perilaku aplikasi GUI sederhana. Jadi sejauh yang saya bisa lihat, ini membuat saya berusaha untuk mendapatkan keseimbangan yang baik antara menjaga desain benar-benar sederhana, atau sengaja melakukan rekayasa berlebihan demi pengujian. Sepertinya saya membangun aplikasi dengan logika bisnis di perpustakaan terpisah dan menguji terhadap perpustakaan seperti biasanya, atau menemukan beberapa mekanisme lain untuk memungkinkan saya menjalankan file tanpa merusak modul tambahan yang desain aplikasi tidak lakukan. sangat butuh.

Sunting:
Harap dicatat bahwa pertanyaan ini adalah tentang bagaimana menyusun hubungan antara NUnit dan executable saya - yang bertentangan dengan DLL - dan bukan tentang bagaimana memisahkan presentasi dan logika bisnis.
/ Edit

Jadi pertanyaan saya adalah:

  1. Apakah ada metode khusus / yang disarankan untuk mengonfigurasi aplikasi GUI sederhana dengan tes unit untuk memungkinkan saya memeriksa keadaan dan perilaku secara memadai, menggunakan alat yang saya miliki, dan tanpa menggunakan rekayasa berlebihan?
  2. Pernahkah saya melewatkan sesuatu yang mendasar tentang cara NUnit harus dipanggil / dikonfigurasikan ketika menguji EXE (sebagai lawan dari DLL)?
  3. Bisakah Anda memberikan atau mengarahkan saya ke arah contoh bagaimana mencapai semua ini?

Saya menyadari bahwa mungkin ada lebih dari satu cara untuk melakukan ini, jadi saya mencari pedoman implementasi spesifik berdasarkan pengalaman Anda.


NUnit tidak dirancang untuk menguji GUI secara langsung. Anda perlu memisahkan lapisan presentasi Anda (tampilan yaitu) dari data dan logika bisnis (model yaitu) sehingga Anda dapat menguji apa yang masuk ke tampilan Anda tanpa menggunakan tampilan.
Bernard

1
@ Brian Pertanyaan ini bukan tentang layering GUI untuk pengujian. Saya secara alami melapisi semua aplikasi saya - bahkan yang sepele - sehingga sebenarnya bukan masalah bagi saya. Saya telah mengedit pertanyaan yang sesuai, dan saya harap itu menghilangkan kesalahpahaman. :)
S.Robins

1
Tidak ada yang sangat rumit dalam hal pengujian unit di EXE. Anda hanya perlu menguji DLL referensi file EXE Anda, dan Anda baik untuk pergi.
whatsisname

Jawaban:


3

Saya menyebutkan dalam salah satu komentar saya untuk jawaban simoraman bahwa saya telah memikirkan beberapa cara untuk melakukan ini. Salah satu opsi saya mirip dengan saran dalam jawaban Jalayn untuk membuat proyek duplikat dan menghasilkan DLL, sementara ide saya yang lain adalah dengan hanya menautkan ke file dalam proyek di mana ada kode yang ingin saya uji. Meskipun kedua opsi dapat dibuat berfungsi, keduanya kurang ideal.

Dalam kasus kedua, saya harus mengacaukan dependensi unit kecuali jika saya benar-benar bisa memisahkan arsitektur untuk meminimalkan ketergantungan. Ini bagus untuk proyek yang lebih kecil, tetapi yang lebih besar dapat dengan mudah menjadi kekacauan nyata untuk dikelola. Namun resistensi terbesar saya terhadap opsi ini adalah tidak adanya pilihan. Tentu saya bisamulai bekerja, tetapi dengan demikian saya secara efektif perlu memecahkan enkapsulasi untuk menguji internal suatu perakitan langsung melalui sumber, daripada menguji melalui antarmuka publik, yang dalam pikiran saya adalah besar tidak boleh tidak. Demikian juga memiliki file proyek tambahan akan berarti upaya duplikasi dalam dua proyek sekaligus, atau menemukan cara untuk menambahkan pengaturan file proyek secara otomatis ke dua file sekaligus, atau ingat untuk menyalin dan mengganti nama bidang proyek setiap kali saya membangun. Ini dapat diotomasi pada build server mungkin, tetapi akan merepotkan untuk mengelola dalam IDE. Sekali lagi, ini bisa bekerja, tetapi itu adalah kludge yang terbaik, dan gangguan yang lebih buruk jika Anda salah.

Tampaknya cara terbaik adalah melakukan seperti apa nama komentar mengomentari pertanyaan saya, dan hanya memasukkan EXE sebagai referensi dalam proyek pengujian. Ternyata EXE secara efektif diperlakukan dengan cara yang sama seperti DLL dalam kasus ini, dan saya dapat mengakses semua kelas berlapis saya untuk menguji apa pun yang mengapung perahu saya.


2

Saya pikir itu:

  • Kode uji bisnis Anda harus dalam proyek terpisah, menguji pustaka kode bisnis Anda.
  • Kode tes GUI Anda harus dalam proyek yang terpisah, menguji perpustakaan GUI Anda. Sekarang, bagaimana membangun pustaka GUI alih-alih yang dapat dieksekusi, saya mencoba menjawabnya nanti.
  • Jika Anda memiliki my.namespace.biz.MyClass, kelas tes Anda harus my.namespace.biz.MyClassTest (atau MyClassTestCase).
  • Jika Anda ingin menguji kode yang ditemukan di target yang dapat dieksekusi, maka Anda harus memiliki pengaturan yang membangun EXE, dan pengaturan lain yang membangun perpustakaan (DLL) yang merupakan salah satu yang akan Anda luncurkan terhadap pengujian Anda.

Ini adalah aturan yang ingin saya ikuti, apakah itu Java atau C # (kecuali tentu saja tidak ada masalah EXE dengan Java :-))

Adapun cara mengkonfigurasi lingkungan pengujian Anda, menurut saya Anda setidaknya memiliki dua pilihan ini:

Menggunakan MSBuild

Buat tiruan dari file .proj Anda (katakanlah myproject-as-dll.proj ). Ubah OutputTypefile yang dikloning dari " EXE" menjadi "Library ". Menggunakan perintah MSBuild Anda sekarang dapat menghasilkan perpustakaan yang dapat Anda tetapkan sebagai referensi ke proyek Anda yang berisi NUnit test case.

Tampaknya mungkin bagi saya, tetapi saya tidak pernah menggunakannya sejujur ​​itu, jadi saya tidak yakin. Plus, Anda mungkin tidak memiliki MSBuild di server uji integrasi Anda, dan saya tidak tahu apakah itu dapat dipisahkan dari Visual Studio ...

Menggunakan NAnt

Jika Anda tidak terbiasa dengan NAnt, Anda harus mencari cara mengkonfigurasi proyek Anda dengan itu. Mungkin lihat ini , ini sudah agak tua tetapi penulis telah berkomentar file NAnt dan Jika menemukannya cukup jelas ( Edit: memeriksa file-nya lebih detail, saya menemukan file konfigurasinya sangat dapat digunakan kembali ). Ia juga melakukan lebih dari sekadar membangun, karena ia menjalankan uji kasus dan meluncurkan alat cakupan kode. Sekarang, saya akui saya tidak pernah menggunakan NAnt, bertentangan dengan rekan Java dan ayahnya "Sem" yang saya gunakan banyak tetapi saya melihat itu hal yang sama dan saya pikir itu tidak sulit untuk dipelajari.

Dengan alat itu, Anda dapat membuat konfigurasi yang memungkinkan Anda untuk:

  • bangun semua proyek Anda (logika bisnis, GUI, dll.) menjadi perpustakaan yang terpisah
  • bangun proyek pengujian Anda
  • meluncurkan tes (bagian tertentu dilakukan dengan tugas NUnit2 ).
  • periksa cakupan kode Anda dengan tugas NCover .

Dengan sedikit lebih banyak kode, Anda bahkan dapat:

  • melakukan penerapan malam hari di server integrasi Anda
  • jika NAnt tersedia di server integrasi Anda, luncurkan tes integrasi setiap malam dengan bantuan tugas yang dijadwalkan

Semua dilakukan tanpa mengubah apa pun di file Visual Studio Anda. Dan, sungguh, itu tidak terlihat seperti rekayasa berlebihan bagi saya, itu hanya satu file. Mungkin butuh Anda satu, mungkin dua hari untuk membuat semuanya bekerja tetapi Anda akan memiliki pengaturan yang bagus menurut saya.

Terakhir, saya akan memberikan kepada klien semua yang diperlukan untuk membangun, menguji, dan menjalankan proyek. Saya cenderung berpikir itu menunjukkan profesionalisme Anda dan fakta bahwa Anda menulis kode dengan kualitas dalam pikiran Anda (yang menurut saya Anda lakukan karena Anda sedang mencari solusi elegan)


0

Hanya karena proyek kecil (awalnya) tidak berarti arsitektur yang tepat adalah rekayasa berlebihan. Fakta bahwa Anda ingin menulis tes memberi tahu bahwa proyek Anda bukan hack sekali-kali yang sepele.

Anda tidak menyebutkan GUI-Framework mana yang Anda gunakan. WPF MVVM (Model-View-ViewModel) bagus dan memungkinkan Anda untuk menulis tes untuk semua logika dengan mudah. Dengan WinForms, saya telah mendengar hal-hal baik tentang MVP (Model-View-Presenter)


Saya menulis tes untuk semua kode yang saya tulis. Bahkan hal-hal yang mungkin Anda temukan sepele. Satu-satunya waktu saya tidak menulis tes adalah ketika saya lonjakan. Dalam hal ini, saya mengirim utilitas satu ke pelanggan, jadi pengujian lebih dari sekadar kemewahan, itu adalah persyaratan untuk memenuhi standar kualitas kami. Dalam hal "over engineering", ini bukan pilihan antara arsitektur yang baik atau buruk, tetapi menghindari kebutuhan untuk memaksakan pelapisan tambahan yang tidak diperlukan dalam hal ini karena aplikasi ini adalah satu-satunya tujuan dengan siklus hidup yang relatif singkat.
S.Robins

Sejauh menyangkut pilihan gui-framework, saya tidak melihat bagaimana ini akan mempengaruhi cara di mana lingkungan pengujian diatur. Saya mencari BAGAIMANA khusus untuk mengimplementasikan tes unit untuk lapisan GUI menggunakan alat yang saya miliki. Jawaban khusus ini tidak benar-benar memberi tahu saya tentang itu.
S.Robins

Simoraman - Jika Anda mengambil paragraf pertama yang agak menghakimi, ini akan menuju ke jawaban. Perbaiki itu dan saya akan menghapus -1 saya. @ S.Robins dicatat bahwa paragraf kedua adalah relevan - meskipun tidak jawaban penuh, itu akan membantu. Jika lapisan GUI Anda tipis, terstruktur dengan baik & jelas, dan semua logika bisnis diuji dengan unit test pada tingkat Model, maka mungkin Anda tidak perlu melalui kerumitan tambahan untuk menguji UI secara eksplisit.
Mark Booth

1
@MarkBooth Layering tidak terlalu menjadi masalah. Seperti simiraman menyebutkan saya bisa MVP, MVVM, atau saya bisa membangun sesuatu yang lebih tipis. Namun saya memiliki beberapa elemen khusus GUI yang akan memerlukan pengujian eksplisit, itulah sebabnya saya memutuskan untuk menulis ini sebagai pertanyaan. Saya punya beberapa ide, dan jika lebih buruk menjadi lebih buruk, saya tahu bahwa pada akhirnya saya akan dapat menyelesaikan masalah dan menulis sendiri jawabannya. Namun saya ingin membuka ini ke komunitas karena saya pikir itu akan menjadi pertanyaan yang bagus untuk ProgrammersSE. ;-)
S.Robins

0

Lihatlah jawaban saya pada pertanyaan ini: Bagaimana cara mengatur MVP untuk solusi WinForms?

Saya sebenarnya telah menulis contoh aplikasi yang menunjukkan bagaimana saya lapisan, dan bagaimana saya menguji, GUI saya.

membaca hasil edit Anda: gunakan pelari uji yang terintegrasi dengan lingkungan pengembangan Anda. Saya menggunakan ReSharper.


Terima kasih atas rekomendasi ReSharper. Ini adalah alat yang saya gunakan saat berkembang. Sayangnya itu tidak akan membantu ketika menjalankan tes pada server build integrasi. Itu juga tidak memberi tahu saya cara mengkonfigurasi tes Nunit untuk mengakses kode di exe saat pengujian.
S.Robins

1
Secara informal, ya. Exe hanyalah view, yang memuat presenter, model, dan viewmodels dari perpustakaan kelas sebagai bagian dari startup aplikasi. Setidaknya dalam solusi saya, pandangannya cukup bodoh sehingga kita tidak mengujinya dengan tes otomatis, dan hanya melakukan tes penerimaan untuk memastikan semuanya dieja dengan benar dan tombol berada di tempat seharusnya. Menguji NUnit dll sangat mudah dilakukan.
Bryan Boettcher

0

Saya telah menulis Nunit WinForms beberapa tahun yang lalu (kurasa 6 tahun). Satu hal yang saya ingat secara khusus adalah bahwa meskipun ini merupakan unit uji, ia juga bertindak sebagai ujung ke ujung uji kasus. Terkadang tidak banyak yang bisa diuji di ujung depan (bentuk sederhana). Jadi, meskipun Anda mencoba menguji kotak pesan yang muncul pada klik tombol, Anda tidak sengaja menguji berbagai metode lain dari lapisan lain. Ada beberapa hal yang tidak dapat diotomatisasi juga. Tampilan, rasa, dan kegunaan tidak dapat diotomatisasi menggunakan pengujian unit otomatis. Anda harus menjalankan beberapa tes manual sebelum merilis.


Jika pelanggan Anda menentukan layar akan terlihat dengan cara tertentu, atau harus berubah dengan cara tertentu, maka Anda harus dapat menguji hal-hal ini. Menangkap spesifikasi sebagai tes adalah jantung dari metodologi BDD, dan saya tidak pernah menemukan situasi di mana Anda tidak dapat - meskipun secara kreatif - menemukan cara untuk mengotomatisasi tes. Pertanyaan sebenarnya adalah apakah pengujian akan bernilai, apakah aplikasi difaktorkan cukup baik untuk memungkinkan Anda mengotomatisasi semua tes di tempat pertama, dan apakah tes akan hemat biaya. Saya setuju, bahwa kadang-kadang tidak.
S.Robins
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.