Alternatif untuk indikator “Passing / Broken build”?

14

Ketika memiliki integrasi berkesinambungan menjalankan tes di setiap komit, praktik terbaik umum adalah memiliki semua tes yang lulus setiap saat (alias "jangan merusak build").

Saya menemukan beberapa masalah dengan itu:

Misalnya seseorang tidak dapat membantu proyek sumber terbuka dengan membuat tes yang sesuai dengan tiket. Saya tahu jika saya mengusulkan Permintaan Tarik ke proyek open source yang berisi tes gagal, build akan ditandai sebagai gagal dan proyek tidak akan mau yang digabungkan ke dalam repositori karena itu akan "memecah build".

Dan saya tidak percaya itu adalah hal yang buruk untuk memiliki tes gagal dalam repo Anda , itu seperti memiliki masalah terbuka di pelacak Anda. Ini hanya hal-hal yang menunggu untuk diperbaiki.

Hal yang sama berlaku di perusahaan. Jika Anda bekerja dengan TDD, Anda tidak bisa menulis tes, komit dan kemudian menulis kode logika yang memenuhi tes. Itu berarti jika saya telah menulis tes 4-5 di laptop saya, saya tidak bisa melakukan itu sebelum pergi liburan. Tidak ada yang bisa mengambil kembali pekerjaanku. Saya bahkan tidak bisa "membagikan" mereka dengan kolega kecuali dengan mengirimkannya melalui email misalnya. Ini juga mencegah bekerja dengan satu orang menulis tes, yang lain menulis model.

Semua yang ingin saya katakan, apakah saya menyalahgunakan / salah paham proses pembangunan / integrasi berkelanjutan? Sepertinya saya "lewat" / "tidak lewat" adalah indikator yang terlalu sempit.

Apakah ada cara untuk membuat integrasi berkelanjutan dan TDD kompatibel?

Mungkin ada solusi / praktik standar untuk membedakan "tes baru" (yang bisa gagal) dan "tes regresi" (yang seharusnya tidak gagal karena mereka dulu bekerja)?

Matthieu Napoli
sumber
1
Miliki indikator yang menunjukkan apakah jumlah tes gagal naik (merah) atau turun (hijau) dalam satu jam terakhir (atau lebih).
Joachim Sauer
2
Saya bukan spesialis TDD / ALM (karena itu komentar, daripada jawaban) tapi saya pikir masalah Anda dapat diselesaikan dengan cabang pribadi / cabang fitur. Apakah Anda mengerjakan Fitur A? Cabang itu, bekerja pada cabang (dengan rekan-rekan), dan setelah Anda selesai - gabungkan ke dalam batang terintegrasi terus menerus.
Avner Shahar-Kashtan
@ JoachimSauer Ya tetapi apakah metrik tersebut distandarisasi / digunakan dalam proyek besar apa pun? Saya mencoba memahami mengapa sebagian besar proyek (dan alat CI) bekerja seperti itu.
Matthieu Napoli
Saya pikir kriteria yang tepat untuk "tes yang dapat gagal" bukanlah "tes baru", melainkan "tes untuk masalah terbuka yang diketahui". Saya dapat melihat bagaimana tes-tes itu berguna untuk dimiliki - saya juga dapat bagaimana tes-tes tersebut TIDAK berguna dalam CI build karena mereka mencemari arti dari lulus tes / gagal di sana (Anda hanya ingin menjalankan tes yang seseorang benar-benar menghabiskan waktu untuk membuat mereka lulus).
Joris Timmermans
@MadKeithV Persis
Matthieu Napoli

Jawaban:

12

Saya melihat di mana Anda mendapatkan, tetapi jenis masalah ini biasanya diselesaikan dengan cara lain. Ada alasan bagus mengapa ini adalah protokol standar. Jika seseorang mengirimkan kode yang tidak dikompilasi, semua orang yang memperbarui kodenya akan memiliki program yang tidak dikompilasi . Itu termasuk programmer yang saat ini mengerjakan sesuatu yang sangat berbeda dan entah bagaimana menemukan diri mereka dalam situasi di mana mereka harus menunggu sebelum mereka dapat mengkompilasi dan menguji apa yang sedang mereka kerjakan.

