Advertisement
  1. Code
  2. PHP

Panduan Pemula untuk Test-Driven Development

Scroll to top
Read Time: 12 min
This post is part of a series called Test-Driven PHP.
It's Time To Dig In
Test-Driven Development in PHP: First Steps

() translation by (you can also view the original English article)

Menguji kode Anda itu mengganggu, tetapi dampak tidak berbuat demikian dapat berlipat-lipat lebih menyebalkan! Dalam artikel ini, kita akan test-drive development untuk menulis dan menguji kode kita lebih efektif.


Apa yang dimaksud dengan Test-Driven Development?

Sejak fajar era komputer, programer dan bug telah berjuang untuk supremasi. Itu adalah kejadian yang tak terelakkan. Bahkan para programer terbesar mangsa anomali ini. Tidak ada kode aman. Itu sebabnya kita melakukan pengujian. Programmer, orang-orang yang setidaknya waras, tes kode mereka dengan menjalankan pada pengembangan mesin untuk memastikan itu apa yang seharusnya.


programmer waras adalah yang mengetes programnya.
Gambar milik http://www.youthedesigner.com

programmer Gila yang tidak mengetes programnya.
Gambar milik http://www.internetannoyanceday.com

Test-driven development adalah suatu teknik pemrograman yang mengharuskan Anda untuk menulis kode aktual dan otomatis tes kode secara bersamaan. Hal ini memastikan bahwa Anda menguji kode Anda- dan memungkinkan Anda untuk tes ulang kode cepat dan mudah, karena hal ini otomatis.

Bagaimana cara kerjanya?

Test-driven development, atau TDD seperti yang kita akan menyebutnya sekarang berkisar sekitar pendek iteratif pengembangan siklus yang pergi sesuatu seperti ini:

  1. Sebelum menulis kode apapun, Anda harus terlebih dahulu menulis tes otomatis untuk kode Anda. Saat menulis tes otomatis, Anda harus memperhitungkan semua mungkin input, kesalahan, dan output. Dengan cara ini, pikiran Anda tidak tertutup oleh setiap kode yang sudah ditulis.
  2. Pertama kali Anda menjalankan tes Anda otomatis, tes harus gagal — menunjukkan bahwa kode belum siap.
  3. Setelah itu, Anda dapat memulai pemrograman. Karena sudah ada tes otomatis, asalkan kode gagal itu, itu berarti bahwa itu masih belum siap. Kode ini dapat diperbaiki sampai sukses semua assertion.
  4. Setelah kode sukses melewati ujian, Anda dapat mulai pembersihan itu, melalui refactoring. Selama kode masih melewati ujian, itu berarti bahwa ia masih bekerja. Anda tidak lagi perlu khawatir tentang perubahan yang memperkenalkan bug baru.
  5. Seluruh hal mulai dari awal lagi dengan beberapa metode lain atau program.

Bagus, tetapi bagaimana Apakah ini lebih baik daripada regular testing?

Apakah Anda pernah sengaja melewatkan pengujian program karena:

  • Anda merasa itu membuang-buang waktu untuk menguji, karena itu hanya perubahan kode sedikit?
  • Anda merasa malas menguji semuanya lagi?
  • Anda tidak memiliki cukup waktu untuk menguji karena manajer proyek ingin itu pindah ke produksi ASAP?
  • Anda mengatakan kepada diri sendiri Anda akan melakukannya "besok"?
  • Anda harus memilih antara manual testing, atau menonton episode terbaru dari acara TV favorit Anda (Big Bang Theory)?

Sebagian besar waktu, tidak ada yang terjadi, dan Anda berhasil memindahkan kode produksi tanpa masalah. Tapi kadang-kadang, setelah Anda sudah pindah ke produksi, segala sesuatu menjadi tidak beres. Anda terjebak memperbaiki seratus lubang di kapal yang tenggelam, dengan lebih banyak muncul setiap menit. Anda tidak ingin untuk menemukan diri dalam situasi ini.

