Advertisement
  1. Code
  2. Tools & Tips

Skrip Shell yang Menguji Coba

by
Difficulty:AdvancedLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Dzu Al-Faqqar (you can also view the original English article)

Menulis skrip shell sangat mirip pemrograman. Beberapa skrip memerlukan sedikit investasi waktu; sedangkan, skrip rumit lainnya mungkin memerlukan pemikiran, perencanaan, dan komitmen yang lebih besar. Dari perspektif ini, masuk akal untuk mengambil pendekatan berbasis tes dan unit menguji script shell kami.

Untuk mendapatkan hasil maksimal dari tutorial ini, Anda harus terbiasa dengan antarmuka baris perintah (CLI); Anda mungkin ingin melihat Command Line adalah tutorial Sahabat Anda jika Anda memerlukan penyegaran. Anda juga membutuhkan pemahaman dasar tentang scripting shell Bash-like. Terakhir, Anda mungkin ingin membiasakan diri dengan konsep pengembangan yang digerakkan oleh pengujian (TDD) dan pengujian unit secara umum; pastikan untuk memeriksa tutorial PHP Test-Driven ini untuk mendapatkan ide dasarnya.


Mempersiapkan Lingkungan Pemrograman

Pertama, Anda memerlukan editor teks untuk menulis skrip shell dan tes unit. Gunakan favoritmu!

Kami akan menggunakan kerangka pengujian unit shell shUnit2 untuk menjalankan pengujian unit kami. Itu dirancang untuk, dan bekerja dengan, kerang mirip Bash. shUnit2 is an open source framework released under the GPL license, and a copy of the framework is also included with this tutorial's sample source code.

Menginstal shUnit2 sangat mudah; cukup unduh dan ekstrak arsip ke lokasi mana pun di hard drive Anda. Itu ditulis dalam Bash, dan dengan demikian, kerangka kerja hanya terdiri dari file skrip. Jika Anda berencana untuk sering menggunakan shUnit2, saya sangat menyarankan Anda meletakkannya di lokasi di PATH Anda.


Menulis Tes Pertama kami

Untuk tutorial ini, ekstrak shUnit ke direktori dengan nama yang sama di folder Sumber Anda (lihat kode yang terlampir pada tutorial ini). Buat folder Tes di dalam Sumber dan tambahkan panggilan file baru firstTest.sh.

Daripada membuat file pengujian dapat dijalankan.

Sekarang Anda dapat menjalankannya dan mengamati output:

Ia mengatakan kami berlari satu sukses tes. Sekarang, mari kita menyebabkan tes gagal; mengubah pernyataan assertEquals sehingga dua senar yang tidak sama dan menjalankan tes lagi:


Permainan Tenis

Anda menulis tes penerimaan pada permulaan proyek/fitur/cerita ketika Anda jelas dapat menentukan persyaratan tertentu.

Sekarang bahwa kita memiliki lingkungan pengujian kerja, mari kita menulis sebuah skrip yang membaca file, membuat keputusan berdasarkan dari isi file, dan output informasi ke layar.

Tujuan utama dari script adalah untuk menunjukkan nilai permainan tenis antara dua pemain. Kita akan berkonsentrasi hanya pada menjaga Skor satu permainan; segala sesuatu yang lain adalah terserah Anda. Aturan penilaian adalah:

  • Pada awal, setiap pemain memiliki nilai nol, disebut "cinta"
  • Pertama, kedua dan ketiga bola memenangkan ditandai sebagai "lima belas", "tiga puluh" dan "empat puluh".
  • Jika pada "empat puluh" Skor sama, itu disebut "deuce".
  • Setelah ini, nilai akan disimpan sebagai "Keuntungan" untuk pemain yang mencetak satu titik lebih daripada pemain lain.
  • Seorang pemain adalah pemenang jika ia berhasil memiliki keuntungan dari setidaknya dua poin dan memenangkan setidaknya tiga poin (yaitu, jika ia mencapai setidaknya "empat puluh").