Protokol standar adalah bahwa Anda dapat melakukan perubahan bahkan untuk pekerjaan yang lengkap atau bahkan tidak lengkap, asalkan dikompilasi sehingga programmer dapat memperbarui kode mereka setiap hari jika perlu.

Namun, saya masih melihat apa yang Anda maksud. Terkadang Anda ingin melakukan komitmen untuk hanya menyimpan kode Anda. Untuk ini, kebanyakan repositori sumber mendukung percabangan. Ini memungkinkan Anda untuk membuat cabang pribadi, mengerjakannya tanpa mengganggu orang lain, kemudian bergabung ke dalam bagasi ketika pekerjaan selesai. Ini memungkinkan Anda untuk melakukan ketika Anda ingin tanpa serangan balik yang terkait dengan menyebabkan build rusak.

Jika itu tidak cocok, GIT memungkinkan Anda untuk melakukan (mendorong) ke repositori di mesin lokal Anda, tetapi mungkin repositori itu bisa berada di mana saja. Anda bisa membuat repositori untuk pekerjaan yang berpotensi parsial / tidak lengkap dan repositori lain untuk pekerjaan yang sudah selesai, dan pada repositori itu Anda bisa menambahkan bangunan malam.

Sekali lagi, saya tidak bisa cukup menekankan pentingnya. Jangan pernah melakukan kode rusak ke trunk! Kontribusi Anda tidak dapat memengaruhi pekerjaan programmer lain.

Edit

Saya melihat bahwa Anda bermaksud tes yang gagal, tetapi menurut pendapat saya, ada sedikit perbedaan. Inti dari suatu tes adalah untuk menentukan apakah aspek tertentu dari suatu program lulus atau gagal. Jika selalu gagal dan Anda tidak melakukan apa pun, maka pengujian tersebut, dalam penggunaan tradisional pengujian unit, tidak menghasilkan apa-apa. Jika Anda menggunakannya untuk melakukan beberapa metrik lain yang tidak memerlukan komit "gagal" jika salah satu tes gagal, maka saya sangat menyarankan Anda mencari cara lain untuk melakukan hal yang sama.

Kalau tidak, Anda berisiko bahwa tes tidak pernah dipertimbangkan atau jika itu menyebabkan bangunan Anda gagal, bahwa sesama programmer Anda mengabaikan bangunan gagal. Lebih penting bahwa programmer menyadari ketika mereka telah melanggar membangun daripada melakukan tes yang tidak menawarkan wawasan nyata dan hanya dapat mengakibatkan praktik buruk.

Neil
sumber
1
Memang Anda membuat titik dengan cabang topik. Tapi saya tidak pernah berbicara tentang melakukan kode yang rusak, hanya gagal tes. Misalnya saya bisa membantu proyek open source dengan membuat tes untuk tiket masuk bahkan jika saya tidak tahu bagaimana memperbaikinya. Itu menghemat waktu bagi para pengelola.
Matthieu Napoli
Jika saya mengerjakan proyek yang sama dengan Anda, dan Anda mengunggah tes gagal, saya sekarang memiliki bangunan yang memiliki tes gagal. Saya mungkin akhirnya menghapus pengujian Anda, karena fungsi itu belum diimplementasikan, atau memutuskan untuk mengimplementasikan fitur dan akhirnya menginjak kode Anda dan membuang-buang waktu. Jika ada budaya melakukan ini, respons semacam itu dapat dihindari, tetapi kemudian semua orang akan melakukannya, dan bahkan ketika semua tes Anda lulus, tidak semua tes saya lakukan. Dalam hal ini, versi build akan selalu gagal. Saya tidak melihat sisi positifnya.
Michael Shaw
the build would always have failing teststepat! Tapi apakah itu hal yang buruk? Satu-satunya metrik kami adalah "build rusak atau tidak", tetapi kode Anda mungkin penuh dengan bug yang diketahui , sehingga tidak benar-benar berarti apa-apa kecuali tidak ada regresi. Di dunia yang sempurna, setiap masalah pelacak akan diuji (mereproduksi lebih mudah daripada memperbaiki). Jadi sisi baiknya adalah untuk melihat bahwa 35 tes / 70% dari semua tes lulus, bahwa Cabang-A meningkatkannya menjadi 40 tes (80%) tanpa regresi, dan bahwa Cabang-B memiliki regresi. Hari ini Anda hanya bisa mengatakan Master dan Cabang-A baik-baik saja dan Cabang-B rusak.
Matthieu Napoli
@Matthieu Saya melihat apa yang Anda maksud. Kedengarannya seperti Anda memerlukan kategori khusus atau sesuatu yang mengatakan "hei, jika tes ini gagal, tidak apa-apa. Kami tahu tentang itu. Tapi kami masih ingin itu berjalan dan jika itu berlalu maka itu lebih baik dan kami harus menghapus kategori khusus karena kami sekarang peduli jika itu rusak "
Earlz
@ Elis Tepat! Yang saya bertanya-tanya adalah "apakah itu dilakukan oleh seseorang, di suatu tempat? Dan apakah ada alat yang mendukung itu (CI dan perpustakaan pengujian unit?" Karena jika saya hanya mengkategorikan tes tersebut dengan CI klasik dan alat unit-test, build akan selalu tetap gagal dan saya tidak akan melihat perbedaan antara tes mana yang gagal, dan karenanya tidak akan berguna: /
Matthieu Napoli
4

