Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development
Code

Alur kerja BDD dengan Behat dan Phpspec

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Arief Syahrir (you can also view the original English article)

Dalam tutorial ini, kita akan melihat dua tool BDD berbeda, Behat dan phpspec, dan melihat bagaimana mereka dapat mendukung Anda dalam proses pengembangan Anda. Belajar BDD dapat membingungkan. Metodologi baru, tool-tool baru dan banyak pertanyaan, seperti "apa yang harus diuji?" dan "tool apa yang digunakan?". Saya berharap bahwa contoh agak sederhana ini akan memberi Anda ide untuk bagaimana Anda dapat memasukkan BDD ke dalam alur kerja Anda sendiri.

Inspirasi saya

Saya terinspirasi untuk menulis tutorial ini oleh Taylor Otwell, pencipta Laravel framework. Beberapa kali, aku telah mendengar Taylor menjelaskan mengapa sebagian besar tidak dilakukannya TDD BDD dengan mengatakan bahwa dia suka untuk pertama merencanakan API kode nya, sebelum benar-benar mulai untuk menerapkannya. Aku telah mendengar ini dari banyak pengembang, dan setiap kali saya berpikir untuk diri sendiri: "Tapi itu adalah kasus penggunaan sempurna untuk TDD/BDD!". Taylor mengatakan bahwa dia suka untuk memetakan API kode nya, dengan menulis kode yang berharap dia punya. Ia akan memulai coding dan tidak akan puas sampai dia telah mencapai API yang tepat. Argumen masuk akal jika Anda hanya menguji/speccing pada tingkat unit, tetapi menggunakan alat seperti Behat, Anda mulai dengan perilaku eksternal perangkat lunak Anda, yang pada dasarnya, sejauh yang saya mengerti, apa yang ingin Taylor capai.

Apa yang akan kita cakup

Dalam tutorial ini, kita akan membangun class loader file konfigurasi sederhana. Kita akan mulai dengan menggunakan pendekatan Taylor dan kemudian beralih ke pendekatan BDD sebagai gantinya. Contoh minimalis, tapi tetap kita harus khawatir tentang fixture, static metode dll, jadi All-in-semua, saya pikir mereka harus cukup untuk menunjukkan bagaimana Behat dan phpspec dapat saling melengkapi.

Disclaimer: Pertama-tama, artikel ini bukanlah panduan memulai. Ini mengasumsikan pengetahuan dasar BDD, Behat dan phpspec. Anda telah mungkin sudah melihat ke dalam tool ini, tetapi masih berjuang dengan cara benar-benar menggunakan mereka dalam alur kerja harian Anda. Jika Anda ingin mempelajari lagi pada phpspec, lihatlah saya memulai tutorial. Kedua dari semua, saya menggunakan Taylor Otwell sebagai contoh. Aku tidak tahu apa-apa tentang bagaimana bekerja Taylor, selain apa yang aku mendengar dia berkata dalam podcast dll. Saya menggunakan dia sebagai contoh karena ia adalah pengembang yang mengagumkan (ia dibuat Laravel!) dan karena ia terkenal. Saya mungkin juga telah menggunakan orang lain, karena sebagian besar pengembang, termasuk saya sendiri, tidak melakukan BDD sepanjang waktu, belum. Juga, saya tidak mengatakan bahwa alur kerja Taylor itu buruk. Saya pikir itu adalah ide cemerlang untuk menaruh beberapa pemikiran ke dalam kode Anda sebelum benar-benar menulis itu. Tutorial ini hanya dimaksudkan untuk menunjukkan BDD untuk melakukan hal ini.

Taylor's Workflow

Mari kita mulai dengan melihat bagaimana Taylor mungkin pergi tentang merancang loader file konfigurasi ini. Taylor mengatakan bahwa dia suka menulis sebuah file teks kosong di editor dan kemudian menulis bagaimana ia ingin pengembang untuk dapat berinteraksi dengan kode nya (API). Dalam konteks BDD, ini biasanya disebut sebagai testing external behavior perangkat lunak dan tool seperti Behat bagus untuk ini. Kita akan melihat ini dalam waktu singkat.

