测试

使用Composer安装PHPUnit

在composer目录下,执行下列命令

1
php composer.phar require --dev phpunit/phpunit:"^5.7|^6.0"

安装画面 phpUnit install

运行语句 以下语句将执行程序中所有的测试的用例

1
vendor/bin/phpunit

测试用例的规则

1.测试的PHP文件应位于tests/TestCase/[Type]目录中。

2.测试文件的文件名应以Test.php结尾,而不仅仅是.php,例如:创建ArticlesLogic的测试文件为 ArticlesLogicTest.php。

3.含测试的类应该继承Cake\TestSuite\TestCase, Cake\TestSuite\IntegrationTestCase\PHPUnit\Framework\TestCase。

4.任何包含测试(即包含断言)的方法的名称都应以开头test,如testPublished()。也可以使用@test注解将方法标记为测试方法。

测试用例的生命周期图

TestCase Life

实例

创建测试源数据库

目的使测试数据库和实际数据库成为不同的数据库。这样可以防止以后出现令人尴尬的错误。 在config/app.php中,连接测试数据库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
      'test' => [
            'className' => Connection::class,
            'driver' => Postgres::class,
            'persistent' => false,
            'host' => '10.1.2.12',
            //'port' => 'non_standard_port_number',
            'username' => 'dev',
            'password' => 'dev_413',
            'database' => 'test_db_service',
            //'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
            'quoteIdentifiers' => false,
            'log' => false,
            //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
            // 'url' => env('DATABASE_TEST_URL', null),
        ],

创建Logic

创建UsersLogic的测试用例

在tests/TestCase/Model/Logic下新建system文件夹,在文件夹下新建UsersLogicTest文件

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php

use App\Model\Logic\System\UsersLogic;
use Cake\TestSuite\TestCase;

class UsersLogicTest extends TestCase {

    public function setUp()
    {
        parent::setUp();
        $this->UsersLogic = UsersLogic::instance();
    }

    /**
     * 测试findUser($id)方法
     *
     * @return void
     */
    public function testFindUser(){
        $result = $this->UsersLogic->findUser(1);
        $expected = [[
            "id"=> 1,
            "loginId"=> "admin",
            "phone"=> "12345678901",
            "avatar"=> "avatar",
            "roleId"=> 1,
            "departmentId"=> 1,
            "lastLoginTime"=> null,
            "mustChangePassword"=> null]
        ];
        $this->assertEquals($expected, $result,'两个结果不相等');
    }


    /**
     * 测试findAll()方法
     *
     * @return void
     */
    public function testFindAll(){
        $result = $this->UsersLogic->findAll();
        $expected = [
            [
              "id"=> 24,
              "loginId"=> "admin2",
              "phone"=> "17766232222",
              "avatar"=> "avatar",
              "roleId"=> 2,
              "roleName"=> "学生",
              "departmentId"=> 1,
              "departmentsName"=> "默认",
              "lastLoginTime"=> null,
              "mustChangePassword"=> null,
              "status"=>0
            ],
            [ "id"=> 1,
              "loginId"=> "admin",
              "phone"=> "12345678901",
              "avatar"=> "avatar",
              "roleId"=> 1,
              "roleName"=> "默认",
              "departmentId"=> 1,
              "departmentsName"=> "默认",
              "lastLoginTime"=> null,
              "mustChangePassword"=> null,
              "status"=> 0
            ]
        ];
        $this->assertEquals($expected, $result,'两个结果不相等');
    }

    /**
     * 测试add方法
     *
     * @return void
     */
    public function testAdd(){
        $data = [
            "loginId"=> "admin3",
            "phone"=> "13401335265",
            "password"=> "123456",
            "name"=> "admin",
            "avatar"=> "avatar",
            "roleId"=> 2,
            "departmentId"=> 1,
            "status"=>0
        ];
        $result = $this->UsersLogic->add($data);

        $res = [
            "loginId"=> $result['loginId'],
            "phone"=> $result['phone'],
            "name"=>  $result['name'],
            "avatar"=> $result['avatar'],
            "roleId"=> $result['roleId'],
            "departmentId"=> $result['departmentId'],
            "status"=> $result['status']
        ];
        $expected = array_diff_key($data, ["password"=> "123456"]); //删除数组中key为"password"的值,赋给新的数组
        $this->assertEquals($expected, $res,'添加不正确');
    }

    /**
     * 测试save方法
     *
     * @return void
     */
    public function testSave(){
        $id = 8;
        $data = [
            "id" => 8,
            "loginId"=> "admin4",
            "phone"=> "13401335268",
        ];
        $result = $this->UsersLogic->save($id,$data);
        $res = [
            "id" => $result['id'],
            "loginId"=> $result['loginId'],
            "phone"=> $result['phone']
        ];
        $this->assertEquals($data, $res,'修改不正确');
    }