Definisi dari Input dan Output

Aplikasi kami akan membaca nilai dari file. Sistem lain akan mendorong informasi ke dalam file ini. Baris pertama dari file data ini akan berisi nama-nama para pemain. Ketika seorang pemain Skor titik, namanya ditulis pada akhir file. Khas Skor file terlihat seperti ini:

Anda dapat menemukan konten ini dalam input.txt file dalam Source folder.

Output dari program kami menulis nilai ke layar satu baris pada satu waktu. Output harus:

Output ini dapat juga ditemukan dalam output.txt file. Kami akan menggunakan informasi ini untuk memeriksa apakah program kami benar.


Tes penerimaan

Anda menulis tes penerimaan pada permulaan proyek/fitur/cerita ketika Anda jelas dapat menentukan persyaratan tertentu. Dalam kasus kami, tes ini hanya panggilan script kami segera-ke-akan-dibuat dengan nama input file sebagai parameter, dan mereka mengharapkan hasil sama dengan file tulisan tangan dari bagian sebelumnya:

Kami akan menjalankan pengujian kami di folder Sumber/Tes; oleh karena itu, cd... membawa kita ke Sumber direktori. Kemudian mencoba untuk menjalankan tennisGamse.sh, yang belum ada. Maka perintah diff akan membandingkan dua file:./output.txt output tulisan tangan kami dan ./results.txt akan memuat hasil dari script kami. Akhirnya, assertTrue memeriksa nilai keluar diff.

Tapi untuk saat ini, tes kami mengembalikan kesalahan berikut:

Mari kita mengubah kesalahan mereka menjadi kegagalan bagus dengan menciptakan sebuah file kosong yang disebut tennisGame.sh dan membuat executable. Sekarang ketika kita menjalankan tes kami, kami tidak mendapatkan error:


Implementasi dengan TDD

Membuat file lain yang disebut unitTests.sh untuk unit test. Kami tidak ingin menjalankan script kami untuk setiap tes; kami hanya ingin menjalankan fungsi-fungsi yang kami uji. Jadi, kita akan membuat tennisGame.sh menjalankan hanya fungsi-fungsi yang akan tinggal di functions.sh:

Ujian pertama kami sederhana. Kami berusaha untuk mengambil nama pemain pertama ketika baris berisi dua nama yang dipisahkan oleh tanda hubung. Tes ini akan gagal karena kita belum memiliki fungsi getFirstPlayerFrom:

Implementasi untuk getFirstPlayerFromis sangat sederhana. Itu adalah kalimat biasa yang didorong melalui perintah sed:

Sekarang melewati tes:

Mari kita menulis tes lain untuk pemain kedua nama:

Kegagalan:

Dan sekarang implementasi fungsi untuk membuatnya lulus:

Sekarang kami telah melewati tes:


Mari kita mempercepat

Mulai saat ini, kita akan menulis tes dan implementasi, dan saya akan menjelaskan hanya apa layak untuk disebutkan.

Mari kita menguji jika kita memiliki pemutar dengan hanya satu Skor. Menambahkan tes berikut:

Dan solusinya:

Kami menggunakan beberapa mewah-celana mengutip untuk lulus urutan newline (\n) dalam string parameter. Kemudian kami menggunakan grep untuk menemukan baris yang berisi nama pemain dan menghitung mereka dengan wc. Akhirnya, kami mengurangi satu dari hasil untuk melawan kehadiran baris pertama (itu mengandung hanya Skor bebas-data terkait).

Sekarang kita berada di tahap refactoring TDD.

Aku hanya menyadari bahwa kode yang benar-benar bekerja untuk lebih dari satu titik per pemain, dan kita dapat refactor kami tes untuk mencerminkan hal ini. Mengubah fungsi tes di atas sebagai berikut:

Tiket masih tes. Waktu untuk melanjutkan dengan logika kami:

Dan implementasi:

