Bagaimana cara Pengiriman Berkelanjutan dalam praktik?

22

Pengiriman Berkelanjutan kedengarannya bagus, tetapi pengalaman saya selama bertahun-tahun dalam pengembangan perangkat lunak menunjukkan bahwa dalam praktiknya itu tidak bisa berfungsi.

(Sunting: Untuk memperjelas, saya selalu memiliki banyak tes yang berjalan secara otomatis. Pertanyaan saya adalah tentang bagaimana mendapatkan kepercayaan diri untuk dikirimkan pada setiap checkin, yang saya pahami adalah bentuk lengkap dari CD. Alternatifnya bukan siklus sepanjang tahun. Ini adalah iterasi setiap minggu (yang beberapa orang mungkin menganggap masih CD jika dilakukan dengan benar), dua minggu, atau bulan; termasuk QA kuno di akhir masing-masing, melengkapi tes otomatis.)

  • Cakupan tes penuh tidak mungkin. Anda harus meluangkan banyak waktu - dan waktu adalah uang - untuk setiap hal kecil. Ini berharga, tetapi waktu dapat dihabiskan untuk berkontribusi pada kualitas dengan cara lain.
  • Beberapa hal sulit untuk diuji secara otomatis. Misalnya GUI. Bahkan Selenium tidak akan memberi tahu Anda jika GUI Anda miring. Akses database sulit untuk diuji tanpa alat berat, dan bahkan itu tidak akan mencakup kasus sudut aneh dalam penyimpanan data Anda. Demikian juga keamanan dan banyak hal lainnya. Hanya kode lapisan bisnis yang secara efektif dapat diuji unit.
  • Bahkan di lapisan bisnis, sebagian besar kode di luar tidak ada fungsi sederhana yang argumen dan nilai pengembaliannya dapat dengan mudah diisolasi untuk keperluan pengujian. Anda dapat menghabiskan banyak waktu membangun objek tiruan, yang mungkin tidak sesuai dengan implementasi nyata.
  • Tes integrasi / fungsional melengkapi tes unit, tetapi ini membutuhkan banyak waktu untuk dijalankan karena biasanya melibatkan menginisialisasi ulang seluruh sistem pada setiap pengujian. (Jika Anda tidak menginisialisasi ulang, lingkungan pengujian tidak konsisten.)
  • Refactoring atau perubahan lainnya mematahkan banyak tes. Anda menghabiskan banyak waktu untuk memperbaikinya. Jika itu masalah memvalidasi perubahan spec yang berarti, itu bagus, tetapi sering kali tes berhenti karena detail implementasi tingkat rendah yang tidak berarti, bukan hal-hal yang benar-benar memberikan informasi penting. Seringkali tweaker difokuskan pada pengerjaan ulang internal tes, bukan pada benar-benar memeriksa fungsi yang sedang diuji.
  • Laporan lapangan tentang bug tidak dapat dengan mudah dicocokkan dengan versi mikro kode yang tepat.
Joshua Fox
sumber
Ini berfungsi dengan sangat baik untuk Etsy slideshare.net/OReillyOSCON/… !
YoTsumi
4
Pengiriman Berkelanjutan tidak memerlukan pengujian (tetapi membantu). Ini merujuk pada fakta bahwa hal-hal yang Anda bangun secara teratur BISA dikirim ke pelanggan jika diperlukan.
Sangat menarik bahwa keberatan Anda untuk pengiriman terus-menerus berfokus pada pengujian sebagai elemen CD. Namun, itu hanya salah satu bagian dari teka-teki: Anda memerlukan perangkat internal yang kompeten, pengembang berkomitmen untuk inspeksi kualitas yang ketat, pendekatan prioritas luas-mendalam-dalam tes otomatis Anda, belum lagi dukungan organisasi yang kuat. Itu bisa dilakukan, tetapi dibutuhkan banyak orang untuk berkomitmen pada penyebabnya.
Stephen Gross
1
@Stephen Ya, saya fokus pada pengujian, karena saya setuju dengan semua aspek lainnya. Saya mendukung pengujian juga. Saya hanya tidak melihat bagaimana Anda bisa memiliki kepercayaan diri yang cukup untuk menerapkan setiap checkin.
Joshua Fox
@ Thorbjørn Ravn Andersen. Tentu saja, CD tampaknya membutuhkan pengujian. Bagaimana Anda bisa memiliki kepercayaan diri untuk secara otomatis mengirimkan setiap checkin tanpanya.
Joshua Fox