Pertama, mungkin Taylor akan membuat keputusan tentang file konfigurasi. Bagaimana mereka harus bekerja? Seperti Laravel, mari kita hanya menggunakan array PHP yang sederhana. Contoh konfigurasi file bisa terlihat seperti ini:

Selanjutnya, bagaimana harus menggunakan kode yang membuat file konfigurasi ini bekerja? Mari kita melakukan ini dengan cara Taylor dan hanya menulis kode yang kami berharap bisa memiliki:

Oke, jadi ini terlihat cukup bagus. Pertama kita memiliki panggilan statis untuk fungsi load(), diikuti oleh tiga case digunakan:

  1. Mendapatkan "timezone" dari file konfigurasi.
  2. Mendapatkan nilai default, jika "timezone" belum dikonfigurasi.
  3. Mengubah pilihan konfigurasi dengan setting untuk sesuatu yang lain. Kami akan menjelaskan setiap kasus penggunaan, atau skenario, dengan Behat dalam waktu singkat.

Masuk akal untuk menggunakan Behat untuk hal-hal ini. Behat tidak akan memaksa kita untuk membuat keputusan desain - kami memiliki phpspec untuk itu. Kita hanya akan bergerak persyaratan, yang kita baru saja dijelaskan, menjadi fitur Behat untuk memastikan bahwa kita mendapatkan yang benar, ketika kita mulai membangun. Fitur behat kami akan berfungsi sebagai acceptance tes untuk persyaratan kami sehingga untuk berbicara.

Jika Anda melihat kode kita menulis, alasan lain untuk menggunakan Behat, bukan hanya phpspec, adalah static call. Hal ini tidak mudah untuk menguji static meteode, terutama jika Anda hanya menggunakan tool seperti phpspec. Kita akan melihat bagaimana kita bisa pergi tentang hal ini ketika kita memiliki Behat dan phpspec yang tersedia.

Setup

Dengan asumsi Anda menggunakan Composer, mengatur Behat dan phspec adalah super sederhana dua langkah proses.

Pertama, Anda perlu file composer.json dasar. Ini memasukan Behat dan phpspec, dan menggunakan psr-4 untuk autoload class:

Menjalankan composer install untuk mengambil dependensi.

phpspec tidak membutuhkan konfigurasi apapun untuk menjalankan, sedangkan Behat membutuhkan untuk menjalankan perintah berikut untuk menghasilkan sebuah scaffold dasar:

Itu adalah semua yang diperlukan. Ini tidak dapat menjadi alasan Anda untuk tidak melakukan BDD!

Perencanaan fitur dengan Behat

Jadi, sekarang semuanya sudah diatur, kami siap untuk mulai melakukan BDD. Karena melakukan BDD berarti menginstal dan menggunakan Behat dan phpspec, kan?

Sejauh yang saya prihatin, kita sudah mulai melakukan BDD. Kami secara efektif telah menggambarkan perilaku eksternal perangkat lunak kami. Kami "klien" dalam contoh ini adalah pengembang, yang akan berinteraksi dengan kode kita. Dengan "efektif", saya berarti bahwa kami telah menggambarkan perilaku dengan cara yang mereka akan mengerti. Kita bisa mengambil kode yang kita telah digariskan, memasukkannya ke dalam README file, dan setiap PHP pengembang akan memahami penggunaan itu. Jadi ini sebenarnya cukup bagus, tapi aku punya dua hal penting untuk dicatat ini. Pertama-tama, menggambarkan perilaku perangkat lunak menggunakan kode hanya bekerja dalam contoh ini karena "klien" programmer. Biasanya, kami uji sesuatu yang akan digunakan oleh orang-orang yang "normal". Bahasa manusia lebih baik daripada PHP ketika kita ingin berkomunikasi dengan manusia. Kedua dari semua, mengapa tidak mengotomatisasi ini? Aku tidak akan berdebat mengapa ini mungkin ide yang baik.

Itu yang dikatakan, saya pikir mulai menggunakan Behat sekarang akan menjadi keputusan yang masuk akal.