Aku hanya memeriksa parameter kedua. Ini tampak seperti aku 'm kecurangan, tapi itu adalah kode sederhana untuk membuat tes yang lulus. Menulis tes lain memaksa kita untuk menambahkan lebih logika, tapi tes apa yang harus kita menulis berikutnya?

Ada dua jalur yang dapat kita ambil. Menguji jika menerima pemain kedua titik memaksa kita untuk menulis lain jika pernyataan, tetapi kita hanya perlu menambahkan pernyataan lain jika kita memilih untuk menguji titik kedua pemain pertama. Yang terakhir menunjukkan sebuah implementasi yang lebih mudah, jadi mari kita mencobanya:

Dan implementasi:

Ini masih terlihat kecurangan, tapi itu bekerja dengan sempurna. Melanjutkan untuk titik ketiga:

Implementasi:

If-elif-else ini mulai mengganggu saya. Saya ingin mengubahnya, tapi mari kita periksa kembali tes kami. Kami memiliki tiga tes yang sangat mirip; jadi mari kita tuliskan dalam satu tes yang menghasilkan tiga pernyataan:

Yang lebih baik, dan masih melewati. Sekarang, mari kita membuat tes serupa untuk pemain kedua:

Menjalankan tes ini menghasilkan output yang menarik:

Yah itu tidak terduga. Kami tahu bahwa Michael akan mendapatkan skor yang salah. Kejutannya adalah John; ia seharusnya memiliki 0 bukan 40. Mari kita perbaiki dengan terlebih dahulu memodifikasi ekspresi if-elif-else:

If-elif-else sekarang lebih kompleks, tetapi kami setidaknya memperbaiki skor John:

Sekarang mari kita perbaiki Michael:

Itu bekerja dengan baik! Sekarang saatnya untuk akhirnya memperbaiki ekspresi jelek jika-elif-lain:

Peta nilai luar biasa! Mari kita beralih ke kasus "Deuce":

Kami memeriksa "Deuce" ketika semua pemain memiliki setidaknya skor 40.

Sekarang kami menguji untuk keuntungan pemain pertama:

Dan untuk membuatnya lulus:

Ada yang jelek jika-elif-lagi, dan kami memiliki banyak duplikasi juga. Semua tes kami lulus, jadi mari kita refactor:

Ini akan bekerja untuk saat ini. Mari kita coba keuntungan untuk pemain kedua:

And the code:

Ini berfungsi, tetapi kami memiliki beberapa duplikasi dalam fungsi checkAdvantage. Mari kita sederhanakan dan menyebutnya dua kali:

Ini sebenarnya lebih baik daripada solusi kami sebelumnya, dan kembali ke implementasi asli dari metode ini. Tetapi sekarang kita memiliki masalah lain: Saya merasa tidak nyaman dengan variabel $1, $2, $3 dan $4. Mereka membutuhkan nama yang bermakna:

Hal ini membuat kode kita lagi, tapi itu secara signifikan lebih ekspresif. Saya menyukainya.

Saatnya untuk menemukan pemenang:

Kita hanya perlu memodifikasi fungsi checkAdvantageFor:

Kita hampir selesai! Sebagai langkah terakhir kami, kami akan menulis kode di tennisGame.sh untuk membuat lulus tes penerimaan. Ini akan cukup sederhana kode:

Kita membaca baris pertama untuk mengambil nama-nama dua pemain, dan kemudian kita secara bertahap membaca file untuk menghitung Skor.


Akhir pikiran

Skrip shell dapat dengan mudah tumbuh dari beberapa baris kode untuk beberapa ratus baris. Ketika ini terjadi, pemeliharaan menjadi semakin sulit. Menggunakan TDD dan pengujian unit dapat sangat membantu untuk membuat skrip yang kompleks yang lebih mudah untuk mempertahankan-bukan untuk menyebutkan bahwa memaksa Anda untuk membangun skrip kompleks dalam cara yang lebih profesional.

Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.