Jawaban:

29

pengalaman saya selama bertahun-tahun dalam pengembangan perangkat lunak menunjukkan bahwa dalam praktiknya itu tidak bisa bekerja.

Sudahkah Anda mencobanya? Dave dan saya menulis buku berdasarkan pengalaman bertahun-tahun bersama, baik diri kita sendiri maupun orang-orang senior lainnya di ThoughtWorks, benar-benar melakukan hal-hal yang kita diskusikan. Tidak ada dalam buku ini yang spekulatif. Segala sesuatu yang kita diskusikan telah dicoba dan diuji bahkan pada proyek-proyek besar yang didistribusikan. Tetapi kami tidak menyarankan Anda mengambilnya dengan iman. Tentu saja Anda harus mencobanya sendiri, dan tolong tulis apa yang Anda temukan berhasil dan yang tidak, termasuk konteks yang relevan, sehingga orang lain dapat belajar dari pengalaman Anda.

Pengiriman Berkelanjutan memiliki fokus besar pada pengujian otomatis. Kami menghabiskan sekitar 1/3 buku untuk membicarakannya. Kami melakukan ini karena alternatifnya - pengujian manual - mahal dan rawan kesalahan, dan sebenarnya bukan cara yang bagus untuk membangun perangkat lunak berkualitas tinggi (seperti yang dikatakan Deming, "Hentikan ketergantungan pada inspeksi massal untuk mencapai kualitas. Tingkatkan proses dan bangun kualitas menjadi produk di tempat pertama ")

Cakupan tes penuh tidak mungkin. Anda harus meluangkan banyak waktu - dan waktu adalah uang - untuk setiap hal kecil. Ini berharga, tetapi waktu dapat dihabiskan untuk berkontribusi pada kualitas dengan cara lain.

Tentu saja cakupan tes penuh tidak mungkin, tetapi apa alternatifnya: cakupan tes nol? Ada trade-off. Di suatu tempat di antara keduanya adalah jawaban yang benar untuk proyek Anda. Kami menemukan bahwa secara umum Anda harus menghabiskan sekitar 50% dari waktu Anda membuat atau mempertahankan tes otomatis. Itu mungkin terdengar mahal sampai Anda mempertimbangkan biaya pengujian manual yang komprehensif, dan memperbaiki bug yang keluar untuk pengguna.

Beberapa hal sulit untuk diuji secara otomatis. Misalnya GUI. Bahkan Selenium tidak akan memberi tahu Anda jika GUI Anda miring.

Tentu saja. Periksa kuadran tes Brian Marick. Anda masih perlu melakukan pengujian eksplorasi dan pengujian kegunaan secara manual. Tetapi untuk itulah Anda harus menggunakan manusia Anda yang mahal dan berharga - bukan pengujian regresi. Kuncinya adalah Anda harus memasang pipa penempatan agar Anda hanya perlu repot menjalankan validasi manual yang mahal terhadap bangunan yang telah lulus serangkaian pengujian otomatis yang komprehensif. Dengan demikian Anda berdua mengurangi jumlah uang yang Anda habiskan untuk pengujian manual, dan jumlah bug yang pernah sampai ke uji manual atau produksi (pada saat itu mereka sangat mahal untuk memperbaikinya). Pengujian otomatis yang dilakukan dengan benar jauh lebih murah daripada siklus hidup produk, tetapi tentu saja ini merupakan pengeluaran modal yang diamortisasi dengan sendirinya seiring waktu.

Akses database sulit untuk diuji tanpa alat berat, dan bahkan itu tidak akan mencakup kasus sudut aneh dalam penyimpanan data Anda. Demikian juga keamanan dan banyak hal lainnya. Hanya kode lapisan bisnis yang secara efektif dapat diuji unit.

Akses basis data diuji secara implisit oleh tes penerimaan fungsional berbasis skenario end-to-end Anda. Keamanan akan memerlukan kombinasi pengujian otomatis dan manual - pengujian penetrasi otomatis dan analisis statis untuk menemukan (mis.) Buffer overruns.