TDD dimaksudkan untuk menghilangkan alasan kami. Ketika program telah dikembangkan menggunakan TDD, memungkinkan kita untuk membuat perubahan dan menguji dengan cepat dan efisien. Kita perlu lakukan adalah menjalankan tes otomatis, dan voila! Jika sukses semua otomatis tes, maka kita sedang baik untuk pergi-jika tidak, maka itu hanya berarti kita melanggar sesuatu dengan perubahan. Dengan mengetahui bagian mana testing yang gagal, itu juga memungkinkan kita untuk dengan mudah menunjukkan di bagian mana perubahan itu pecah, sehingga memperbaiki bug yang lebih mudah.


Aku dijual. Bagaimana kita melakukan ini?

Ada banyak otomatis pengujian Framework PHP luar sana yang kita dapat gunakan. Salah satu framework pengujian yang paling banyak digunakan adalah PHPUnit.

PHPUnit adalah framework pengujian yang bagus, yang dapat dengan mudah diintegrasikan ke dalam proyek Anda sendiri, atau proyek-proyek lain yang dibangun di atas framework PHP yang populer.

Untuk tujuan kita, kita tidak perlu banyak fungsi yang menawarkan PHPUnit. Sebaliknya, kita akan memilih untuk membuat pengujian kami menggunakan banyak lebih mudah pengujian framework, disebut SimpleTest.

Pada langkah berikutnya, mari kita asumsikan bahwa kami sedang mengembangkan sebuah aplikasi guestbook mana setiap pengguna dapat menambahkan dan lihat guestbook entries. Mari kita asumsikan bahwa markup telah selesai, dan bahwa kita hanya membuat class yang berisi logika aplikasi buku tamu, yang adalah di mana aplikasi menyisipkan dan membaca ke database. Membaca bagian dari class ini adalah apa yang akan kita untuk mengembangkan dan menguji.


Langkah 1. Mengatur SimpleTest

Ini adalah dapat dikatakan sebagai suatu langkah paling mudah dari semua. Bahkan orang ini bisa melakukannya:


Saya bisa melakukan ini... Dapat saya gunakan, saya, UMM... otak!
Gambar milik http://longstreet.typepad.com/

Download SimpleTest di sini, dan ekstrak ke folder pilihan Anda--sebaiknya folder dimana Anda akan mengembangkan kode Anda, atau Anda include_path PHP untuk memudahkan akses.

Untuk tutorial ini, saya telah membuat folder seperti:

Index.php akan menjalankan guestbook.php, dan memanggil metode view dan menampilkan entri. Di dalam class folder adalah dimana kami akan menempatkan guestbook.php kelas, dan test folder adalah di mana kita menempatkan simpletest Perpustakaan.


Langkah 2. Rencanakan serangan Anda

Langkah kedua, yang benar-benar yang paling penting, adalah untuk mulai membuat tes Anda. Untuk ini, Anda benar-benar perlu untuk merencanakan dan berpikir tentang apa fungsi yang Anda akan lakukan, input apa mungkin itu akan, dan Keluaran sesuai akan dikirim. Langkah ini menyerupai bermain permainan catur — Anda perlu tahu segala sesuatu tentang lawan (program), termasuk semua kelemahan (kemungkinan kesalahan) dan kekuatan (apa yang terjadi jika berhasil berjalan).

Jadi untuk aplikasi buku tamu kami, mari kita berbaring skema:

View

  • Fungsi ini tidak akan ada masukan karena hanya akan mengambil semua entri dari database dan mengirimkan data yang dicetak.
  • Itu akan mengembalikan sebuah array catatan guestbook, menyatakan nama poster dan pesannya. Jika tidak ada catatan, maka itu masih harus mengembalikan array kosong.
  • Jika terdapat catatan, array akan memiliki nilai 1 atau lebih di dalamnya.
  • Pada saat yang sama, array akan memiliki struktur yang spesifik, seperti:
1
Array (
2
    [0] => Array (
3
        ['name'] = "Bob"
4
        ['message'] = "Hi, I'm Bob."
5
    )
6
    [1] => Array (
7
        ['name'] = "Tom"
8
        ['message'] = "Hi, I'm Tom."
9
    )
10
)

Langkah 3. Menulis tes!

Sekarang, kita dapat menulis ujian pertama kami. Mari kita mulai dengan menciptakan sebuah file bernama guestbook_test.php di dalam folder tes.

1
<?php
2
require_once(dirname(__FILE__) . '/simpletest/autorun.php');
3
require_once('../classes/guestbook.php');
4
5
class TestGuestbook extends UnitTestCase {
6
  
7
}

Kemudian, mari kita mengubah apa yang kita sudah ditentukan dari langkah dua,.

1
<?php
2
require_once(dirname(__FILE__) . '/simpletest/autorun.php');
3
require_once('../classes/guestbook.php');
4
5
class TestGuestbook extends UnitTestCase {
6
    function testViewGuestbookWithEntries()
7
	{
8
		$guestbook = new Guestbook();
9
		// Add new records first

10
		$guestbook->add("Bob", "Hi, I'm Bob.");
11
		$guestbook->add("Tom", "Hi, I'm Tom.");
12
		$entries = $guestbook->viewAll();
13
		
14
		$count_is_greater_than_zero = (count($entries) > 0);
15
		$this->assertTrue($count_is_greater_than_zero);
16
		$this->assertIsA($entries, 'array');
17
		foreach($entries as $entry) {
18
			$this->assertIsA($entry, 'array');
19
			$this->assertTrue(isset($entry['name']));
20
			$this->assertTrue(isset($entry['message']));
21
		}
22
	}
23
	
24
	function testViewGuestbookWithNoEntries()
25
	{
26
		$guestbook = new Guestbook();
27
		$guestbook->deleteAll(); // Delete all the entries first so we know it's an empty table

28
		$entries = $guestbook->viewAll();
29
		$this->assertEqual($entries, array());
30
	}
31
}

Assertion pastikan bahwa hal tertentu adalah apa yang seharusnya terjadi — pada dasarnya, memastikan bahwa apa yang dikembalikan adalah apa yang Anda harapkan untuk dikembalikan. Misalnya, jika fungsi seharusnya mengembalikan nilai true jika berhasil, maka dalam pengujian kami, kita harus menegaskan bahwa nilai mengembalikan sama dengan true.

Seperti yang Anda lihat di sini, kami menguji melihat buku tamu dengan entri dan tanpa. Kami memeriksa jika ini dua skenario melewati kriteria kami dari langkah dua. Anda mungkin juga menyadari bahwa setiap tes kita fungsi dimulai dengan kata 'test'. Kami melakukan ini karena, ketika SimpleTest menjalankan kelas ini, ia akan mencari semua fungsi yang mulai dengan kata 'test' dan menjalankannya.

Dalam class eksperimen kami, kami juga telah menggunakan beberapa metode assertion, seperti assertTrue, assertIsA dan assertEquals. Fungsi assertTrue cek apakah nilainya true. AssertIsA memeriksa apakah variabel jenis atau class tertentu. Dan akhirnya, assertEquals cek jika sebuah variabel benar-benar sama dengan nilai tertentu.

Ada metode assertion lain disediakan oleh SimpleTest, yang:

assertTrue($x) Gagal jika $x false
assertFalse($x) Gagal jika $x true
assertNull($x) Gagal jika $x di set
assertNotNull($x) Gagal jika $x tidak di set
assertIsA ($x, $t) Gagal jika $x bukan class atau jenis $t
assertNotA ($x, $t) Gagal jika $x adalah class atau jenis $t
assertEqual ($x, $y) Gagal jika $x == $y adalah false
assertNotEqual ($x, $y) Gagal jika $x == $y adalah true
assertWithinMargin ($x, $y, $m) Gagal jika abs($x-$y) < $m adalah false
assertOutsideMargin ($x, $y, $m) Gagal jika abs($x-$y) < $m adalah true
assertIdentical ($x, $y) Gagal jika $x == $y adalah false atau jenis ketidakcocokan
assertNotIdentical ($x, $y) Gagal jika $x == $y adalah true dan sesuai dengan jenis
assertReference ($x, $y) Gagal kecuali $x dan $y adalah variabel yang sama
assertClone ($x, $y) Gagal kecuali $x dan $y salinan identik
assertPattern ($p, $x) Gagal kecuali regex $p sesuai $x
assertNoPattern ($p, $x) Gagal jika regex $p sesuai $x
expectError($x) Menelan kesalahan pencocokan mendatang
assert($e) Gagal pada objek expectation gagal $e

Daftar metode assertion milik http://www.simpletest.org/en/unit_test_documentation.html


Langkah 4. Gagal menang

Setelah Anda selesai menulis kode, Anda harus menjalankan tes. Pertama kali Anda menjalankan tes, itu harus gagal. Jika tidak, maka itu berarti bahwa tes Anda tidak benar-benar menguji apa-apa.

Untuk menjalankan tes Anda, cukup menjalankan guestbook_test.php di browser Anda. Anda harus melihat ini pertama:

Hal ini terjadi karena kami belum membuat class guestbook. Untuk melakukannya, buat guestbook.php di dalam folder classes. class harus berisi metode kami berencana untuk digunakan, tetapi seharusnya tidak mengandung apapun yang belum pada awalnya. Ingat, kita sedang menulis tes pertama sebelum menulis kode apapun.

1
<?php
2
class Guestbook
3
{
4
	
5
	public function viewAll() {
6
	
7
	}
8
	
9
	public function add( $name, $message ) {
10
11
	}
12
	
13
	public function deleteAll() {
14
		
15
	}
16
}

Ketika Anda menjalankan tes lagi, seharusnya terlihat seperti ini:

Seperti yang kita lihat di sini, ujian kami sekarang adalah dimenangkan oleh gagal. Ini berarti bahwa ujian kami sekarang siap untuk mendapatkan "jawaban."


Langkah 5. Menjawab tes Anda dengan menulis kode


Di beberapa titik, kita semua merasa seperti ini ketika kami pemrograman.
Gambar milik http://fermentation.typepad.com/fermentation

Sekarang bahwa kita memiliki tes otomatis bekerja, kita dapat mulai menulis kode. Membuka class guestbook.php Anda dan mulai membuat jawaban untuk tes Anda.

1
<?php
2
class Guestbook
3
{
4
	// To save time, instead of creating and connecting to a database, we're going to

5
	// simulate a "database" by creating a static entries array here.

6
	// It will be like we have two entries in the table.

7
	
8
	private static $_entries = array(
9
		array (
10
			'name' => 'Kirk',
11
			'message' => 'Hi, I\'m Kirk.'
12
		),
13
		array (
14
			'name' => 'Ted',
15
			'message' => 'Hi, I\'m Ted.'
16
		)
17
	);
18
	
19
	public function viewAll() {
20
		// Here, we should retrieve all the records from the database.

21
		// This is simulated by returning the $_entries array

22
		return self::$_entries;
23
	}
24
	
25
	public function add( $name, $message ) {
26
		// Here, we simulate insertion into the database by adding a new record into the $_entries array

27
		// This is the correct way to do it: self::$_entries[] = array('name' => $name, 'message' => $message );

28
		self::$_entries[] = array('notname' => $name, 'notmessage' => $message ); //oops, there's a bug here somewhere

29
		return true;
30
	}
31
	
32
	public function deleteAll() {
33
		// We just set the $_entries array to simulate 

34
		self::$_entries = array();
35
		return true;
36
	}
37
}

