解决方案 - 自动化单元测试

2022-06-30 16:07:44 浏览数 (2)

前言

收到读者的咨询,情况是这样的:

“亮哥,看了你最近的 8 篇关于持续交付的文章,想咨询一下对于研发人员有没有可落地的方案,我是 PHP 研发工程师,项目中使用的是 Laravel 框架,负责的是电商业务,如何将持续交付使用起来呢?”

今天有时间,简单整理一下,首先我们要知道持续交付涉及的事情很多,涉及的人员角色也很广,比如包括需求分析人员、技术人员、运维人员、测试人员、客户 等。关于这个问题,文章中理论的部分很到位,目前我们主要从技术人员的角度考虑,做一些 技术导向且支持开发过程的测试 ,实现一个可落地的方案,等拿到代码后就可以在此基础上编写,虽然不是很全面,但可以在此基础上进行扩展。

约定测试 Case

以电商业务为例,简单列举 2 个测试 Case:

  1. 下单(从购物车下单) -> 支付(优惠券 余额) -> 发货 -> 收货 -> 评价;
  2. 下单(直接下单) -> 支付(微信) -> 发货 -> 收货 -> 退款(售后);

实际场景中有很多 Case,比如就支付这块就有很多种排列组合,退款这块也会有很多排列组合,原理都是一样的,只要上面的两个会写了,其他的也就都会写了。

项目分析

Case 中的不同环节的不同操作,对于后端来说都是可供调用的 API 接口,其实我们要实现的就是如何自动化按照流程自定义流程顺序调用这些 API 接口。

项目的框架是 Laravel,那么我们考虑的就是在框架中如何编写单元测试代码?这个比较简单,在 tests 目录就可以编写测试用例。

用例编写

安装 orchestra/testbench

代码语言:javascript复制
composer require --dev "orchestra/testbench"

使用这个包,可以帮助编写 Laravel 项目测试,在这里面可以使用 Laravel 中的一些特性。

创建 BaseTestCase.php

代码语言:javascript复制
<?php

namespace Tests;

abstract class BaseTestCase extends OrchestraTestbenchTestCase
{

}

要注意的是 extends OrchestraTestbenchTestCase 而不是 PHPUnitFrameworkTestCase

创建 OrderTest.php

代码语言:javascript复制
<?php

namespace TestsUnit;

use TestsBaseTestCase;

class OrderTest extends BaseTestCase
{
    /**
     * 流程:
     * 1.下单(从购物车下单)
     * 2.支付(优惠券   余额)
     * 3.发货
     * 4.收货
     * 5.评价
     */
    public function testCase1()
    {
        // 1.下单(从购物车下单)

        // 2.支付(优惠券   余额)

        // 3.发货

        // 4.收货

        // 5.评价

        /**
         * 1.在每个流程中都模拟调用 HTTP API 接口;
         * 2.断言 HTTP 状态码为 200;
         * 3.如果还有业务状态码,需要断言业务状态码为正确返回的状态码;
         */
        
        // 仅做效果演示,断言 200 = 200,总是真 
        $this->assertEquals(200, 200);
    }

    /**
     * 流程:
     * 1.下单(直接下单)
     * 2.支付(微信)
     * 3.发货
     * 4.收货
     * 5.退款(售后)
     */
    public function testCase2()
    {
        // 1.下单(直接下单)

        // 2.支付(微信)

        // 3.发货

        // 4.收货

        // 5.退款(售后)

        $this->assertEquals(200, 200);
    }
}

输出结果美化

代码语言:javascript复制
composer require --dev codedungeon/phpunit-result-printer

使用这个工具,可以让输出结果更加美观、清晰明了。

phpunit.xml 中配置 printerClass = "CodedungeonPHPUnitPrettyResultPrinterPrinter",例如:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    printerClass="CodedungeonPHPUnitPrettyResultPrinterPrinter"
    colors="true">
    <testsuites>
        <testsuite name="Laravel Test Suite">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

效果

代码语言:javascript复制
./vendor/bin/phpunit tests/Unit/OrderTest.php

两个绿色对勾,表示两个 Case 执行通过。

疑问

一、有同学会说了,这不是自动化的呀,需要手动执行一个命令才行,如果你们发布系统使用的 GitLab,那么在 GitLab 中增加一个环节即可,在这个环节中执行这个命令。

二、如果执行项目内全部的 case 怎么办?命令这样写就可以 ./vendor/bin/phpunit tests

三、Case 一定 API 测试吗?不一定,也可以测试自己的方法。

四、持续集成/持续交付与语言有关系吗?没关系。

小结

以上,就是一个可落地的方案,基本上跑通了,在此基础上编写就可以,根据自己的业务场景去完善吧。

在这做个小调查,大家在项目中都编写测试用例吗,为什么?欢迎大家在留言区评论。

0 人点赞