Bahkan di lapisan bisnis, sebagian besar kode di luar tidak ada fungsi sederhana yang argumen dan nilai pengembaliannya dapat dengan mudah diisolasi untuk keperluan pengujian. Anda dapat menghabiskan banyak waktu membangun objek tiruan, yang mungkin tidak sesuai dengan implementasi nyata.

Tentu saja tes otomatis mahal jika Anda membangun perangkat lunak Anda dan tes Anda buruk. Saya sangat merekomendasikan membaca buku "mengembangkan perangkat lunak berorientasi objek, dipandu oleh tes" untuk memahami bagaimana melakukannya dengan benar sehingga tes dan kode Anda dapat dipertahankan dari waktu ke waktu.

Tes integrasi / fungsional melengkapi tes unit, tetapi ini membutuhkan banyak waktu untuk dijalankan karena biasanya melibatkan menginisialisasi ulang seluruh sistem pada setiap pengujian. (Jika Anda tidak menginisialisasi ulang, lingkungan pengujian tidak konsisten.)

Salah satu produk yang saya kerjakan memiliki serangkaian 3.500 tes penerimaan ujung ke ujung yang membutuhkan waktu 18 jam untuk berjalan. Kami menjalankannya secara paralel pada kotak 70 kotak dan mendapatkan umpan balik dalam 45 m. Masih lebih lama dari ideal sebenarnya, itulah sebabnya kami menjalankannya sebagai tahap kedua dalam pipa setelah unit test berjalan dalam beberapa menit sehingga kami tidak membuang-buang sumber daya kami pada build yang kami tidak memiliki tingkat dasar kepercayaan pada.

Refactoring atau perubahan lainnya mematahkan banyak tes. Anda menghabiskan banyak waktu untuk memperbaikinya. Jika itu masalah memvalidasi perubahan spec yang berarti, itu bagus, tetapi sering kali tes berhenti karena detail implementasi tingkat rendah yang tidak berarti, bukan hal-hal yang benar-benar memberikan informasi penting. Seringkali tweaker difokuskan pada pengerjaan ulang internal tes, bukan pada benar-benar memeriksa fungsi yang sedang diuji.

Jika kode dan tes Anda dienkapsulasi dengan baik dan longgar, refactoring tidak akan merusak banyak tes. Kami menjelaskan dalam buku kami bagaimana melakukan hal yang sama untuk tes fungsional juga. Jika tes penerimaan Anda pecah, itu pertanda bahwa Anda kehilangan satu atau lebih tes unit, jadi bagian dari CD melibatkan terus meningkatkan cakupan tes Anda untuk mencoba dan menemukan bug sebelumnya dalam proses pengiriman di mana tes lebih halus dan bug lebih murah untuk diperbaiki.

Laporan lapangan tentang bug tidak dapat dengan mudah dicocokkan dengan versi mikro kode yang tepat.

Jika Anda pengujian sedang dan melepaskan lebih sering (bagian dari titik CD) maka adalah relatif mudah untuk mengidentifikasi perubahan yang menyebabkan bug. Inti dari CD adalah untuk mengoptimalkan siklus umpan balik sehingga Anda dapat mengidentifikasi bug sesegera mungkin setelah mereka diperiksa untuk kontrol versi - dan memang, lebih baik sebelum mereka diperiksa (itulah sebabnya kami menjalankan uji coba membangun dan unit sebelum check-in).

