Yii2的Codeception測試-2測試工作

這是一個系列文章呀袱,分3部分:
1稚照、準(zhǔn)備工作--Yii2高級模板的安裝鲫忍,以及編寫一個類(方法)和一個model的RETful
2冀墨、測試工作--單元測試和API(REST規(guī)范的)測試
3、力爭上游--覆蓋率献丑、基礎(chǔ)概念末捣、引用文獻(xiàn)等

本文是第二部分,主要是單元測試和API測試创橄。

單元測試

1箩做、執(zhí)行vendor/bin/codecept generate:cest -c common unit CustomeString
新建了common\tests\unit\CustomeStringCest.php妥畏,開始寫測試代碼了邦邦,增加內(nèi)容:

    public function tryToTest(UnitTester $I)
    {
        $len = 10;
        $prefix = 'pre';
        
        $string = CustomString::generateCode($len, $prefix);
        expect(strlen($string))->equals($len + 3);
        expect(substr($string, 0, 3))->equals($prefix);
        //等效于 expect($string)->startsWith($prefix);
       //這就是codeception的強(qiáng)大之處,封裝了幾乎所有測試需要的醉蚁,官方說90%+,且不希望你重復(fù)造輪子
    }

2燃辖、執(zhí)行vendor/bin/codecept run -c common
我們可以在命令終端看到測試運(yùn)行的情況网棍。

至此郭赐,恭喜你,已經(jīng)利用codeception進(jìn)行了某個類的(方法的)測試确沸。

我們繼續(xù)來書寫如何測試一個model:
4捌锭、執(zhí)行vendor/bin/codecept generate:test -c common unit models/News
新建一個common\test\unit\models\NewsTest.php,我們仿照LoginFormTest.php罗捎,編寫NewsTest.php:

<?php

namespace common\tests\models;

use common\fixtures\NewsFixture;
use common\models\News;

class NewsTest extends \Codeception\Test\Unit
{
    public function _fixtures()
    {
        return [
            'news' => [
                'class' => NewsFixture::class,
                'dataFile' => codecept_data_dir() . 'news.php',
            ],
        ];
    }
    
