PHPUnit实践二(生命周期)
本系列教程所有的PHPUnit测试基于PHPUnit6.5.9
版本,Lumen 5.5
框架
PHPUnit测试一个文件类的生命周期
理解PHPUnit加载机制(Lumen版)
- PHPUnit自动测试文件会自动加载引入(include file)
- PHPUnit去启动setUp方法,Lumen里重写了setUp,加载了bootstrap/app.php
- app.php加载了composer的autoload,借此你项目所有自动加载环境都有了,不过不包含tests目录
至此我们引入了我们需要构建自己的自动加载类
增加tests的自动加载
我们需要给tests下的测试用例创建类似下面的结构
├── BaseCase.php 重写过Lumen基类的测试基类,用于我们用这个基类做测试基类,后续会说明 ├── bootstrap.php tests自动加载文件 ├── Cases 测试用例目录 │ └── Demo 测试模块 │ ├── logs 日志输出目录 │ ├── PipeTest.php PHPUnit流程测试用例 │ ├── phpunit.xml phpunit配置文件xml │ └── README.md 本模块测试用例说明 ├── ExampleTest.php 最原始测试demo └── TestCase.php Lumen自带的测试基类
tests自动加载文件代码
<?php /** * 测试框架的自动加载测试文件类 * User: qikailin */ error_reporting(E_ALL ^ E_NOTICE); require __DIR__ . '/../vendor/autoload.php'; define('MY_TESTS_DIR_BASE', realpath(dirname(__FILE__))); set_include_path(implode(PATH_SEPARATOR, array( WPT_TEST_DIR_BASE, get_include_path() ))); spl_autoload_register(function ($class) { $classFile = MY_TESTS_DIR_BASE . DIRECTORY_SEPARATOR . str_replace(["Test\\", "/", "\\"], ["", DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR], $class) . ".php"; if (file_exists($classFile)) { include_once $classFile; } }, true, false);
phpunit.xml
自动加载配置bootstrap文件
<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="../../bootstrap.php" convertErrorsToExceptions="true" convertNoticesToExceptions="false" convertWarningsToExceptions="false" colors="true"> </phpunit>
流程测试代码
TestCase.php
# 代码头部添加 命令空间Test namespace Test;
PipeTest 流程代码
<?php /** * 测试类的每个测试方法都会运行一次 setUp() 和 tearDown() 模板方法(同时,每个测试方法都是在一个全新的测试类实例上运行的)。 * 另外,setUpBeforeClass() 与 tearDownAfterClass() 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。 * 如果有需要共享的对象或变量,可以放在setUpBeforeClass,并设置为静态属性 * User: qikailin */ namespace Test\Cases\Demo; use Test\BaseCase; class PipeTest extends BaseCase { public static function setUpBeforeClass() { fwrite(STDOUT, __METHOD__ . "\n"); } public function setUp() { fwrite(STDOUT, __METHOD__ . "\n"); } /** * 测试方法的前置执行,setUp之后 */ protected function assertPreConditions() { fwrite(STDOUT, __METHOD__ . "\n"); } public function testOne() { fwrite(STDOUT, __METHOD__ . "\n"); $this->assertTrue(true); } public function testTwo() { fwrite(STDOUT, __METHOD__ . "\n"); // 两个交换下顺序可以看下效果 // 正常执行成功assert可以继续执行,失败的会跳出方法 $this->assertArrayHasKey('d', ['d'=>1, 'e'=>2]); $this->assertTrue(false); } public function testThree() { fwrite(STDOUT, __METHOD__ . "\n"); $this->assertTrue(false); } public function testFour() { fwrite(STDOUT, __METHOD__ . "\n"); } /** * 测试方法成功后的后置执行,tearDown之前 */ protected function assertPostConditions() { fwrite(STDOUT, __METHOD__ . "\n"); } public function tearDown() { fwrite(STDOUT, __METHOD__ . "\n"); } public static function tearDownAfterClass() { fwrite(STDOUT, __METHOD__ . "\n"); } /** * 不成功后拦截方法 * 必须重新抛出错误,如果不抛出错误,断言会当成成功了 */ public function onNotSuccessfulTest(\Throwable $e) { fwrite(STDOUT, __METHOD__ . "\n"); // 必须重新抛出错误,如果不抛出错误,断言会当成成功了 throw $e; } }
运行
# 你可以把vendor/bin加入到环境变量PATH cd tests/Demo ../../../vendor/bin/phpunit
运行输出
PHPUnit 6.5.9 by Sebastian Bergmann and contributors. Test\Cases\Demo\PipeTest::setUpBeforeClass Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testOne Test\Cases\Demo\PipeTest::assertPostConditions Test\Cases\Demo\PipeTest::tearDown .Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testTwo Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::onNotSuccessfulTest FTest\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testThree Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::onNotSuccessfulTest FTest\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testFour Test\Cases\Demo\PipeTest::assertPostConditions Test\Cases\Demo\PipeTest::tearDown R 4 / 4 (100%)Test\Cases\Demo\PipeTest::tearDownAfterClass Time: 1.29 seconds, Memory: 6.00MB There were 2 failures: 1) Test\Cases\Demo\PipeTest::testTwo Failed asserting that false is true. /xxx/tests/Cases/Demo/PipeTest.php:47 2) Test\Cases\Demo\PipeTest::testThree Failed asserting that false is true. /xxx/tests/Cases/Demo/PipeTest.php:53 -- There was 1 risky test: 1) Test\Cases\Demo\PipeTest::testFour This test did not perform any assertions FAILURES! Tests: 4, Assertions: 4, Failures: 2, Risky: 1. Generating code coverage report in HTML format ... done
整理流程输出
Test\Cases\Demo\PipeTest::setUpBeforeClass Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testOne Test\Cases\Demo\PipeTest::assertPostConditions Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testTwo Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::onNotSuccessfulTest Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testThree Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::onNotSuccessfulTest Test\Cases\Demo\PipeTest::setUp Test\Cases\Demo\PipeTest::assertPreConditions Test\Cases\Demo\PipeTest::testFour Test\Cases\Demo\PipeTest::assertPostConditions Test\Cases\Demo\PipeTest::tearDown Test\Cases\Demo\PipeTest::tearDownAfterClass
总结
一个测试类文件,从setUpBeforeClass加载,且仅此加载一次
每个测试方法都会走的过程:setUp->assertPreConditions->测试方法->[assert成功执行:assertPostConditions]->tearDown->[assert执行失败:onNotSuccessfulTest,且本方法需要抛出错误]
本个测试类文件执行tearDownAfterClass结束
参考
相关推荐
xhqiang 2019-06-30
hebiwtc 2020-04-22
Nicolase 2019-12-27
田野 2017-10-17
xcguoyu 2015-08-26
wqzbxh 2015-01-21
limuxia 2011-11-28
SuperMenyII 2019-07-01
huanxueruxi 2019-07-01
wzllai 2019-07-01
spinachcqb 2019-06-30
ahxxx 2019-06-30
aikudeyu 2016-07-01
Ykbug 2016-06-09
zhangkala 2016-01-08
麦盟Maimob 2015-08-26
怕什么真理无穷 2019-06-26
cxymds 2019-06-26
xishizhaohua 2019-06-26