Diberikan cabang master dengan tes gagal, bagaimana Anda bisa yakin - tanpa membandingkan daftar itu dengan build sebelumnya - bahwa Anda belum memperkenalkan bug?

Melacak jumlah tes gagal saja tidak cukup: Anda mungkin memperbaiki satu tes, dan memecahkan yang lain. Dan jika Anda sedang berlibur, tidak akan jelas bagi orang lain melihat bangunan yang gagal.

Jaga agar cabang utama Anda bersih dan hijau setiap saat. Bekerja di cabang. Simpan cabang di bawah CI, dalam pekerjaan yang terpisah, dan lakukan tes yang gagal sesuka hati Anda. Hanya saja, jangan mematahkan master.

Mintalah resensi cabang hanya menggabungkan cabang Anda jika lulus semua tes. (Lebih kuat lagi: minta resensi hanya dapat menggabungkan cabang Anda jika hasil menggabungkan cabang ke master melewati semua tes!)

Frank Shearar
sumber
2
Simply tracking the number of failing tests is insufficientitu bukan satu-satunya metrik yang mungkin. Sebagai contoh: Branch-A improves it to 40 tests (80% passing) with no regression. Tidak ada regresi berarti sebelumnya lulus tes selalu lulus. Singkatnya, tes akan dibiarkan gagal asalkan tidak pernah lulus. Tampaknya bagi saya bahwa kita kehilangan hal-hal baik dengan membatasi untuk melarang tes gagal di cabang utama. (tentu saja akan membutuhkan alat yang bekerja secara berbeda: tes unit, CI, ...)
Matthieu Napoli
Saya masih mendukung pendapat saya: master harus selalu hijau, karena jelas dan tidak ambigu. Yang pasti, tes marker gagal ... di cabang fitur. CI dapat terus mengingatkan orang akan bug yang luar biasa.
Frank Shearar
Saya pikir apa yang diusulkan Matthieu adalah definisi yang sedikit berbeda dari "hijau", tidak menyimpang dari tuan yang selalu hijau. Tidak jelas bagi saya bahwa itu tidak masuk akal - tentu saja perlu beberapa alat pelacakan yang tidak sepele. (Perlu mengembalikan perubahan yang membuat tes lulus? Beruntung jika itu berarti negara tiba-tiba merah ...)
Christopher Creutzig
NUnit memiliki konsep tes yang diabaikan. Itu mungkin alternatif: mereka tidak lari sehingga mereka tidak gagal, tetapi mereka masih dilaporkan diabaikan.
Frank Shearar
2

Ada beberapa cara untuk menyelesaikan masalah Anda tanpa membuang praktik yang dipahami dan diterima tentang integrasi berkelanjutan.

Saya akan mulai dengan masalah melakukan 'tes rusak' yang sesuai dengan tiket. Salah satu solusinya adalah membuat satu atau lebih tes pemecahan yang mengekspos masalah, kemudian benar-benar memperbaiki masalah , sehingga mereka dapat digabungkan kembali ke baris kode utama bersama-sama. Solusi kedua adalah memiliki tes yang rusak, tetapi gunakan beberapa jenis bendera abaikan sehingga mereka tidak benar-benar menjalankan dan menghancurkan build. Mungkin menambahkan komentar atau anotasi khusus yang membuatnya sangat jelas bahwa ini adalah ujian yang rusak Ticket#N. Juga lampirkan catatan pada tiket itu sendiri yang mengacu pada tes yang dibuat yang sedang menunggu untuk dibatalkan dan dijalankan. Ini akan membantu seseorang memperbaiki tiket, tetapi juga tidak akan menjadi bendera merah bagi seseorang yang datang di ujian.