Menggunakan Behat, kami ingin menjelaskan masing-masing skenario yang telah kita dijelaskan di atas. Kami tidak ingin untuk menutupi luas setiap edge case yang terlibat dalam menggunakan perangkat lunak. Kami memiliki phpspec tersedia jika ini harus dibutuhkan untuk memperbaiki bug di sepanjang jalan dll. Saya pikir banyak pengembang, mungkin termasuk Taylor, merasa seperti mereka harus memikirkan semuanya dan memutuskan segala sesuatu sebelum mereka dapat menulis tes dan spesifikasi. Itulah sebabnya mengapa mereka memilih untuk memulai tanpa BDD, karena mereka tidak ingin memutuskan segala sesuatu terlebih dahulu. Hal ini tidak terjadi dengan Behat, karena kita menggambarkan perilaku eksternal dan penggunaan. Untuk menggunakan Behat untuk menggambarkan fitur, kita tidak perlu memutuskan apa-apa lebih dari pada contoh di atas dengan menggunakan file teks mentah. Kita hanya perlu untuk menentukan persyaratan fitur - dalam kasus ini API eksternal class loader file konfigurasi.

Sekarang, mari kita ambil kode PHP di atas dan mengubahnya menjadi Behat fitur, yang menggunakan bahasa Inggris (benar-benar menggunakan bahasa Gherkin).

Membuat file di features/ direktori, disebut config.feature, dan mengisi skenario berikut:

Dalam fitur ini, kami menggambarkan, dari luar, bagaimana "pengembang" akan mampu menyimpan pilihan konfigurasi. Kita tidak peduli tentang perilaku internal - kami akan ketika kita mulai menggunakan phpspec. Asalkan fitur ini berjalan hijau, kita tidak peduli apa yang terjadi di belakang layar.

Mari kita menjalankan Behat dan melihat apa yang dipikirkan fitur:

Dengan perintah ini, kami memberitahukan Behat untuk menambahkan definisi langkah penting untuk feature context. Aku tidak akan pergi lebih detal tentang Behat, tapi ini menambah sekelompok metode kosong FeatureContext class kami yang memetakan ke langkah fitur kami di atas.

Sebagai contoh, lihatlah definisi langkah bahwa Behat ditambahkan langkah there is a configuration file yang kami gunakan sebagai langkah "Given" semua tiga skenario:

Sekarang, Semua harus kita lakukan adalah untuk mengisi beberapa kode untuk menggambarkan hal ini.

Menulis langkah definisi

Sebelum kita mulai, saya punya dua hal penting untuk membuat tentang definisi langkah:

  1. Intinya adalah untuk membuktikan bahwa perilaku sekarang, adalah tidak seperti yang kita inginkan menjadi. Setelah itu, kita bisa mulai untuk merancang kode kita, sebagian besar waktu menggunakan phpspec, untuk mendapatkan hijau.
  2. Implementasi langkah definisi tidak penting - kita hanya perlu sesuatu yang bekerja dan mencapai "1". Kita dapat refactor kemudian.

Jika Anda menjalankan vendor/bin/behat, Anda akan melihat bahwa semua skenario sekarang telah pending.

Kita mulai dengan langkah Given there is a configuration file. Kita akan menggunakan fixture file konfigurasi, sehingga kita dapat menggunakan metode statis load() kemudian. Kita peduli tentang metode statis load() karena hal itu memberikan kita API Config::load() , banyak seperti Laravel facade. Langkah ini dapat diterapkan dalam berbagai cara. Untuk sekarang, saya pikir kita harus hanya memastikan bahwa kita memiliki fixture yang tersedia dan bahwa hal itu berisi array:

Kita akan menuju ke hijau dengan langkah ini tanpa menerapkan kode apapun selain membuat fixture tersebut. Tujuan dari langkah Given adalah untuk meletakkan sistem dalam keadaan yang dikenal. Dalam kasus ini, itu berarti memastikan kita memiliki file konfigurasi.

Untuk langkah hijau pertama kami, kita hanya perlu untuk membuat fixture:

Selanjutnya, kita memiliki langkah And, yang dalam kasus ini adalah hanya sebuah alias untuk Given. Kami ingin memastikan bahwa file konfigurasi berisi pilihan untuk timezone. Sekali lagi, ini hanya berhubungan dengan fixture kami, jadi kami tidak peduli banyak tentang hal itu. Aku membanting kode berikut (hackish) bersama-sama untuk mencapai hal ini:

Kode di atas tidak cantik, tapi accomplishes apa yang perlu. Hal ini memungkinkan kita memanipulasi fixture kami dari dalam fitur kami. Jika Anda menjalankan Behat, Anda akan melihat bahwa itu menambahkan opsi "timezone" untuk config.php fixture:

Sekarang adalah waktu untuk membawa beberapa asli "Taylor kode"! Langkah When I load the configuration file akan terdiri dari kode yang kita benar-benar peduli tentang. Kami akan membawa beberapa kode dari file teks mentah dari sebelumnya, dan pastikan bahwa itu berjalan:

Menjalankan Behat, tentu ini akan gagal, karena Config belum ada. Mari kita membawa phpspec untuk menyelamatkannya!

Merancang dengan Phpspec

Ketika kita menjalankan Behat, kita akan mendapatkan kesalahan fatal:

Untungnya, kami memiliki phpspec yang tersedia, termasuk Kode Generator yang mengagumkan.

Dengan perintah ini, phpspec dibuat dua file berikut untuk kami:

Hal ini membuat kita menyingkirkan kesalahan fatal pertama, tapi Behat masih tidak berjalan:

load() akan menjadi metode statis dan dengan demikian, adalah tidak mudah specced dengan phpspec. Untuk dua alasan ini adalah OK, meskipun:

  1. Perilaku metode load() yang akan menjadi sangat sederhana. Jika kita membutuhkan lebih kompleksitas nanti, kita dapat mengekstrak logika untuk dapat diuji metode kecil.
  2. Perilaku, seperti untuk sekarang, ditutupi dengan cukup baik oleh Behat. Jika metode tidak memuat file ke dalam sebuah array dengan benar, Behat akan squirk pada kami.

Ini adalah salah satu situasi dimana banyak pengembang akan menabrak dinding. Mereka akan membuang phpspec dan menyimpulkan bahwa itu menyebalkan dan bekerja melawan mereka. Tapi, melihat seberapa baik Behat dan phpspec yang saling melengkapi di sini?

Daripada mencoba untuk mendapatkan 100% cakupan dengan phpspec, mari kita hanya menerapkan fungsi sederhana load() dan menjadi yakin bahwa ditutupi oleh Behat:

Kami cukup yakin bahwa opsi-opsi konfigurasi kami sekarang dimuat. Jika tidak, sisa langkah kami akan gagal dan kita dapat melihat ke dalam ini lagi.

Membangun fitur dengan iterasi

Kembali ke hijau dengan Behat dan phpspec, kita dapat sekarang melihat langkah fitur berikutnya Then I should get 'UTC' as 'timezone' option.

Dalam langkah ini kita menulis lebih dari kode yang kami berharap bisa memiliki. Menjalankan Behat meskipun, kita akan melihat bahwa kita tidak memiliki get() metode yang tersedia:

Saatnya untuk kembali ke phpspec dan menyelesaikan masalah ini.

Pengujian accesor dan mutators, AKA Getter dan setter, adalah hampir seperti itu lama dillemma ayam atau telur. Bagaimana kita dapat menguji get() metode jika kita belum memiliki set() metode dan sebaliknya. Bagaimana saya cenderung untuk pergi tentang hal ini adalah untuk hanya menguji keduanya sekaligus. Ini berarti bahwa kita benar-benar akan menerapkan fungsi untuk mengatur pilihan konfigurasi, walaupun kita tidak belum mencapai skenario itu .

Contoh berikut akan melakukannya:

Pertama, kita akan memiliki generator phpspec membantu kita memulai:

Sekarang, mari kita kembali ke hijau:

Dan, begitu:

Yang punya jalan panjang. Menjalankan Behat, kita melihat bahwa kita adalah baik ke kedua skenario sekarang. Selanjutnya, kita perlu untuk mengimplementasikan fitur default pilihan, karena get() hanya mengembalikan null sekarang.

Langkah fitur pertama serupa dengan yang kita menulis sebelumnya. Bukannya menambahkan pilihan ke array, kita akan unset itu:

Hal ini tidak cantik. Saya tahu! Kita pasti bisa refactor itu, karena kami berulang diri kita sendiri, tapi itu bukan cakupan tutorial ini.

