使用 Codeception 对 Yii2 进行 API 测试
Published on Feb 02, 2020
前言
Yii2 官方兼容 Codeception 测试框架,你可以创建以下类型的测试:
- 单元测试: 验证一个独立的代码单元是否按照期望的方式运行
- 功能测试: 在浏览器模拟器中以用户视角来验证期望的场景是否发生
验收测试: 在真实的浏览器中以用户视角验证期望的场景是否发生
Yii 为 yii2-app-basic 和 yii2-app-advanced 应用模板均提供了对上述三种类型都支持的开箱即用的测试套件。
这次我们要做的是基于
yii2-app-advanced
模板, 为其增加API测试套件,用于测试API接口。
搭建项目
从模板创建项目
composer create-project --prefer-dist yiisoft/yii2-app-advanced acme
准备测试环境
cd acme # 初始化项目 php init --env=Development --overwrite=y # 创建测试用数据库, 与 common/config/test-local.php 中的配置保持一致 # 执行数据库迁移, 注意, 使用的是 yii_test, 而不是 yii php yii_test migrate/up
执行
./vendor/bin/codecept run
以启动测试假设你已经全局安装了
codeception
, 后面均直接使用codecept
命令, 不再加上路径了。这里执行的测试内容为 advanced 模板项目中自带的测试,同时覆盖了单元测试, 功能测试和验收测试。输出内容如下:
➜ ./vendor/bin/codecept run Codeception PHP Testing Framework v4.0.3 Powered by PHPUnit 8.5.2 by Sebastian Bergmann and contributors. Running with seed: [common\tests]: tests from /home/demo/Code/learning/yii2-app-advanced/common Common\tests.unit Tests (3) ----------------------------------------------------------------------------------------------------------------------------- ✔ LoginFormTest: Login no user (0.01s) ✔ LoginFormTest: Login wrong password (0.42s) ✔ LoginFormTest: Login correct (0.46s) --------------------------------------------------------------------------------------------------------------------------------------------------------- ...此处有省略... [backend\tests]: tests from /home/demo/Code/learning/yii2-app-advanced/backend Backend\tests.functional Tests (1) ---------------------------------------------------------------------------------------------------------------------- ✔ LoginCest: Login user (0.43s) --------------------------------------------------------------------------------------------------------------------------------------------------------- Backend\tests.unit Tests (0) ---------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------- Time: 4.53 seconds, Memory: 30.00 MB OK (43 tests, 121 assertions)
创建API测试套件
首先需要明确的是 yii2 advanced 模板属于多应用项目,分为 frontend 和 backend , 当然还可以按需继续添加其他应用。 我们需要在多个应用中分别创建API测试套件。此处以 frontend 应用为例。
- 进入应用根目录
cd frontend
创建API测试套件
codecept generate:suite api
, 输出如下➜ codecept generate:suite api Helper \frontend\tests\Helper\Api was created in /path/acme/frontend/tests/_support/Helper/Api.php Actor ApiTester was created in /path/acme/frontend/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
由输出可知,该命令共生成了三个文件。 查看其中
tests/api.suite.yml
文件内容如下:actor: ApiTester modules: enabled: - \frontend\tests\Helper\Api
修改
api.suite.yml
文件, 修改后内容如下:suite_namespace: frontend\tests\api actor: ApiTester modules: enabled: - \frontend\tests\Helper\Api - REST: depends: Yii2 config: - Yii2
composer 安装API测试所需依赖(
api.suite.yml
中启用的REST
模块)composer require codeception/module-rest --dev
执行
codecept run api
目的是为了验证配置是否正确, 依赖是否安装, 同时生成
tests/_support/_generated/ApiTesterActions.php
文件
创建测试
先随便写个常见的登录接口
新建
frontend/controllers/ApiController.php
控制器文件, 内容如下:<?php namespace frontend\controllers; use yii\web\Controller; class ApiController extends Controller { public $enableCsrfValidation = false; public function actionLogin() { return json_encode([ 'code' => 200, 'data' => [ 'token' => 'some random string', ], 'message' => 'OK', ]); } }
生成测试类
执行
codecept generate:cest api LoginCest
以生成tests/api/LoginCest.php
测试类,然后在测试类中添加测试方法,修改后文件内容如下:<?php namespace frontend\tests\api; use Codeception\Util\HttpCode; use frontend\tests\ApiTester; use yii\helpers\Url; class LoginCest { public function _before(ApiTester $I) { } // tests public function tryToTest(ApiTester $I) { $I->wantTo('登录'); $I->haveHttpHeader('Accept', 'application/json'); $I->haveHttpHeader('Content-Type', 'application/json'); $I->sendPOST(Url::toRoute('/api/login'), ['username' => 'username', 'password' => 'password']); $I->seeResponseCodeIs(HttpCode::OK); $I->canSeeResponseIsJson(); $I->canSeeResponseContainsJson(['code' => 200]); } }
执行测试
codecept run api LoginCest
, 输出如下➜ codecept run api LoginCest Codeception PHP Testing Framework v4.0.3 Powered by PHPUnit 8.5.2 by Sebastian Bergmann and contributors. Running with seed: Frontend\tests.api Tests (1) ---------------------------------------------------------------------------------------------------------------------------- ✔ LoginCest: 登录 (0.01s) --------------------------------------------------------------------------------------------------------------------------------------------------------- Time: 127 ms, Memory: 12.00 MB OK (1 test, 4 assertions)