cakephp/codeception

此软件包已被废弃且不再维护。未建议替代软件包。

使用Codeception运行CakePHP测试

dev-master 2023-02-20 01:56 UTC

This package is auto-updated.

Last update: 2023-03-20 02:06:06 UTC


README

Build Status Software License

⚠️ 此存储库已归档且不再维护。

一个用于测试由CakePHP 3驱动的应用的codeception模块。使用Codeception与CakePHP结合,可以打开全新的测试功能。

前端测试

(即基于浏览器的流程测试)

后端测试

(即直接、内部方法测试)

使用方法

从CakePHP应用中,在命令行中运行以下命令

$ composer require --dev cakephp/codeception:dev-master && composer run-script post-install-cmd

如果您正在开发一个插件,请首先将安装后脚本添加到您的composer.json

{
    "scripts": {
        "post-install-cmd": "Cake\\Codeception\\Console\\Installer::customizeCodeceptionBinary"
    }
}

安装后,现在可以运行bootstrap,这将为您应用创建所有必需的codeception文件

$ vendor/bin/codecept bootstrap

这将在您的app目录中创建以下文件/文件夹

├── codeception.yml
├── src
│   └── TestSuite
│       └── Codeception
|           ├── AcceptanceTester.php
|           ├── FunctionalTester.php
|           ├── UnitTester.php
|           ├── Helper
│           │   ├── Acceptance.php
│           │   ├── Functional.php
│           │   └── Unit.php
|           └── _generated
|               └── .gitignore
└── tests
    ├── Acceptance.suite.yml
    ├── Functional.suite.yml
    ├── Unit.suite.yml
    ├── Acceptance
    │   └── bootstrap.php
    ├── Fixture
    │   └── dump.sql
    ├── Functional
    │   └── bootstrap.php
    └── Unit
        └── bootstrap.php

您可能已经注意到,CakePHP实现有一些不同之处

  • 使用驼峰命名空间名称(Functionalfunctional
  • 使用bootstrap.php,没有下划线前缀(与 _bootstrap.php 相反)
  • 使用 src/TestSuite/Codeception 为自定义模块(助手)
  • 使用 tmp/tests 存储日志(与 tests/_logs 相反)
  • 使用 tests/Fixture 存储固定数据(与 tests/_data 相反)
  • 使用 tests/Envs 存储固定数据(与 tests/_envs 相反)
  • 添加 .gitignore 以防止跟踪自动生成的文件
  • 使用 codecept 二进制文件添加各种生成文件的自定义模板

要更好地了解Codeception测试的工作原理,请查阅官方文档

示例Cept

<?php
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that adding a bookmark works');
$I->amOnPage('/bookmarks/add');
$I->see('Submit');
$I->submitForm('#add', [
    'title' => 'First bookmark',
]);
$I->seeInSession([
    'Flash'
]);

操作

认证

...

配置

使用seeInConfig($key, $value = null)断言配置键(/值)

$I->seeInConfig('App.name'); // checks only that the key exists
$I->seeInConfig('App.name', 'CakePHP');
$I->seeInConfig(['App.name' => 'CakePHP']);

使用dontSeeInConfig($key, $value = null)断言没有配置键(/值)

$I->dontSeeInConfig('App.name'); // checks only that the key does not exist
$I->dontSeeInConfig('App.name', 'CakePHP');
$I->dontSeeInConfig(['App.name' => 'CakePHP']);

数据库

使用haveRecord($model, $data = [])插入记录

这在你只需要为单个测试(临时夹具)创建记录时很有用。它不会断言任何内容,并返回插入记录的ID。

$I->haveRecord('users', ['email' => 'jadb@cakephp.org', 'username' => 'jadb']);

使用 grabRecord($model, $conditions = []) 检索记录

这是对 Cake\ORM\Table::find('first') 方法的封装。

$I->grabRecord('users', ['id' => '1']);

使用 seeRecord($model, $conditions = []) 断言记录存在

这检查请求的记录是否真的存在于数据库中。

$I->seeRecord('users', ['username' => 'jadb']);

使用 dontSeeRecord($model, $conditions = []) 断言记录不存在

这检查请求的记录是否真的不存在于数据库中。

$I->dontSeeRecord('users', ['email' => 'jadb@cakephp.org']);

分发器

...

杂项

加载夹具

在你的 Cest 测试用例中,编写 $fixutures 属性

class AwesomeCest
{
    public $fixtures = [
        'app.users',
        'app.posts',
    ];

    // ...
}

你可以在 Cest 测试用例中使用 $autoFixtures$dropTables 属性和 loadFixtures() 方法

class AwesomeCest
{
    public $autoFixtures = false;
    public $dropTables = false;
    public $fixtures = [
        'app.users',
        'app.posts',
    ];

    public function tryYourSenario($I)
    {
        // load fixtures manually
        $I->loadFixtures('Users', 'Posts');
        // or load all fixtures
        $I->loadFixtures();
        // ...
    }
}

在你的 Cept 测试用例中使用 $I->useFixtures()$I->loadFixtures()

$I = new FunctionalTester($scenario);

// You should call `useFixtures` before `loadFixtures`
$I->useFixtures('app.users', 'app.posts');
// Then load fixtures manually
$I->loadFixtures('Users', 'Posts');
// or load all fixtures
$I->loadFixtures();

使用 expectedCakePHPVersion($ver, $operator = 'ge') 断言 CakePHP 版本

$I->expectedCakePHPVersion('3.0.4');

路由器

使用 amOnRoute($route, $params = []) 通过路由打开页面

以下所有形式都是等效的

$I->amOnRoute(['controller' => 'Posts', 'action' => 'add']);
$I->amOnRoute('addPost'); // assuming there is a route named `addPost`

使用 amOnAction($action, $params = []) 通过操作打开页面

以下所有形式都是等效的

$I->amOnAction('Posts@add');
$I->amOnAction('Posts.add');
$I->amOnAction('PostsController@add');
$I->amOnAction('PostsController.add');
$I->amOnAction('posts@add');
$I->amOnAction('posts.add');

使用 seeCurrentRouteIs($route, $params = []) 断言 URL 与路由匹配

以下所有形式都是等效的

$I->seeCurrentRouteIs(['controller' => 'Posts', 'action' => 'add']);
$I->seeCurrentRouteIs('addPost'); // assuming there is a route named `addPost`

使用 seeCurrentActionIs($action, $params = []) 断言 URL 与操作匹配

以下所有形式都是等效的

$I->seeCurrentActionIs('Posts@add');
$I->seeCurrentActionIs('Posts.add');
$I->seeCurrentActionIs('PostsController@add');
$I->seeCurrentActionIs('PostsController.add');
$I->seeCurrentActionIs('posts@add');
$I->seeCurrentActionIs('posts.add');

会话

使用 haveInSession($key, $value = null) 在会话中插入键/值

$I->haveInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->haveInSession(['redirect' => Router::url(['_name' => 'dashboard'])]);

使用 seeInSession($key, $value = null) 断言会话中的键/值

$I->seeInSession('redirect'); // only checks the key exists.
$I->seeInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->seeInSession(['redirect', Router::url(['_name' => 'dashboard'])]);

使用 dontSeeInSession($key, $value = null) 断言会话中不存在键/值

$I->dontSeeInSession('redirect'); // only checks the key does not exist.
$I->dontSeeInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->dontSeeInSession(['redirect', Router::url(['_name' => 'dashboard'])]);

视图

...