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@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ì.

Tham khảo