    /**
     * 测试delete方法
     *
     * @return void
     */
    public function testDelete(){
        $id= 8;
        $result = $this->UsersLogic->delete($id);
        $this->assertEquals(true, $result ,'删除失败');
    }

}

运行该测试用例

输入以下命令:

1
vendor/bin/phpunit UnitTest tests/TestCase/Model/Logic/system/UsersLogicTest.php

执行测试后,结果如图:

TestCase user ok

创建控制器Controller测试用例

对Restful结构中的UsersController创建测试用例 在tests/TestCase/Controller下新建UsersControllerTest测试文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php

use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;

class UsersControllerTest extends TestCase{

    use IntegrationTestTrait;

    public function testIndex()
    {
        $this->get('/users');
        $this->assertResponseOk();
    }

    public function testView()
    {
        $this->get('/users/view/1');
        $this->assertResponseOk();
    }

    public function testAdd()
    {
        $data = [
            "loginId"=> "admin3",
            "phone"=> "13401335265",
            "password"=> "123456",
            "name"=> "admin",
            "avatar"=> "avatar",
            "roleId"=> 2,
            "departmentId"=> 1,
            "status"=>0
        ];
        $this->post('/users/add', $data);
        $this->assertResponseOk();
    }

    public function testEdit()
    {
        $data = [
            "id" => 1,
            "name"=> "admin_admin",
            "avatar"=> "avatar_avatar",
        ];
        $this->put('/users/edit/1',$data);
        $this->assertResponseOk();
    }

    public function testDelete()
    {
        $this->delete('/users/delete/19');
        $this->assertResponseOk();
    }
}

控制器测试用例,执行结果如图:

TestCase controller ok

断言

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
布尔类型
assertTrue   断言为真
assertFalse  断言为假

NULL类型
assertNull     断言为NULL
assertNotNull  断言非NULL

数字类型
assertEquals             断言等于
assertNotEquals          断言不等于
assertGreaterThan        断言大于
assertGreaterThanOrEqual 断言大于等于
assertLessThan           断言小于
assertLessThanOrEqual    断言小于等于

字符类型
assertEquals          断言等于
assertNotEquals       断言不等于
assertContains        断言包含
assertNotContains     断言不包含
assertContainsOnly    断言只包含
assertNotContainsOnly 断言不只包含

数组类型
assertEquals          断言等于
assertNotEquals       断言不等于
assertArrayHasKey     断言有键
assertArrayNotHasKey  断言没有键
assertContains        断言包含
assertNotContains     断言不包含
assertContainsOnly    断言只包含
assertNotContainsOnly 断言不只包含

对象类型
assertAttributeContains           断言属性包含
assertAttributeContainsOnly       断言属性只包含
assertAttributeEquals             断言属性等于
assertAttributeGreaterThan        断言属性大于
assertAttributeGreaterThanOrEqual 断言属性大于等于
assertAttributeLessThan           断言属性小于
assertAttributeLessThanOrEqual    断言属性小于等于
assertAttributeNotContains        断言不包含
assertAttributeNotContainsOnly    断言属性不只包含
assertAttributeNotEquals          断言属性不等于
assertAttributeNotSame            断言属性不相同
assertAttributeSame               断言属性相同
assertSame                        断言类型和值都相同
assertNotSame                     断言类型或值不相同
assertObjectHasAttribute          断言对象有某属性
assertObjectNotHasAttribute       断言对象没有某属性

class类型
class类型包含对象类型的所有断言,还有
assertClassHasAttribute          断言类有某属性
assertClassHasStaticAttribute    断言类有某静态属性
assertClassNotHasAttribute       断言类没有某属性
assertClassNotHasStaticAttribute 断言类没有某静态属性

文件相关
assertFileEquals     断言文件内容等于
assertFileExists     断言文件存在
assertFileNotEquals  断言文件内容不等于
assertFileNotExists  断言文件不存在

XML相关
assertXmlFileEqualsXmlFile        断言XML文件内容相等
assertXmlFileNotEqualsXmlFile     断言XML文件内容不相等
assertXmlStringEqualsXmlFile      断言XML字符串等于XML文件内容
assertXmlStringEqualsXmlString    断言XML字符串相等
assertXmlStringNotEqualsXmlFile   断言XML字符串不等于XML文件内容
assertXmlStringNotEqualsXmlString 断言XML字符串不相等

详细可参考以下网址:https://www.w3cschool.cn/phpunit5/1k7b2ozt.html

查看覆盖率

修改Docker 项目的php.ini文件(php/php.ini) docker_php

修改完成,编译docker

1
2
docker-compose build
docker-compose up -d

启动docker后,在docker中执行

1
vendor/bin/phpunit --coverage-html webroot/coverage
docker_php_start

出现下列语句代表运行完成。 docker_php_end

查看html docker_php_html docker_php_html_show