Jez Humble
sumber
Terima kasih atas jawaban anda. Ya, saya percaya pada pengujian. Proyek saya memiliki jangkauan kode yang baik dari pengujian otomatis yang dijalankan dengan build harian. Saya hanya mengatakan bahwa Anda perlu semacam iterasi sebelum rilis. "Kamu masih harus melakukan pengujian eksplorasi ... secara manual." Saya tidak mengerti. Sistem CD lengkap menggunakan setiap checkin. Bagaimana Anda bisa melakukannya jika Anda memasukkan pengujian manual?
Joshua Fox
3
Saya suka membedakan antara pengiriman berkelanjutan dan penerapan berkelanjutan. Inilah perbedaannya. Pengiriman kontinu berarti Anda menjaga sistem selalu siap produksi dan dapat dirilis sesuai permintaan dengan menekan satu tombol. Rilis adalah keputusan bisnis. Penempatan berkelanjutan adalah kasus pembatas di mana Anda merilis setiap build yang bagus (perhatikan tidak setiap check-in - beberapa check-in tidak menghasilkan build yang dapat dirilis). Dalam kedua kasus Anda dapat memasukkan validasi manual: kuncinya adalah konsep pipa penyebaran .
Jez Humble
Mengenai "Akses basis data diuji secara implisit oleh tes penerimaan fungsional berbasis skenario end-to-end Anda." Masalah utama adalah ini implisit . Orang-orang tampaknya senang dengan itu, tetapi ini adalah pendekatan yang sangat membuang waktu; alih-alih mengatakan masalah "Ini yang saya harapkan dari DB dan malah mendapat ini", katanya "Sesuatu pecah di salah satu dari 100 lapisan".
atoth
11

Pertama, CD membutuhkan satu penyesuaian mental yang besar - Anda harus mengakui bahwa terkadang segala sesuatunya akan rusak, apa pun yang Anda lakukan. Pada akhirnya, Anda tidak dapat membuktikan negatif.

Setelah Anda melewati ini, Anda menyadari bahwa Anda memerlukan alat dan prosedur untuk a) menangkap kesalahan ini dengan sangat cepat dan b) memutar kembali atau menggunakan pembaruan dengan sangat efisien. Selain itu, jika Anda benar-benar meminum CD cocktail, Anda benar-benar memberikan banyak perubahan kecil dan runcing yang mudah untuk diputar kembali dan seharusnya tidak dapat memperkenalkan bug utama, aplikasi-lebar. Bahkan orang-orang yang benar-benar berlatih CD menangani pergantian besar dengan cara yang lebih tradisional.

Wyatt Barnett
sumber
"kecil ... perubahan ... seharusnya tidak dapat memperkenalkan bug di seluruh aplikasi". Bahkan dalam kode yang diperhitungkan dengan baik, ini bisa terjadi. Misalnya, Anda menambahkan div yang mendorong div lain keluar dari tampilan di satu browser tertentu. Sebagai contoh, nilai nol muncul dalam kasus sudut yang tidak terduga, melempar pengecualian dan mencegah GUI dari rendering sama sekali. Ya, Anda harus menguji segala kemungkinan, seperti yang saya lakukan, tetapi bug pasti terjadi, dan bug kecil dapat mengganggu seluruh aplikasi.
Joshua Fox
Tetapi mereka masih mudah ditemukan dan diperbaiki yang merupakan titik penekanan yang lebih besar.
Wyatt Barnett
2

Setiap sistem memiliki risiko, dan setiap risiko memiliki potensi biaya. Jika biaya beberapa risiko kecil, dari jenis yang mungkin memakan waktu berbulan-bulan atau bertahun-tahun untuk ditemukan dalam pengujian ekstensif dan QA, cukup tinggi (perangkat lunak dalam alat pacu jantung Anda), Anda tidak dapat mengirim tanpa periode ekstensif pengujian suatu rilis beku. Jika biaya kegagalan cukup kecil, mungkin Anda mengirim terus menerus dengan nol pengujian (halaman Facebook kucing Anda).

hotpaw2
sumber
Iya nih. Untuk sebagian besar aplikasi produksi, risikonya ada di antara keduanya. Dan menurut saya risikonya sedemikian rupa sehingga kami tidak ingin menggunakan setiap checkin, bahkan dengan pengujian otomatis. Tampaknya putaran QA selalu dibutuhkan. Tapi kira-kira rilis mingguan sepertinya layak untuk saya.
Joshua Fox
1

Cakupan tes penuh tidak mungkin. Anda harus meluangkan banyak waktu - dan waktu adalah uang - untuk setiap hal kecil. Ini berharga, tetapi waktu dapat dihabiskan untuk berkontribusi pada kualitas dengan cara lain.

Anda tidak perlu cakupan 100%, Anda perlu cukup percaya diri dalam sistem Anda, bahwa perubahan di satu tempat tidak akan merusak hal-hal yang sebelumnya terbukti berhasil.