class guestbook.php ini memiliki beberapa bug di dalamnya sengaja, sehingga kita dapat melihat apa yang tampak seperti apa jika tes gagal.

Setelah kami jalankan pengujian kami, kami harus melihat sesuatu seperti ini:

Hasil tes menunjukkan kepada kita di tes mana assertion kode gagal Dari ini, kita dapat dengan mudah menunjukkan bahwa baris 16 dan 17 adalah assertion yang melemparkan error.

1
<?php
2
require_once(dirname(__FILE__) . '/simpletest/autorun.php');
3
require_once('../classes/guestbook.php');
4
5
class TestGuestbook extends UnitTestCase {
6
...
7
...
8
...
9
	$this->assertTrue(isset($entry['name']));
10
	$this->assertTrue(isset($entry['message']));
11
...
12
...
13
...
14
}

Ini jelas menjelaskan bahwa array mengembalikan entri tidak memiliki key yang benar. Berdasarkan hal ini, kita dengan mudah akan tahu bagian mana dari kode yang salah.

1
<?php
2
class Guestbook
3
{
4
...
5
...
6
...
7
	public function add( $name, $message ) {
8
		// Here, we simulate insertion into the database by adding a new record into the $_entries array

9
		self::$_entries[] = array('name' => $name, 'message' => $message ); //fixed!

10
		return true;
11
	}
12
...
13
...
14
...
15
}

Sekarang, ketika kita menjalankan pengujian kami lagi, itu harus menunjukkan kita:


Langkah 6. Refactor dan memperbaiki kode Anda

Karena kode kita sedang menguji di sini cukup sederhana, kami pengujian dan memperbaiki bug tidak bertahan lama. Tetapi jika ini adalah sebuah aplikasi yang lebih kompleks, Anda harus membuat beberapa perubahan kode Anda, membuatnya bersih sehingga lebih mudah untuk mempertahankan, dan banyak hal lainnya. Masalah dengan ini, meskipun, adalah bahwa perubahan biasanya memperkenalkan tambahan bug. Ini adalah tempat tes otomatis kami datang-sekali kita melakukan perubahan, kita hanya dapat menjalankan tes lagi. Jika itu masih sukses, maka itu berarti kami tidak merusak apa-apa. Jika gagal, kita tahu bahwa kita melakukan kesalahan. Itu juga memberitahu kita dimana masalahnya, dan, mudah-mudahan, bagaimana kami dapat memperbaikinya.


Langkah 7. Bilas dan ulangi

Akhirnya, ketika program Anda memerlukan fungsi baru, Anda akan perlu untuk menulis tes baru. Itu mudah! Bilas dan ulangi prosedur langkah dua (karena file SimpleTest Anda harus sudah dibentuk), dan memulai siklus lagi.


Kesimpulan

Ada lebih banyak artikel mendalam test-driven development di luar sana, dan bahkan lebih fungsionalitas untuk SimpleTest daripada apa yang ditampilkan dalam artikel ini — hal-hal seperti mock objek, Indonesia, yang membuatnya lebih mudah untuk membuat tes. Jika Anda ingin membaca lebih lanjut, Wikipedia test-driven development halaman harus membuat Anda di sebelah jalan yang benar Jika Anda tertarik untuk menggunakan SimpleTest sebagai framework testing, browse dokumentasi online dan pastikan untuk memeriksa fitur lain.

Pengujian merupakan bagian integral dari siklus pengembangan, namun, itu terlalu sering hal pertama yang akan dipotong ketika tenggat waktu dekat. Mudah-mudahan, setelah membaca artikel ini, Anda akan menghargai bagaimana membantu itu adalah untuk berinvestasi dalam test-driven development.

Apakah pikiran Anda pada Test-Driven Development? Itu sesuatu yang Anda terapkan, atau apakah Anda pikir itu membuang-buang waktu? Beritahu saya di komentar!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
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.