Berbagai metode pengujian
Pertama-tama tentukan apa yang Anda lakukan: Pengujian unit atau pengujian integrasi . Jumlah lapisan tidak relevan untuk pengujian unit karena Anda hanya menguji satu kelas yang paling mungkin. Sisanya yang kau tiru. Untuk pengujian integrasi, Anda dapat menguji beberapa lapisan. Jika Anda memiliki tes unit yang baik, triknya adalah membuat tes integrasi tidak terlalu rumit.
Jika pengujian unit Anda baik, Anda tidak perlu mengulangi pengujian semua detail saat melakukan pengujian integrasi.
Istilah yang kami gunakan, itu sedikit tergantung platform, tetapi Anda dapat menemukannya di hampir semua platform pengujian / pengembangan:
Contoh aplikasi
Tergantung pada teknologi yang Anda gunakan, nama mungkin berbeda, tetapi saya akan menggunakan ini sebagai contoh:
Jika Anda memiliki aplikasi CRUD sederhana dengan Model produk, ProductsController, dan tampilan indeks yang menghasilkan tabel HTML dengan produk:
Hasil akhir dari aplikasi ini memperlihatkan tabel HTML dengan daftar semua produk yang aktif.
Pengujian unit
Model
Model yang dapat Anda uji cukup mudah. Ada berbagai metode untuk itu; kami menggunakan perlengkapan. Saya pikir itu yang Anda sebut "set data palsu". Jadi sebelum setiap tes dijalankan, kita membuat tabel, dan memasukkan data asli. Sebagian besar platform memiliki metode untuk ini. Misalnya, di kelas pengujian Anda, metode setUp () yang dijalankan sebelum setiap tes.
Kemudian kami menjalankan pengujian kami, misalnya: produk testGetAllActive .
Jadi kami menguji langsung ke database uji. Kami tidak mencemooh sumber data; kami membuatnya selalu sama. Sebagai contoh, ini memungkinkan kami untuk menguji dengan versi baru dari database, dan masalah kueri akan muncul.
Di dunia nyata Anda tidak dapat selalu mengikuti 100% tanggung jawab tunggal . Jika Anda ingin melakukan ini lebih baik, Anda bisa menggunakan sumber data yang Anda tiru. Bagi kami (kami menggunakan ORM) yang rasanya seperti menguji teknologi yang sudah ada. Juga tes menjadi jauh lebih kompleks, dan mereka tidak benar-benar menguji kueri. Jadi kita tetap seperti ini.
Data kode keras disimpan secara terpisah dalam perlengkapan. Jadi fixture-nya seperti file SQL dengan tabel buat pernyataan dan sisipan untuk catatan yang kita gunakan. Kami menjaga mereka tetap kecil kecuali ada kebutuhan nyata untuk menguji dengan banyak catatan.
class ProductModel {
public function getAllActive() {
return $this->find('all', array('conditions' => array('active' => 1)));
}
}
Pengendali
Pengontrol membutuhkan lebih banyak pekerjaan, karena kami tidak ingin menguji model dengan itu. Jadi yang kita lakukan adalah mengejek model. Itu berarti: Kami menguji: index () metode yang harus mengembalikan daftar catatan.
Jadi kita mengejek metode model getAllActive () keluar dan menambahkan data tetap di dalamnya (dua catatan misalnya). Sekarang kami menguji data yang dikirim oleh pengontrol ke tampilan, dan kami membandingkan jika kami benar-benar mendapatkan dua catatan itu kembali.
function testProductIndexLoggedIn() {
$this->setLoggedIn();
$this->ProductsController->mock('ProductModel', 'index', function(return array(your records) ));
$result=$this->ProductsController->index();
$this->assertEquals(2, count($result['products']));
}
Cukup. Kami mencoba menambahkan fungsionalitas sebagai sedikit ke controller karena itu membuat pengujian sulit. Tapi tentu saja selalu ada beberapa kode di dalamnya. Misalnya, kami menguji persyaratan seperti: Tampilkan dua catatan itu hanya jika Anda masuk.
Jadi, pengontrol membutuhkan satu tiruan secara normal dan sepotong kecil data yang dikodekan. Untuk sistem login mungkin yang lain. Dalam pengujian kami, kami memiliki metode pembantu untuk itu: setLoggedIn (). Itu membuatnya mudah untuk menguji dengan login atau tanpa login.
class ProductsController {
public function index() {
if($this->loggedIn()) {
$this->set('products', $this->ProductModel->getAllActive());
}
}
}
Tampilan
Pengujian tampilan sulit. Pertama kita memisahkan logika yang berulang. Kami memasukkannya ke dalam Pembantu dan menguji kelas-kelas itu dengan ketat. Kami mengharapkan output yang sama selalu. Misalnya, generateHtmlTableFromArray ().
Kemudian kami memiliki beberapa pandangan spesifik proyek. Kami tidak menguji itu. Tidak benar-benar diinginkan untuk menguji unit tersebut. Kami menyimpannya untuk pengujian integrasi. Karena kami mengambil banyak kode untuk dilihat, kami memiliki risiko yang lebih rendah di sini.
Jika Anda mulai menguji yang kemungkinan Anda perlu mengubah tes Anda setiap kali Anda mengubah sepotong HTML yang tidak berguna untuk sebagian besar proyek.
echo $this->tableHelper->generateHtmlTableFromArray($products);
Tes integrasi
Bergantung pada platform Anda di sini, Anda dapat bekerja dengan cerita pengguna, dll. Ini bisa berbasis web seperti Selenium atau solusi serupa lainnya.
Secara umum kami hanya memuat basis data dengan perlengkapan dan menegaskan data mana yang harus tersedia. Untuk pengujian integrasi penuh, kami biasanya menggunakan persyaratan yang sangat global. Jadi: Atur produk ke aktif lalu periksa apakah produk tersedia.
Kami tidak menguji semuanya lagi, seperti apakah bidang yang tepat tersedia. Kami menguji persyaratan yang lebih besar di sini. Karena kami tidak ingin menduplikasi pengujian kami dari pengontrol atau tampilan. Jika ada sesuatu yang benar-benar kunci / inti dari aplikasi Anda atau untuk alasan keamanan (periksa kata sandi TIDAK tersedia) maka kami menambahkannya untuk memastikan itu benar.
Data kode keras disimpan di dalam fixture.
function testIntegrationProductIndexLoggedIn() {
$this->setLoggedIn();
$result=$this->request('products/index');
$expected='<table';
$this->assertContains($expected, $result);
// Some content from the fixture record
$expected='<td>Product 1 name</td>';
$this->assertContains($expected, $result);
}