单元测试「PHPUnit」的使用

本文是在Laravel框架下使用PHPUnit进行单元测试

为什么要单元测试 ?

只要你想到输入一些东西到print语句或调试表达式中,就用测试代替它。

安装PHPUnit

  • 使用 composer 方式安装 PHPUnit
1
composer require --dev phpunit/phpunit
  • 安装 Monolog日志包, 做phpunit测试记录日志使用
1
composer require monolog/monolog

PHPUnit简单用法

单个文件测试

创建目录 tests, 新建文件 StackTest.php, 编辑如下:

一般初始化Laravel框架就带有tests文件夹, 用于存放测试代码

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
<?php

namespace App\tests;

require_once __DIR__ . '/../vendor/autoload.php';

define("ROOT_PATH", dirname(__DIR__) . "StackTest.php/");

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use PHPUnit\Framework\TestCase;

class StackTest extends TestCase
{
public function testPushAndPop()
{
$stack = [];

$this->assertEquals(0, count($stack));

array_push($stack, 'foo');

// 添加日志文件, 如果没有安装monolog,则有关monolog的代码都可以注释掉
$this->Log()->error('hello', $stack);

$this->assertEquals('foo', $stack[count($stack) - 1]);
$this->assertEquals(1, count($stack));

$this->assertEquals('foo', array_pop($stack));
$this->assertEquals(0, count($stack));
}

public function Log()
{
// create a log channel
$log = new Logger('Tester');
$log->pushHandler(new StreamHandler(ROOT_PATH . 'storage/logs/app.log', Logger::WARNING));
$log->error('Error');

return $log;
}
}

代码解释:

    1. StackTest为测试类
    1. StackTest 继承于 PHPUnit\Framework\TestCase
    1. 测试方法testPushAndPop(), 测试方法必须为public权限, 一般以test开头,或者你也可以选择给其加注释@test来表示
    1. 在测试方法内,类似于 assertEquals() 这样的断言方法用来对实际值与预期值的匹配做出断言

命令行执行

1
phpunit命令 测试文件命名

例如:

1
2
3
4
./vendor/bin/phpunit tests/StackTest.php

// 或者可以省略文件后缀名
./vendor/bin/phpunit tests/StackTest

执行结果:

1
2
3
4
5
6
7
8
$ ./vendor/bin/phpunit tests/StackTest.php
PHPUnit 7.2.6 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 203 ms, Memory: 4.00MB

OK (1 test, 5 assertions)

我们可以在app.log文件中查看我们打印的日志信息。

  • storage/logs/app.log
1
2
[2018-07-11 08:45:24] Tester.ERROR: Error [] []
[2018-07-11 08:45:24] Tester.ERROR: hello ["foo"] []

类文件引入

  • Calculator.php
1
2
3
4
5
6
7
8
9
<?php

class Calculator
{
public function sum($a, $b)
{
return $a + $b;
}
}
  • 单元测试类: CalculatorTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

namespace App\tests;

require_once __DIR__ . '/../vendor/autoload.php';
require "Calculator.php";

use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase
{
public function testSum()
{
$obj = new \Calculator;

$this->assertEquals(2, $obj->sum(1, 1));
}
}

命令执行:

1
2
3
4
5
6
7
8
$ ./vendor/bin/phpunit tests/CalculatorTest
PHPUnit 7.2.6 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 185 ms, Memory: 4.00MB

OK (1 test, 1 assertion)

如果我们把这里的断言故意写错,$this->assertEquals(1, $obj->sum(0, 0));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ./vendor/bin/phpunit tests/CalculatorTest
PHPUnit 7.2.6 by Sebastian Bergmann and contributors.

F 1 / 1 (100%)

Time: 194 ms, Memory: 4.00MB

There was 1 failure:

1) App\tests\CalculatorTest::testSum
Failed asserting that 2 matches expected 1.

C:\WWW\Laravel\tests\CalculatorTest.php:16

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

会直接报出方法错误信息及行号,有助于我们快速找出bug

高级用法

你是否已经厌烦了在每一个测试方法命名前面加一个test,是否因为只是调用的参数不同,却要写多个测试用例而纠结?
我最喜欢的高级功能,现在隆重推荐给你,叫做框架生成器

  • Calculator.php
1
2
3
4
5
6
7
8
9
10
<?php  

class Calculator
{
public function sum($a, $b)
{
return $a + $b;
}
}
?>
  • 命令行启动测试用例,使用关键字 --skeleton
1
./vendor/bin/phpunit --skeleton Calculator.php
  • 执行结果:
1
2
3
PHPUnit 7.2.6 by Sebastian Bergmann and contributors.

Wrote test class skeleton for Calculator to CalculatorTest.php.

是不是很简单,因为没有测试数据,所以这里加测试数据,然后重新执行上边的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php  

class Calculator
{
/**
* @assert (0, 0) == 0
* @assert (0, 1) == 1
* @assert (1, 0) == 1
* @assert (1, 1) == 2
*/
public function sum($a, $b)
{
return $a + $b;
}
}
?>
  • 原始类中的每个方法都进行@assert注解的检测。这些被转变为测试代码,像这样:
1
2
3
4
5
6
7
/**
* Generated from @assert (0, 0) == 0.
*/
public function testSum() {
$obj = new Calculator;
$this->assertEquals(0, $obj->sum(0, 0));
}

出现错误: unrecognized option --skeleton

1
2
wget https://phar.phpunit.de/phpunit-skelgen.phar
php phpunit-skelgen.phar

参考

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2023 Keep It Simple And Stupid All Rights Reserved.

访客数 : | 访问量 :