Langkah kedua fitur juga tampak akrab, dan sebagian besar adalah copy dan paste dari sebelumnya:

get() mengembalikan null. Mari kita melompat ke phpspec dan menulis contoh untuk memecahkan masalah ini:

Pertama, kami memeriksa bahwa kita mendapatkan nilai default jika "pilihan" belum dikonfigurasi. Kedua, kami pastikan bahwa opsi default tidak menimpa opsi konfigurasi.

Pada pandangan pertama, phpspec mungkin tampak seperti berlebihan dalam hal ini, karena kami hampir menguji hal yang sama dengan Behat. Saya ingin menggunakan phpspec untuk spec edge-case meskipun, yang seperti yang tersirat dalam skenario. Dan juga, Generator kode dari phpspec benar-benar hebat. Saya menggunakannya untuk segalanya dan aku mendapati diriku bekerja lebih cepat setiap kali saya menggunakan phpspec.

Sekarang, phpspec menegaskan apa Behat telah mengatakan kepada kami:

Untuk mendapatkan kembali ke green, kita akan menambahkan "kembali awal" untuk get() metode:

Kami melihat bahwa phpspec sekarang bahagia:

Dan begitu adalah Behat, dan kita.

Kami selesai dengan skenario kedua kami dan memiliki satu tersisa untuk pergi. Untuk skenario terakhir, kita hanya perlu menulis definisi untuk dan And I set the 'timezone' configuration option to 'GMT' langkah:

Karena kita sudah diimplementasikan set() method, langkah ini sudah hijau:

Ringkasan

Semuanya sudah bagus dan hijau, jadi mari kita memiliki ringkasan cepat dan melihat apa yang telah kita capai.

Kami secara efektif telah menggambarkan perilaku eksternal loader file konfigurasi, pertama dengan menggunakan pendekatan Taylor's, dan kemudian dengan menggunakan pendekatan BDD tradisional. Selanjutnya, kami telah mengimplementasikan fitur, menggunakan phpspec untuk merancang dan menggambarkan perilaku internal. Contoh kami telah bekerja pada ini cukup sederhana, tetapi kita telah membahas dasar-dasar. Jika kita membutuhkan lebih kompleksitas, kita dapat melanjutkan apa yang sudah kita miliki . Menggunakan BDD, kami memiliki setidaknya tiga pilihan:

  1. Jika kita mengamati bug atau perlu mengubah beberapa internal perangkat lunak kami, kami dapat menjelaskan yang menggunakan phpspec. Menulis contoh gagal yang menampilkan bug dan menulis kode yang diperlukan untuk sampai ke hijau.
  2. Jika kita perlu menambahkan kasus penggunaan baru untuk apa yang kita miliki, kita dapat menambahkan sebuah skenario untuk config.feature. Kita dapat kemudian iteratively bekerja jalan melalui setiap langkah, menggunakan Behat dan phpspec.
  3. Jika kita perlu untuk mengimplementasikan fitur baru, seperti mendukung YAML file konfigurasi, kita dapat menulis fitur baru dan memulai lagi, menggunakan pendekatan kami telah digunakan selama tutorial ini.

Dengan konfigurasi dasar ini, kami memiliki tidak ada alasan untuk tidak menulis gagal tes atau spec, sebelum kita menulis kode kita. Apa yang telah ktia banguan sekarang dicover oleh tes, yang akan membuatnya jauh lebih mudah untuk bekerja dengan itu nantinya. Tambahkan ke bahwa, bahwa kode kita juga sepenuhnya didokumentasikan. Kasus penggunaan yang dijelaskan dalam bahasa Inggris dan cara kerja internal yang dijelaskan dalam spesifikasi kami. Dua hal ini akan membuatnya mudah bagi pengembang lain untuk memahami dan bekerja dengan basis kode.

Itu adalah harapan saya bahwa tutorial ini membantu Anda untuk lebih memahami bagaimana BDD dapat digunakan dalam konteks PHP, dengan Behat dan phpspec. Jika Anda memiliki pertanyaan atau komentar, silahkan post di bawah ini di bagian komentar.

Terima kasih sudah membaca!

Advertisement
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.