Dan ke masalah Anda berikutnya dengan TDD. TDD adalah tentang menulis tes kecil dan kemudian menulis sejumlah kecil kode untuk membuat tes lulus . Kemudian tetap iterasi sampai Anda memiliki modul fungsional kecil. Saya merasa bahwa jika Anda menulis 4-5 tes, maka Anda pergi berlibur, Anda mungkin salah melakukannya. Anda dapat memasangkan program dengan seseorang dengan cara yang salah satu dari Anda menulis tes, yang lain kode yang sesuai. Namun Anda tidak boleh menggunakan repositori baris kode utama untuk membagikan kode ini di antara Anda berdua sebelum modul yang lengkap siap untuk dikomit. Seperti yang disarankan orang lain, cabang bersama akan menyelesaikan masalah Anda di sana.

Mencoba memecahkan mantra integrasi berkelanjutan dapat mengarah ke jalur yang tidak terduga dan menakutkan. Sebagai contoh, apa artinya cakupan kode dalam jenis lingkungan ini ? Bagaimana pengembang tidak merasa bahwa sistem memiliki banyak " Windows Rusak " ? Bagaimana seseorang membuat perubahan, menjalankan tes dan tahu apakah mereka benar-benar melanggar sesuatu yang baru, atau hanya barang lama?

c_maker
sumber
Anda tidak perlu alat apa pun untuk dibagikan dengan orang yang Anda program pasangan - cukup serahkan keyboard. Jika Anda menggunakan komputer yang berbeda, well, tidak ada yang salah dengan itu, hanya saja bukan "pair programming".
Christopher Creutzig
1

Saya pikir masalah mendasar Anda adalah bahwa Anda menyertakan HASIL tes sebagai bagian dari build. Meskipun jelas beberapa orang setuju dengan Anda, yang lain tidak. Menghancurkan bangunan terjadi ketika tidak dibangun. Tidak ketika itu tidak membangun tanpa kesalahan.

Pertimbangkan proyek besar seperti Windows atau Linux, atau bahkan sesuatu seperti Firefox - apakah Anda pikir mereka mengirim bug gratis? Tentu saja tidak. Sekarang proyek-proyek ini tidak melakukan TDD, tapi itu benar-benar tidak relevan - TDD tidak mengubah dua fakta mendasar: bug ada, dan butuh waktu untuk memperbaikinya. Waktu di mana proyek (open source atau tidak) tidak mampu membuang-buang bug prioritas rendah. Baru-baru ini KDE memiliki bug yang telah diperbaiki lebih dari satu dekade. Kapan terakhir kali Anda mendengar seseorang berkata, "Saya senang kami menunggu satu dekade untuk mengirimkan proyek kami"?

TDD, dengan cara tertentu, mungkin membuatnya lebih mudah untuk dikirim dengan bug - karena Anda memiliki pemahaman yang lebih baik tentang apa cacatnya. Jika Anda dapat menentukan dengan tepat apa yang menyebabkan bug, Anda memiliki dasar yang sangat baik untuk menimbang biaya untuk memperbaikinya.

Rekomendasi saya adalah menemukan proyek yang tidak masalah merah di antara hijau.

jmoreno
sumber
1
 > a common best practice is to have all the tests passing (green) at all times.

Saya lebih suka semua tes tidak gagal (tidak merah).

Dengan definisi yang sedikit berbeda ini Anda juga dapat menentukan tes apa saja

  • belum diimplementasikan (abu-abu di nunit jika ada NotImplementedException)
  • diketahui gagal = "perlu dilakukan" dengan menandai / memberi anotasi pada tes yang diabaikan (kuning)

Saya Anda periksa ini ke dalam repositori build terus-menerus Anda tidak rusak dan karena itu valid.

k3b
sumber
0

