基于 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 进入自动进行单元测试模式,需要在本地主机的命令行中使用 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 将会接到通知并再次运行单元测试。这一次运行测试失败,并会看到类似下面这样的失败提示框:

撤销 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 安装下面两个依赖包:

[email protected]:~/Code/blog$ composer require michelf/php-markdown
[email protected]:~/Code/blog$ composer require "michelf/php-smartypants=1.6.0-beta1"

创建 Markdown 测试类

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

[email protected]:~/Code/blog$ gulp tdd

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

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

<?php

class MarkdownerTest extends TestCase
{

    protected $markdown;

    public function setup()
    {
        $this->markdown = new \App\Services\Markdowner();
    }

    public function testSimpleParagraph()
    {
        $this->assertEquals(
            "<p>test</p>\n",
            $this->markdown->toHTML(‘test‘)
        );
    }
}

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

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

创建Markdowner服务

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

在 app\Services 目录下新建 Markdowner.php 文件,编辑该文件内容如下:

<?php

namespace App\Services;

use Michelf\MarkdownExtra;
use Michelf\SmartyPants;

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 检测到文件修改然后重新运行单元测试,这次会就收到绿色的提示,代表测试通过,一切正常。

如果没有看到绿色提示,则代表测试失败,需要回头检查下 App\Services\Markdowner 和 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 \App\Services\Markdowner();
    }

    /**
     * @dataProvider conversionsProvider
     */
    public function testConversions($value, $expected)
    {
        $this->assertEquals($expected, $this->markdown->toHTML($value));
    }

    public function conversionsProvider()
    {
        return [
            ["test", "<p>test</p>\n"],
            ["# title", "<h1>title</h1>\n"],
            ["Here‘s Johnny!", "<p>Here’s Johnny!</p>\n"],
        ];
    }
}

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

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。

时间: 2024-11-19 09:33:49

基于 Laravel 开发博客应用系列 —— 从测试开始(二):使用Gulp实现自动化测试的相关文章

基于 Laravel 开发博客应用系列 —— 从测试开始(一):创建项目和PHPUnit

1.创建博客项目 我们将遵循上一节提到的六步创建一个新 Laravel 5.1 项目的步骤,创建本节要用到的博客项目 —— blog. 首先,在本地主机安装应用骨架: [email protected]:~/Code$ composer create-project laravel/laravel blog --prefer-dist 接下来,编辑 Homestead.yaml,添加站点信息及数据库信息: sites: - map: test.app to: /home/vagrant/Code

基于 Laravel 开发博客应用系列 —— 设置 Windows 本地开发环境

1.安装原生PHP 下载/解压 PHP 到 PHP 下载页下载最新版本的 PHP(如果使用 Laravel 5.1 的话需要 PHP 5.5.9+ 版本),解压下载的zip格式压缩文件到本地目录,比如E:\Php. 编辑 php.ini 打开命令行按照如下步骤创建php.ini文件: C:\Users\Test>E: E:\>cd Php E:\Php> copy php.ini-development php.ini 然后在编辑 php.ini: // 将 ; extension_di

基于Laravel开发博客应用系列 —— 使用Bower+Gulp集成前端资源

本节我们将讨论如何将前端资源集成到项目中,包括前端资源的发布和引入.本项目将使用 Bower 和 Gulp 下载和集成jQuery.Bootstrap.Font Awesome 以及 DataTables. 1.“偷”别人的代码 开发 web 应用最快的方式就是借鉴别人的项目.换句话说,“偷”他们的代码. 当然,不是真偷. 举个例子吧,Twitter Bootstrap 的许可证声明允许任何人可以免费使用 Bootstrap 框架. 现在的 web 站点包含很多东西:框架.库.前端资源,等等.如

基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境

1.不同 Linux 发行版本的区别 不同的 Linux 发行版本之间有一些细微区别,尤其是包管理器:CentOS 和 Fedora 使用 yum 作为包管理器,而Ubuntu 使用  apt,在 OS X 上除了 App Store 之外没有其他官方的包管理器了,但有一个非官方的 OS X 包管理器 —— homebrew.抛开表象的不同,这些 *nix 系统背后的原理都是一致的,包括 OS X. 声明:本节如无特别说明,默认使用 Ubuntu 15.10 系统. 2.安装 PHP PHP 通

基于 Laravel 开发博客应用系列 —— Homestead 和 Laravel 安装器

1.Homestead 从主机操作系统的控制台中(Windows 中被称作命令提示符,Linux 中被称作终端),你可以轻松通过不带参数的homestead 命令查看所有有效的 Homestead 命令: 日常最经常使用的命令恐怕非启动 Homestead 虚拟机的 homestead up 莫属了. 2.常用 Homestead 命令概览 下面是常用的 Homestead 命令说明: homestead up:该命令用于启动 Homestead 虚拟机,如果加上 --provision 选项那

文顶顶iOS开发博客链接整理及部分项目源代码下载

文顶顶iOS开发博客链接整理及部分项目源代码下载 网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课和跟着文顶顶的博客做项目之后,最快只需要2个月时间,就基本可以独立完成iOS App的开发工作.有经验的开发者也可以在该博客中寻找代码片段进行学习借鉴,必有所收获. 在此也向@文顶顶 表示严重感谢! 由于文顶顶博客博文繁多,每次找文章需要频繁的翻页,

iOS开发-博客导出工具开发教程(附带源码)

前言: 作为一名学生, 作为一名iOS开发学习者, 我个人浏览信息包括博客, 更多的选择移动终端.然而, csdn并没有现成的客户端(不过有个web版的). 之前曾经看到一款开源的导出工具, 但是它是基于Windows平台的.导出的也仅仅是PDF格式.而且, 对于文章的导出, 需要精确URL.无法做到边浏览别导出. 另外, 我想实现的是, 可以在没有网络的情况下, 浏览自己收藏的文章.并且, 对于自己收藏的文章, 可以分类管理. 最关键的是, 对于自己的文章, 可以做一个备份.我曾经遇到过这样一

Django1.7开发博客

转自: http://www.pycoding.com/articles/category/django 基于最新的django1.7写的,通俗易懂,非常适合新手入门. 感谢博主! 参考教程: http://tutorial.djangogirls.org/ GitHub项目地址: https://github.com/yidao620c/simpleblog Heroku演示地址: https://yidaoblog.herokuapp.com/   教程目录: 使用Django1.7开发博客

中文 iOS/Mac 开发博客列表(网址改进)

中文 iOS/Mac 开发博客列表(网址改进) https://github.com/tangqiaoboy/iOSBlogCN 大牛blog: http://blog.devtang.com/ 唐巧 网易微博后台 .猿题库.有道云笔记.粉笔网 http://beyondvincent.com/blog/archives/ 破船 http://onevcat.com/ 王巍 Line 技术领域 :ios+unity3d http://swifter.tips 王巍 swifter 的网站 htt