PHP 开发入门自动化测试历程(二)

刻意练习,坚持

在上篇文章中,对 PHPUnit已经有了基础的认识后,就可以回归到真实的场景中,在 Laravel 框架中为应用程序编写自动化测试代码。

Laravel 测试

Laravel官方文档中,明确写出了其对测试的良好支持,默认就支持用 PHPUnit 来做测试。这个支持可能表现在这两个地方:

  • 默认引用了 phpunit/phpunit
  • 优雅扩展了 PHPUnit

了解 Laravel 测试结构

要在框架中编写测试,首先得了解框架和测试代码的结构。

在一个 Laravel 应用根目录下,默认存在 如下结构:

  • tests 目录(编写测试的地方)
    • Feature 目录(存放功能测试)
    • Unit 目录(存放单元测试)
    • CreateApplication.php 文件(用于初始化框架应用)
    • TestCase 文件(所有测试类需要继承的抽象类,内部引用了 CreateApplication
  • phpunit.xml文件(指导 phpunit运行 )。

因此,当安装好了 PHPUnit ,并在根目录下执行 phpunit命令,会自动搜索 phpunit.xml 文件,然后根据文件里的配置信息运行默认的测试。

如果没有安装 PHPUnit,因为默认引用了 phpunit/phpunit包,还可以使用 ./vendor/bin/phpunit 运行测试。

不纠结功能测试与单元测试

在上一篇文章中,就提到了不要过分纠结功能测试、单元测试这些概念的定义。但现在遇到了,就给出自己简单的认知(不一定正确,主要是让自己理解),以接口开发为例:

  • 针对某个具体接口或多个接口组合的测试,可以称为 “功能测试”
  • 每个接口中可能调用多个独立方法,针对这些方法的测试,可以理解为 “单元测试”

具体编写测试

在有了上述的基础后,就可以开始编写自己的测试代码了,不要期望一口气写出多么优雅、完善的测试代码,最重要的是 坚持 刻意练习,在编写的过程中不断调整总结自己的经验出来。以一个简单的保存接口为例:

存在一个接口 xxx/article用于新建文章,那就可以为此创建一个功能测试: php artisan make:test CreateArticleTest ,内容如下:

<?php 
namespace Tests\Feature\Credits;   

use Tests\TestCase;   

class CreateArticleTest extends TestCase 
{  
    // 接口URI  
    protected $createArticleUri = 'xxx/article';    
    /**  @test 测试创建文章要求必填标题*/ 
    public function create_article_require_title()  
    {  
        // 请求接口,并断言接口响应与返回码  
        $this->json('POST', $this->createArticleUri, ['title' => null])
            ->assertStatus(200) 
            ->assertJson(['code' => 'xxxx']);  
    } 
}

假设接口内部,会验证文章是否重名,通常我们会为此编写一个独立方法,此时就需要创建一个单元测试: php artisan make:test ArticleTest --unit ,内容如下:

<?php 
namespace Tests\Unit;   

use Tests\TestCase;   

class ArticleTest extends TestCase 
{  
    /** @test 测试可以判断文章是否重名*/  
    public function can_konw_title_is_repeat()  
    {  
        $articleOne = factory(Article::class)->create(['title' => '标题1']);
        $articleTwo = factory(Article::class)->make(['title' => '标题1']);
        $result = $articleTwo->isRepeat();
        $this->assertTrue($result);
    } 
}

总结

上面列举了一个非常简单的测试,这里并不会详细的介绍 Laravel 框架里测试的方法,建议阅读官方文档,后面会列出参考链接。

要再次强调,对于开发而言,写这些测试代码的难度并不高,关键还是要坚持写、刻意练习、不断总结,入门都不是问题。

在养成编写测试代码的习惯后,遇到的测试场景也会越来越多,思维也会更加完善,代码质量随着会更加有保障。

Laravel 网站有个文档 《TDD 构建 Laravel 论坛笔记》,是很不错的入门指引,有条件也可以购买网站上的 L07 Laravel 教程 - Laravel TDD ,这也是很好的教程。

在入门的过程中,自己也总结了一些点:

  • 注意直接使用 PHPUnit与在 Laravel 中使用的差异
    因为 Laravel扩展了 PHPUnit,因此某些方法是原生 PHPUnit中不存在的,只在 Laravel 中可以使用,不过这些扩展的内容,使用起来确实会更加优雅。

  • 使用 Laravel 数据库事务,清理测试数据
    Laravel 提供了 DatabaseTransactionTrait,只要在测试类中引入了。就会将每个测试用例包含在事务中, 及时清除数据库里的测试数据。

  • 暴露异常,便于定位问题
    对于接口 Laravel 默认会进行异常处理,这在测试过程中是不利于调试的,可以在测试方法中使用:

    // 不处理异常 
    $this->withoutExceptionHandling();   
    // 处理异常 
    $this->withExceptionHandling();
  • 使用 Laravel 模型工厂快捷造数据
    很多测试的执行,都需要依赖很多数据,通过 Laravel 的模型工厂,可以很快捷的构造需要的数据。

参考

后续历程

本作品采用《CC 协议》,转载必须注明作者和本文链接
生于忧患,死于安乐
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!