Anda dapat mempertimbangkan dua CI berbeda membangun "konsep".

  1. CI biasa terbentuk. Pembangunan CI biasa harus mengkompilasi dan menjalankan hanya tes-tes yang kodenya telah ditulis untuk membuatnya lulus, sehingga laporan CI lulus / gagal tes merupakan indikator regresi yang jelas dan tidak ambigu terhadap keadaan kode yang diterima sebelumnya.
  2. Membangun CI "masa depan". Build ini mengkompilasi dan menjalankan hanya tes-tes yang tidak ada kode yang ditulis khusus untuk membuatnya lulus. Mungkin ada beberapa alasan untuk melakukan tes seperti itu:

    • Tes dapat ditambahkan untuk kasus-kasus kegagalan spesifik dari pelacak masalah, yang belum ada perbaikan yang dicoba. Jelas bermanfaat untuk sudah memiliki uji coba yang dikodifikasikan dan berjalan untuk masalah bahkan tanpa perbaikan.

    • Tes ditambahkan untuk fungsionalitas baru yang diperlukan yang belum diimplementasikan.

    • Seringkali lebih mudah untuk mengetahui cara menguji kegagalan atau fitur daripada mengetahui bagaimana menerapkan fitur atau memperbaiki, dan memisahkan dua langkah dengan melakukan tes ke kontrol sumber dapat berguna untuk memastikan tidak ada informasi yang hilang.

Seperti dalam CI "standar", dalam rezim pengembangan reguler tim hanya akan melihat hasil build harian dari build reguler.

Tim juga dapat mengawasi evolusi kasus uji dari pembangunan CI "masa depan" - khusus untuk melihat apakah ada perubahan yang dibuat untuk CI reguler yang benar-benar memperbaiki masalah dari bangunan "masa depan", yang dapat menjadi indikasi penting masalah mendasar atau peningkatan desain.

Akhirnya, jika seorang anggota tim memiliki waktu ekstra di tangan mereka, mereka dapat melihat memperbaiki salah satu masalah dari "masa depan", dan jika mereka berhasil memindahkannya ke "biasa" (sambil memperbarui status pelacak masalah).

Joris Timmermans
sumber
0

Dan saya tidak percaya itu adalah hal yang buruk untuk memiliki tes gagal dalam repo Anda, itu seperti memiliki masalah terbuka di pelacak Anda. Ini hanya hal-hal yang menunggu untuk diperbaiki.

Masalahnya bukan tes gagal, itu adalah indikator sederhana, konteks kurang dari regresi. Aka: sebagai pengembang, dapatkah saya memeriksa satu indikator dan tahu apakah saya memperkenalkan kode regresi atau rusak.

Saat Anda memperkenalkan konsep kegagalan 'lunak' (tidak apa-apa, kami sedang mengusahakannya / belum diimplementasikan / kami sedang menunggu versi baru / itu akan lulus lagi setelah bangunan lain ini diperbaiki), Anda memerlukan setiap orang yang mungkin berlari atau melihat tes untuk mengetahui kondisi yang diharapkan. Yang dalam tim yang cukup besar akan berubah setiap saat: indikator Anda menjadi tidak berarti. Dalam konteks yang lebih kecil (uji integrasi tim pribadi misalnya), maka saya pikir ini seperti utang teknis dan tidak masalah - hanya perlu dikelola.

Cara sebagian besar alamat alat yaitu 'hijau / lewat' mencerminkan apa hasil yang diharapkan - bukan karena kode berfungsi:

  • Kebugaran memiliki konsep kegagalan yang diharapkan.
  • JUnit memiliki @Ignored / @Test (harapan =)
  • Mentimun memiliki status 'belum diimplementasikan' (atau apa pun namanya)

Mereka datang dengan masalah mereka sendiri (bagaimana Anda membedakan antara 'ya, kami tahu itu rusak, bekerja di sana' dan 'perilaku yang benar adalah pengecualian') - tetapi mereka membantu.

ptyx
sumber
0

Saya menggunakan tes yang dilewati.

Dalam kerangka pengujian unit tertentu yang saya gunakan, saya bisa meningkatkan pengecualian SkipTest. Tes tidak benar-benar berjalan, dan kegagalannya tidak akan merusak build. Namun, saya bisa melihat jumlah tes yang dilewati dan melihat apakah ada pekerjaan yang harus dilakukan di daerah itu.

Winston Ewert
sumber