Beberapa hal sulit untuk diuji secara otomatis. Misalnya GUI. Bahkan Selenium tidak akan
memberi tahu Anda jika GUI Anda miring. Akses basis data sulit untuk diuji tanpa alat berat, dan bahkan itu tidak akan mencakup kasus sudut aneh dalam penyimpanan data Anda.

Namun, akses basis data sepele untuk ditulis. Anda seharusnya tidak memerlukan banyak tes pada lapisan data Anda karena hanya mendapatkan dan mengatur data. Yang paling penting adalah memastikan bahwa ketika gagal, ia memutar balik dan mencatat masalah sehingga Anda dapat memperbaikinya.

Demikian juga keamanan dan banyak hal lainnya. Hanya kode lapisan bisnis yang secara efektif dapat diuji unit. Bahkan di lapisan bisnis, sebagian besar kode di luar tidak ada fungsi sederhana yang argumen dan nilai pengembaliannya dapat dengan mudah diisolasi untuk keperluan pengujian.

Maka banyak fungsi / kelas Anda terlalu besar. Mereka harus ditulis agar dapat diuji.

Anda dapat menghabiskan banyak waktu membangun objek tiruan, yang mungkin tidak sesuai dengan implementasi nyata.

I / O objek tiruan harus cocok dengan apa yang diharapkan. Apa yang terjadi di dalamnya tidak penting.

Tes integrasi / fungsional melengkapi tes unit, tetapi ini membutuhkan banyak waktu untuk dijalankan karena biasanya melibatkan menginisialisasi ulang seluruh sistem pada setiap pengujian. (Jika Anda tidak menginisialisasi ulang, lingkungan pengujian tidak konsisten.)

Ini tidak boleh dijalankan sepanjang waktu. Sesuai kebutuhan.

Refactoring atau perubahan lainnya mematahkan banyak tes. Anda menghabiskan banyak waktu untuk memperbaikinya. Jika itu masalah memvalidasi perubahan spec yang berarti, itu bagus, tetapi sering kali tes berhenti karena detail implementasi tingkat rendah yang tidak berarti, bukan hal-hal yang benar-benar memberikan informasi penting. Seringkali tweaker difokuskan pada pengerjaan ulang internal tes, bukan pada benar-benar memeriksa fungsi yang sedang diuji.

Kemudian kode Anda terlalu erat digabungkan, dan tes Anda ditulis dengan buruk.

Laporan lapangan tentang bug tidak dapat dengan mudah dicocokkan dengan versi mikro kode yang tepat.

Tidak yakin apa yang Anda dapatkan di sini? Jika ada bug, tulis tes untuk menunjukkan keberadaannya, lalu perbaiki.

CaffGeek
sumber
"I / O dari objek tiruan harus sesuai dengan apa yang diharapkan". "Membangun MO yang sepenuhnya mengimplementasikan antarmuka-spesifikasi memakan waktu. Lebih buruk lagi, seseorang harus memperbaruinya secara terus-menerus, sehingga seseorang secara efektif menulis semua kode dua kali (sekali untuk produksi dan sekali untuk MO)
Joshua Fox
1

Bekerja dengan baik untuk kami, tetapi sebagian besar pelanggan kami internal. Beberapa build dilakukan pada siang hari, build rusak tidak ditoleransi, mekanisme mulai web digunakan sehingga pengguna mendapatkan versi terbaru setiap peluncuran. Satu hal yang membuat CD banyak masalah hilang. Ya, Anda memiliki masalah kompatibilitas setiap saat, namun, karena Anda hanya menerapkan perubahan kecil setiap kali, masalah tersebut sangat mudah untuk ditangani. Tingkat stres CD JAUH lebih rendah daripada ketika kami membuat pembaruan besar dan harus berharap semuanya benar karena akan ada begitu banyak kode untuk ditinjau jika terjadi kerusakan.

Brian Knoblauch
sumber
-4

Sejujurnya, SEMUA perangkat lunak dalam pengiriman berkelanjutan! Yang paling penting adalah mengeluarkannya! Dapatkan pengguna Anda menggunakannya dan memprioritaskan permintaan fitur dan gangguan bug setelah itu.

"Artis seniman sejati"
- Steve Jobs.

Gary Willoughby
sumber
alternatif untuk CD bukanlah siklus sepanjang tahun. Ini adalah iterasi setiap minggu, dua minggu, atau bulan.
Joshua Fox