zoukankan      html  css  js  c++  java
  • 基于 Laravel 开发博客应用系列 —— 从测试开始(二):使用Gulp实现自动化测试

    3、使用 Gulp 进行 TDD(测试驱动开发)

    Gulp 是一个使用 JavaScript 编写的自动化构建工具。用于对前端通用任务(如最小化、压缩、编译)进行自动构建。Gulp 还可以用来监控源代码的改动并自动运行任务。

    Laravel 5.1 提供了一个封装 Gulp 的 Laravel Elixir 包,可用于轻松构建 Gulp 任务,Elixir 为 Gulp 添加了优雅的语法,Elixir 之于 Gulp 正如 Laravel 之于 PHP。

    Gulp 最常见的用法之一就是自动构建单元测试,这里我们将遵循 TDD(测试驱动开发)流程让 Gulp 自动运行测试。

    首先,编辑根目录下的 gulpfile.js 文件如下:

    var elixir = require('laravel-elixir');
    
    elixir(function(mix) {
        mix.phpUnit();
    });
    

    这里我们调用 elixir() 方法,接收的 mix 对象可以用于处理很多事情。你可以用它来将 LESS 文件编译成 CSS 文件,也可以用它来将多个 CSS 文件合并到一起,并且为合并后的文件添加版本控制,等等等等。所有这些事情都可以通过调用 mix 对象提供的接口方法来实现。

    但是现在,我们只运行 PHPUnit 测试。

    接下来,在本地主机的项目根目录下,运行 gulp 来看看会发生什么:

    gulp运行phpunit执行结果

    你应该还会接收到一个弹出框通知,通知如果是绿色的表明测试成功:

    2015-11-29 15-35-01

    如果想让 gulp 进入自动进行单元测试模式,需要在本地主机的命令行中使用 gulp tdd 命令:

    使用gulp tdd实现自动化测试

    如果Ubuntu下执行该命令报错:Error: watch ENOSPC,对应解决办法是在终端执行如下命令:

    echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

    再重新运行 gulp tdd 即可。

    运行 gulp tdd 命令后该命令会一直挂起在那里,监听源文件的修改,并在需要的时候运行单元测试。

    为了演示是否有效,我们修改 tests/ExampleTest.php 中的 see() 这一行测试代码如下:

    $this->visit('/')->see('Laravel Academy');

    保存这个文件后,gulp 将会接到通知并再次运行单元测试。这一次运行测试失败,并会看到类似下面这样的失败提示框:

    使用Gulp运行单元测试失败提示框

    撤销 tests/ExampleTest.php 中的修改并保存,gulp 会再次运行 PHPUnit,这一次又可以接收到测试成功通知。

    注:要退出 Gulp 的 tdd 模式只需使用快捷键 Ctrl+C 即可。

    4、创建Markdown服务

    在本博客项目中我们将使用 Markdown 格式编辑文章。Markdown 是一种轻量级的标记语言,Markdown 的理念是能让文档更容易读、写和随意改。Markdown 格式文本可以被轻松转化为 HTML。

    为了举例进行测试,我们将要使用 TDD 开发流程构建将 Markdown 文本转化为 HTML 文本的服务。

    安装 Markdown 依赖包

    有很多 PHP 包可用于将 Markdown 转化为 HTML。这里我们使用 Michel Fortin 提供的包 SmartyPants,在本地主机上使用 Composer 安装下面两个依赖包:

    nonfu@ubuntu:~/Code/blog$ composer require michelf/php-markdown 
    nonfu@ubuntu:~/Code/blog$ composer require "michelf/php-smartypants=1.6.0-beta1"

    创建 Markdown 测试类

    开启 TDD 首先要做的事情就是触发 gulp 为 tdd 模式(如果已经开启略过此步):

    nonfu@ubuntu:~/Code/blog$ gulp tdd

    现在 Gulp 已经在监听文件修改,一旦有“风吹草动”,就会立即运行 PHPUnit。

    下面我们来创建测试类。在 tests 目录中创建一个 Services 文件夹,并在该文件夹下新建一个MarkdownerTest.php,编辑文件内容如下:

    <?php
    
    class MarkdownerTest extends TestCase
    {
    
        protected $markdown;
    
        public function setup()
        {
            $this->markdown = new AppServicesMarkdowner();
        }
    
        public function testSimpleParagraph()
        {
            $this->assertEquals(
                "<p>test</p>
    ",
                $this->markdown->toHTML('test')
            );
        }
    }
    

    保存文件后,你应该会接收到测试失败通知。

    这里需要说明的是,尽管测试有时候会失败,但有时候这也是件好事情,因为通过失败信息可以推断哪里出错了,从而方便我们迅速解决问题。此时错误的原因是 AppServicesMarkdowner 这个类不存在。

    创建Markdowner服务

    这里我们创建一个封装前面使用 Composer 安装的 php-markdown 和 php-smartypants 包的简单服务类。

     appServices 目录下新建 Markdowner.php 文件,编辑该文件内容如下:

    <?php
    
    namespace AppServices;
    
    use MichelfMarkdownExtra;
    use MichelfSmartyPants;
    
    class Markdowner
    {
    
        public function toHTML($text)
        {
            $text = $this->preTransformText($text);
            $text = MarkdownExtra::defaultTransform($text);
            $text = SmartyPants::defaultTransform($text);
            $text = $this->postTransformText($text);
            return $text;
        }
    
        protected function preTransformText($text)
        {
            return $text;
        }
    
        protected function postTransformText($text)
        {
            return $text;
        }
    }
    

    保存该文件后,Gulp 检测到文件修改然后重新运行单元测试,这次会就收到绿色的提示,代表测试通过,一切正常。

    如果没有看到绿色提示,则代表测试失败,需要回头检查下 AppServicesMarkdowner 和 MarkdownerTest 这两个类看是否有什么问题。

    更加复杂的迭代测试

    诚然,这并不是 TDD 的最佳示例,因为这只是先创建一个简单的测试类,然后创建实现类修复测试出现的问题。在实际应用场景中,TDD 应该有更多次的迭代,其大致流程应该像这样:

    • 创建 MarkdownerTest,定义测试方法
    • 测试失败
    • 创建 Markdowner 类,硬编码 toHTML() 进行测试
    • 测试成功
    • 修改 Markdowner 类使用 MarkdownExtra
    • 测试成功
    • 添加 testQuotes() 方法到 MarkdownerTest 类
    • 测试失败
    • 修改 Markdowner 类使用 SmartyPants
    • 测试成功

    以此类推。甚至 Markdowner 类的结构都是有缺陷的,要对该类进行纯正的单元测试,应该将 MarkdownExtra 和  SmartyPants 的实例注入到 Markdowner 的构造函数中,这样的话我们的单元测试可以注入模拟的对象并且只验证  MarkdownExtra 的行为而不是其调用的类。

    但是本系列教程不是关于测试的,实际上,我们只会在这里讨论测试,我们仍将保留其结构但是会添加更多的测试。

    修改 MarkdownerTest.php 文件内容如下:

    <?php
    
    class MarkdownerTest extends TestCase
    {
    
        protected $markdown;
    
        public function setup()
        {
            $this->markdown = new AppServicesMarkdowner();
        }
    
        /**
         * @dataProvider conversionsProvider
         */
        public function testConversions($value, $expected)
        {
            $this->assertEquals($expected, $this->markdown->toHTML($value));
        }
    
        public function conversionsProvider()
        {
            return [
                ["test", "<p>test</p>
    "],
                ["# title", "<h1>title</h1>
    "],
                ["Here's Johnny!", "<p>Here&#8217;s Johnny!</p>
    "],
            ];
        }
    }
    

    这里我们修改测试类同时进行多个转化测试。

    5、其它测试方法

    这里我们不想列出 Laravel 5.1 中所有可用的测试方法,因为PHP中的测试方法不是单一的,也不是固定不变的,在 Laravel 中同样也是如此。但是这里,我们还是想要列出一些其它可选的测试方法。

    phpspec

    除了 PHPUnit 之外,Laravel 5.1还提供了开箱即用的 phpspec。这是另一个流行的 PHP 单元测试工具,聚焦于行为驱动开发(BDD)。

    下面是 phpspec 的一些说明:

    • 安装在 vendor/bin 目录下,因此可以在项目根目录中直接运行 phpspec
    • 配置文件是位于项目根目录下的 phpspec.yml
    • 要从 Gulp 中运行 phpspec,可以调用 mix 对象上的 phpSpec() 函数
    • 如果你将应用的命名空间名称 App 改成了其它的,需要修改 phpspec.yml 中相应的配置

    单元测试

    尽管说到 PHP 单元测试,PHPUnit 已经成为事实上的标准方式,但还是有一些其他单元测试包可供使用:

    功能测试

    这种测试是对整个应用进行测试而不是仅仅验证应用中的某个片段。当使用 Laravel 5.1 提供的测试方法时,还可以使用  PHPUnit 进行一些功能测试。ExampleTest.php 中提供了一个简单的示例,但是还有专门的测试框架专注于功能测试:

    行为驱动开发(BDD)

    BDD 有两个分支:SpecBDD 和 StoryBDD

    SpecBDD 专注于代码的技术层面,Laravel 5.1 自带的 phpspec 是标准的SpecDD

    StoryBDD 则强调商业或者功能测试,Behat 是最流行的 StoryBDD 框架,此外,Codeception 也可以用作 StoryBDD。

  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/chinalorin/p/5845266.html
Copyright © 2011-2022 走看看