Trong quá trình phát triển phần mềm luôn có phần testing, đặc biệt với PHP có một Framework testing nổi tiếng mà ai cũng biết đó là PHPUnit test, tuy nhiên nó vẫn còn những hạn chế. Hôm nay tôi sẽ giới thiệu cho các bạn một Framework testing mà nó bao gồm đầy đủ các tính năng của PHPUnit test và những tính năng khác mà PHPUnit test không có được, đó là Codeception.
Codeception là một framework testing có hỗ trợ cho nhiều PHP framework chẳng hạn như Symfony, Laravel5, Yii2, Zend Framework. Ngoài ra nó còn cung cấp tính năng Code generator nên ta có thể tạo test code một cách đơn giản và nhanh chóng.
Code generator
Gõ lệnh:
./codecept list
Như ta thấy có rất nhiều lệnh để sinh code 1 cách tự động. Trước tiên điều cần làm là tạo 1 file config generate:suite, sau đó dựa vào file config đó ta có thể tạo ra các chương trình test 1 cách dễ dàng.
generate
generate:cept Generates empty Cept file in suite
generate:cest Generates empty Cest file in suite
generate:environment Generates empty environment config
generate:feature Generates empty feature file in suite
generate:groupobject Generates Group subscriber
generate:helper Generates new helper
generate:pageobject Generates empty PageObject class
generate:phpunit Generates empty PHPUnit test without Codeception additions
generate:scenarios Generates text representation for all scenarios
generate:stepobject Generates empty StepObject class
generate:suite Generates new test suite
generate:test Generates empty unit test file in suite
Phương châm
Để duy trì chất lượng của chương trình test thì đỏi hỏi phải được bảo trì liên tục. Nhưng nếu mà làm quá chi tiết thì sẽ làm tăng chi phí và nhiều khi chỉ có người viết test mới có thể hiểu được. Vì vậy, lần này mình chỉ trình bày việc thực hiện test tự động chỉ trong những phạm vi bên dưới.
Screen system
Acceptance test
※ Kiểm tra 1 Screen coi có hoạt động bình thường hay không theo 1 luồng từ lúc nhập dự liệu đến khi kết thúc.
API system
Function test
※ Kiểm tra từng API trường hợp đúng có trả về đúng giá trị hay không và trường hợp sai coi có trả về đúng theo từng error code hay không.
Unit test
※ Kiểm tra validation giá trị input của từng API coi có giống giả thuyết hay không.
Lưu ý
Khi làm việc với Codeception thì nhận ra những điểm cần lưu ý.
Point 1: Webdriver thì nên sử dụng Php Browser
Tùy vào từng trường hợp thì ta nên suy xét xem xài cái nào là hợp lý. Chẳng hạn ví dụ như 2 Webdriver Selenium2 và PhantomJS thì tuy có nhiều tính năng cao nhưng khi cài đặt và chạy thì việc quản lý process rất phiền phức, tốc độ chạy cảm thấy cũng rất chậm. Chính vì vậy nếu chỉ làm những việc đơn giản thì PHP Browser là một lựa chọn hợp lý để sử dụng.
PHP Browser:
- Điểm mạnh: chỉ cần có PHP và Curl là có thể chạy và tốc độ chạy rất nhanh.
- Điểm yếu: không thể dùng với Javascript.
Point 2: Nên sử dụng Cest hơn là Cept
Trong Codeception có 2 kiểu mẫu để tạo test program là Cept và Cest. Cept là kiểu đơn giản hóa, còn Cest giống như một đối tượng thực hiện test theo một định hướng.
Cept
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('perform actions and see result');
$I->amOnPage('/login');
$I->fillField('user_id','aaa');
$I->fillField('password','aaa');
$I->click('ログイン');
$I->see('TOP');
Cest
<?php
class LoginCest
{
public function login(\AcceptanceTester $I)
{
$I->wantTo('perform actions and see result');
$I->amOnPage('/login');
$I->fillField('user_id','aaa');
$I->fillField('password','aaa');
$I->click('ログイン');
$I->see('TOP');
}
}
Ngoài Cest con có sử dụng anotation, vì vậy bạn có thể tạo 1 chương trình test có hệ thống. Giống như bên dưới là 1 ví dụ về dataprovider, hàm type()
có thể được truyền vào như là một tham số. Ngoài ra @before
và @after
có thể được sử dụng để thiết lập như là điều kiện tiền đề, điều này làm cho việc test rất tiện lợi và dễ dàng. Nhưng phương thức có gắn "" sẽ không được thực hiện khi chạy.
Ví dụ:
/**
* 正常系テスト
* @param ApiTester $I
* @dataprovider _type
*/
public function check(ApiTester $I, \Codeception\Example $example)
{
$I->wantTo('api execute test. type ' . $example['type']);
$I->haveHttpHeader('Content-Type', 'application/json');
$I->sendPOST('api/a', ['type' => $example['type']]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
$I->seeResponseContainsJson(['result' => 'success']);
$I->seeResponseContainsJson(['data1' => 'a']);
$I->seeResponseContainsJson(['data2' => 'b']);
}
public function _type()
{
return [
['type'=>"a"],
['type'=>"b"],
['type'=>"c"],
['type'=>"d"],
['type'=>"e"],
];
}
Kết quả :
Codeception PHP Testing Framework v2.2.7
Powered by PHPUnit 4.8.31 by Sebastian Bergmann and contributors.
Api Tests (5) ------------------------------------------
✔ TestGetCest: Api execute test. type a (0.54s)
✔ TestGetCest: Api execute test. type b (0.15s)
✔ TestGetCest: Api execute test. type c (0.15s)
✔ TestGetCest: Api execute test. type d (0.14s)
✔ TestGetCest: Api execute test. type e (0.14s)
--------------------------------------------------------
Point 3 :Có thể phân tích kết quả của API sau khi chạy
Với những API sử dụng JSON thì có thể dùng hàm seeResponseContainsJson
để kiểm tra, và dùng hàm grabDataFromResponseByJsonPath
để lấy kết quả sau khi chạy một API A để truyền cho một API B nào đó.
$I->wantTo('perform actions and see result');
$I->haveHttpHeader('Content-Type', 'application/json');
//api a
$I->sendPOST('/api/a', []);
$id = $I->grabDataFromResponseByJsonPath('$.data')[0]['id'];
//api b
$I->sendPOST('/api/b', ['id'=>$id]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
$I->seeResponseContainsJson(['result' => 'success']);
Kết luận
Codeception rất đơn giản và dễ xài, các câu lệnh các hàm như một câu tiếng anh bình thường, đọc vô là ta có thể hiểu ngay là đang muốn test cái gì.