    public function testValidate()
    {
        $model = new News(['title' => 'one title']);
        expect('model should create successfully', $model->save())->true();
        
        $model = new News(['code' => \Yii::$app->security->generateRandomString(33)]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('code');
        
        $model = new News(['title' => null]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('title');
        
        $model = new News(['title' => \Yii::$app->security->generateRandomString(256)]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('title');
    }
    
    public function testData()
    {
        $data = News::find()->where(['title' => 'This is a title'])->one();
        expect(count($data))->equals(1);
    }
}

5观谦、因?yàn)樾枰玫?code>NewsFixture::class和codecept_data_dir() . 'news.php'
所以我們需要在common的fixtures下新建NewFixture.php
(具體位置無所謂桨菜,只需要保證命名空間是common\fixtures):

<?php
namespace common\fixtures;

use yii\test\ActiveFixture;

class NewsFixture extends ActiveFixture
{
    public $modelClass = 'common\models\News';
}

然后在common\tests\_data下新建news.php,自己添加一些數(shù)據(jù):

<?php

return [
    [
        'code' => 'abcdefg',
        'title' => 'This is a title',
        'content' => '<p>some Content</p>',
        'status' => 0,
        'created_at' => 1402312317,
        'updated_at' => 1402312317,
        'created_by' => 1,
        'updated_by' => 1,
    ],
    [
        'code' => '22222',
        'title' => 'This is second title',
        'content' => '<p>some Content</p>',
        'status' => 1,
        'created_at' => 1402312317,
        'updated_at' => 1402312317,
        'created_by' => 1,
        'updated_by' => 1,
    ],
];

6豁状、執(zhí)行vendor/bin/codecept run -c common,查看測試運(yùn)行情況倒得。
至此泻红,單元測試算告一段落。

單元測試霞掺,基本上就是對自定義的類的(方法的)測試谊路,還有model的一些測試。
當(dāng)有新的自定義類或者model時菩彬,類似上述新增測試用例即可缠劝。

7、 補(bǔ)充:
由于codeception包含3種格式的測試文件:Cept, Cest and Test

Cept are written as narrative scenarios. To make a PHP file a valid scenario, its name should have a Cept suffix.
描述行語言骗灶,文件后綴是Cept惨恭,常用于功能、驗(yàn)收還有API測試耙旦。
Cest combines scenario-driven test approach with OOP design. In case you want to group a few testing scenarios into one, you should consider using Cest format.
Codeception can also execute PHPUnit test files for unit testing脱羡。
注意Test格式時,方法名需要以test開頭免都,另外兩種格式不要求锉罐。

上述的例子是Test格式,當(dāng)然可以寫成Cept和Cest琴昆,實(shí)質(zhì)上等效氓鄙。
我習(xí)慣單元測試用Cest,API測試用Cept业舍。
執(zhí)行vendor/bin/codecept generate:cest -c common unit models/News抖拦,
新建一個common\test\unit\models\NewsCest.php,等效代碼如下:

<?php

namespace common\tests\unit\models;

use common\fixtures\NewsFixture;
use common\models\News;
use common\tests\UnitTester;

class NewsCest
{
    public function _before(UnitTester $I)
    {
        $I->haveFixtures([
            'news' => [
                'class' => NewsFixture::class,
                'dataFile' => codecept_data_dir() . 'news.php',
            ],
        ]);
    }
    
    public function _after(UnitTester $I)
    {
    }
    
    // tests
    public function tryToTestValidate(UnitTester $I)
    {
        $model = new News(['title' => 'one title']);
        expect('model should create successfully', $model->save())->true();
        
        $model = new News(['code' => \Yii::$app->security->generateRandomString(33)]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('code');
        
        $model = new News(['title' => null]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('title');
        
        $model = new News(['title' => \Yii::$app->security->generateRandomString(256)]);
        expect('model should create fail', $model->save())->false();
        expect('error message should be set', $model->errors)->hasKey('title');
    }
    
    public function toTestData()
    {
        $data = News::find()->where(['title' => 'This is a title'])->one();
        expect(count($data))->equals(1);
    }
}

功能和驗(yàn)收測試

由于前后端分離舷暮,這里不再介紹codeception的功能和驗(yàn)收測試态罪。
你可以查看frontend/tests/下的functional和accptance部分。
關(guān)于前端測試下面,可以參看CodeceptJS

API測試

接口的自動化測試复颈,這里是一個方案,具體參看WebServices沥割,
Postman的自動化接口測試也是一個不錯的方案耗啦,有時間再整理凿菩。

首先要執(zhí)行vendor/bin/codecept g:suite api -c blog,輸出:

Helper \blog\tests\Helper\Api was created in /home/lijun/works/yii-application/blog/tests/_support/Helper/Api.php
Actor ApiTester was created in /home/lijun/works/yii-application/blog/tests/_support/ApiTester.php
Suite config api.suite.yml was created.
 
Next steps:
1. Edit api.suite.yml to enable modules for this suite
2. Create first test with generate:cest testName ( or test|cept) command
3. Run tests of this suite with codecept run api command
Suite api generated

按照提示繼續(xù)下面的步驟:
1)帜讲、編輯api.suite.yml衅谷,啟用REST,且依賴Yii2似将。如下:

#suite_namespace: blog\tests\api
actor: ApiTester
modules:
    enabled:
        - \blog\tests\Helper\Api
        - REST:
            #url:
            depends: Yii2
            #part: Json

2)获黔、執(zhí)行vendor/bin/codecept g:cept api -c blog News創(chuàng)建測試文件blog\tests\api\NewsCept.php。

<?php

use blog\tests\ApiTester;
use Codeception\Util\HttpCode;

$I = new ApiTester($scenario);

//create
$data = ['code' => 'code1', 'title' => 'first title', 'content' => 'first content'];
$I->wantTo('create a news');
$I->sendPOST('/news', $data);
$I->seeResponseCodeIs(HttpCode::CREATED);
$I->seeResponseIsJson();
//{"code":"code1","title":"first title","content":"first content","id":16}
$I->seeResponseContainsJson($data);

//view
$I->wantTo('view a news');
$id = $I->grabDataFromResponseByJsonPath('$.id')[0];
$I->sendGET('/news/' . $id);
$I->seeResponseCodeIs(HttpCode::OK);
$I->seeResponseIsJson();
$I->seeResponseMatchesJsonType([
    'id' => 'integer',
    'title' => 'string',
    'content' => 'string|null',
]);

//update
$I->wantTo('update news');
$id = $I->grabDataFromResponseByJsonPath('$.id')[0];
$I->sendPUT('/news/' . $id, ['content' => 'updated content']);
$I->seeResponseCodeIs(HttpCode::OK);
$I->seeResponseContainsJson(['content' => 'updated content']);

//index
$I->wantTo('list news');
$I->sendGET('/news');
$I->seeResponseCodeIs(HttpCode::OK);
//{"items":[{"id":49,"code":"code1","title":"first title","content":"first content","status":0,"created_at":0,"created_by":0,"updated_at":0,"updated_by":0}],"_links":{"self":{"href":"http://localhost/index-test.php/news?page=1"}},"_meta":{"totalCount":1,"pageCount":1,"currentPage":1,"perPage":20}}
$I->seeResponseJsonMatchesJsonPath('$.items..title');
$I->seeResponseJsonMatchesXpath('//_meta//totalCount');


//delete
$I->wantTo('delete a news');
$id = $I->grabDataFromResponseByJsonPath('$.items..id');
$I->sendDELETE('/news/' . $id[0]);
$I->seeResponseCodeIs(HttpCode::NO_CONTENT);

//index
$I->wantTo('list empty news');
$I->sendGET('/news');
$I->seeResponseCodeIs(HttpCode::OK);

3)在验、運(yùn)行測試vendor/bin/codecept run -c blog玷氏,
提示需要安裝flow/jsonpath,執(zhí)行composer require -dev "flow/jsonpath"腋舌。待安裝之后再次執(zhí)行測試即可盏触。

至此,REST的API測試完成侦厚。
Yii2下使用codeception進(jìn)行單元測試和API測試到此告一段落耻陕,后面可以繼續(xù)熟悉codeception的強(qiáng)大吧。

上一篇:準(zhǔn)備工作
下一篇:力爭上游

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刨沦,一起剝皮案震驚了整個濱河市诗宣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌想诅,老刑警劉巖召庞,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異来破,居然都是意外死亡篮灼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門徘禁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诅诱,“玉大人,你說我怎么就攤上這事送朱∧锏矗” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵驶沼,是天一觀的道長炮沐。 經(jīng)常有香客問我,道長回怜,這世上最難降的妖魔是什么大年? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上翔试,老公的妹妹穿的比我還像新娘轻要。我一直安慰自己,他們只是感情好遏餐,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布伦腐。 她就那樣靜靜地躺著,像睡著了一般失都。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幸冻,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天粹庞,我揣著相機(jī)與錄音,去河邊找鬼洽损。 笑死庞溜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碑定。 我是一名探鬼主播流码,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼延刘!你這毒婦竟也來了漫试?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤碘赖,失蹤者是張志新(化名)和其女友劉穎驾荣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體普泡,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡播掷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了撼班。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歧匈。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砰嘁,靈堂內(nèi)的尸體忽然破棺而出件炉,到底是詐尸還是另有隱情般码,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布板祝,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏孤里。R本人自食惡果不足惜伏伯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一捌袜、第九天 我趴在偏房一處隱蔽的房頂上張望说搅。 院中可真熱鬧虏等,春花似錦弄唧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澄干,卻和暖如春柠傍,著一層夾襖步出監(jiān)牢的瞬間麸俘,已是汗流浹背惧笛。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留静檬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓拂檩,卻偏偏與公主長得像嘲碧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子愈涩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容