PHPUnit实践一(初识和生命周期)

栏目: PHP · 发布时间: 6年前

内容简介:本教程所有的PHPUnit测试基于日常我们的普通用到的测试:单元测试是针对程序的最小单元来进行正确性检验的测试工作,程序单元就是应用的最小可测试部件,一个单元可能是单个程序,类,对象,方法等

本教程所有的PHPUnit测试基于 PHPUnit6.5.9 版本, Lumen 5.5 框架

前置

日常我们的普通用到的测试:

  1. 代码直接echo,debug等方法测试 -> 跟踪细节断点型测试
  2. log日志辅助测试 -> 跟踪细节断点型测试
  3. 辅助工具,postman之类的做请求类测试->请求类测试
  4. 浏览器直接测试->浏览器测试

单元测试

单元测试是针对程序的最小单元来进行正确性检验的测试工作,程序单元就是应用的最小可测试部件,一个单元可能是单个程序,类,对象,方法等

单元测试是用来测试包或者程序的一部分代码或者一组代码的函数。测试的目的是确认目标代码在给定的场景下,有没有按照期望工作。

一个场景是正向路经测试,就是在正常执行的情况下,保证代码不产生错误的测试。这种测试可以用来确认代码可以成功地向数据库中插入一条工作记录。

另外一些单元测试可能会测试负向路径的场景,保证代码不仅会产生错误,而且是预期的错误。

这种场景下的测试可能是对数据库进行查询时没有找到任何结果,或者对数据库做了无效的更新。

在这两种情况下,测试都要验证确实产生了错误,且产生的是预期的错误。总之,不管如何调用或者执行代码,所写的代码行为都是可预期的

优点或改善解决问题

  1. 减少bug

    通过运行单元测试可以直接测试各个功能的正确性,有bug可以直接发现并解决,如果要等到跟其他的功能对接,进行连贯测试,测试比较麻烦,而且bug不能及早的发现并解决

  2. 快速定位bug

    如果是web项目的某一个功能,平常我们定位bug可能是页面输入值,后台断点,一步一步的需要bug位置,如果有编写单元测试,则可以直接修改数据,运行单元测试即可,快速有限

  3. 提高代码质量

    如果每一个部件都是完美的,那么组合起来肯定也是完美的。整体代码质量就得到了保障

  4. 减少调试时间

    当不知问题所在的时候,可能需要各种调试与运行,而如果所有的都有编写单元测试,那么可以直接运行单元测试,就能定位问题所在位置。

PHPUnit

PHPUnit是一个面向 PHP 程序员的测试框架,这是一个xUnit的体系结构的单元测试框架。

版本

主版本 初始版本 PHP兼容性 支持 后台框架对应版本
PHPUnit 8 2019年2月1日 PHP 7.2, PHP 7.3, PHP 7.4 在2021年2月5日结束支持
PHPUnit 7 2018年2月2日 PHP 7.1, PHP 7.2, PHP 7.3 在2020年2月7日结束支持
PHPUnit 6 2017年2月3日 PHP 7.0, PHP 7.1, PHP 7.2 在2019年2月1日结束支持 *
PHPUnit 5 2015年10月2日 PHP 5.6, PHP 7.0, PHP 7.1 在2018年2月2日结束支持
PHPUnit 4 2014年3月7日 PHP 5.3, PHP 5.4, PHP 5.5, PHP 5.6 在2017年2月3日结束支持

PHPUnit测试一个文件类的生命周期

PHPUnit实践一(初识和生命周期)

流程测试代码

自动加载文件

<?php
/**
 * 测试框架的自动加载测试文件类
 * User: qikailin
 */
error_reporting(E_ALL ^ E_NOTICE);
require __DIR__ . '/../vendor/autoload.php';

define('WPT_TEST_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 = WPT_TEST_DIR_BASE . DIRECTORY_SEPARATOR . str_replace(["Test\\", "/", "\\"],
            ["", DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR], $class) . ".php";
    
    if (file_exists($classFile)) {
        include_once $classFile;
    }

}, true, false);

PipeTest 流程代码

<?php
/**
 * 测试类的每个测试方法都会运行一次 setUp() 和 tearDown() 模板方法(同时,每个测试方法都是在一个全新的测试类实例上运行的)。
 * 另外,setUpBeforeClass() 与 tearDownAfterClass() 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。
 * 如果有需要共享的对象或变量,可以放在setUpBeforeClass,并设置为静态属性
 * User: qikailin
 */
namespace Test\Cases\Headline;

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
../../../vendor/bin/phpunit --bootstrap ../../bootstrap.php Cases/Demo/PipeTest.php

运行输出

PHPUnit 6.5.9 by Sebastian Bergmann and contributors.

Test\Cases\Headline\PipeTest::setUpBeforeClass
Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testOne
Test\Cases\Headline\PipeTest::assertPostConditions
Test\Cases\Headline\PipeTest::tearDown
.Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testTwo
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::onNotSuccessfulTest
FTest\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testThree
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::onNotSuccessfulTest
FTest\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testFour
Test\Cases\Headline\PipeTest::assertPostConditions
Test\Cases\Headline\PipeTest::tearDown
R                                                                4 / 4 (100%)Test\Cases\Headline\PipeTest::tearDownAfterClass


Time: 1.29 seconds, Memory: 6.00MB

There were 2 failures:

1) Test\Cases\Headline\PipeTest::testTwo
Failed asserting that false is true.

/web/www/wpt/gt-api/tests/Cases/Demo/PipeTest.php:47

2) Test\Cases\Headline\PipeTest::testThree
Failed asserting that false is true.

/web/www/wpt/gt-api/tests/Cases/Demo/PipeTest.php:53

--

There was 1 risky test:

1) Test\Cases\Headline\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\Headline\PipeTest::setUpBeforeClass
Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testOne
Test\Cases\Headline\PipeTest::assertPostConditions
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testTwo
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::onNotSuccessfulTest
Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testThree
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::onNotSuccessfulTest
Test\Cases\Headline\PipeTest::setUp
Test\Cases\Headline\PipeTest::assertPreConditions
Test\Cases\Headline\PipeTest::testFour
Test\Cases\Headline\PipeTest::assertPostConditions
Test\Cases\Headline\PipeTest::tearDown
Test\Cases\Headline\PipeTest::tearDownAfterClass

输出标识说明

.
当测试成功时输出。

F
当测试方法运行过程中一个断言失败时输出。

E
当测试方法运行过程中产生一个错误时输出。

R
当测试被标记为有风险时输出。

S
当测试被跳过时输出。

I
当测试被标记为不完整或未实现时输出。

参考

PHPUnit 6.5 官方文档


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Remote

Remote

Jason Fried、David Heinemeier Hansson / Crown Business / 2013-10-29 / CAD 26.95

The “work from home” phenomenon is thoroughly explored in this illuminating new book from bestselling 37signals founders Fried and Hansson, who point to the surging trend of employees working from hom......一起来看看 《Remote》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具