Gulp 是一個使用 JavaScript 編寫的自動化構建工具。用於對前端通用任務(如最小化、壓縮、編譯)進行自動構建。Gulp 還能夠用來監控源代碼的改動並自動運行任務。php
Laravel 5.1 提供了一個封裝 Gulp 的 Laravel Elixir 包,可用於輕鬆構建 Gulp 任務,Elixir 爲 Gulp 添加了優雅的語法,Elixir 之於 Gulp 正如 Laravel 之於 PHP。前端
Gulp 最多見的用法之一就是自動構建單元測試,這裏咱們將遵循 TDD(測試驅動開發)流程讓 Gulp 自動運行測試。laravel
首先,編輯根目錄下的 gulpfile.js
文件以下:git
var elixir = require('laravel-elixir'); elixir(function(mix) { mix.phpUnit(); });
這裏咱們調用 elixir()
方法,接收的 mix
對象能夠用於處理不少事情。你能夠用它來將 LESS 文件編譯成 CSS 文件,也能夠用它來將多個 CSS 文件合併到一塊兒,而且爲合併後的文件添加版本控制,等等等等。全部這些事情均可以經過調用 mix
對象提供的接口方法來實現。github
可是如今,咱們只運行 PHPUnit 測試。web
接下來,在本地主機的項目根目錄下,運行 gulp
來看看會發生什麼:gulp
你應該還會接收到一個彈出框通知,通知若是是綠色的代表測試成功:ubuntu
若是想讓 gulp
進入自動進行單元測試模式,須要在本地主機的命令行中使用 gulp tdd
命令:markdown
若是Ubuntu下執行該命令報錯:Error: watch ENOSPC,對應解決辦法是在終端執行以下命令:app
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 便可。
在本博客項目中咱們將使用 Markdown 格式編輯文章。Markdown 是一種輕量級的標記語言,Markdown 的理念是能讓文檔更容易讀、寫和隨意改。Markdown 格式文本能夠被輕鬆轉化爲 HTML。
爲了舉例進行測試,咱們將要使用 TDD 開發流程構建將 Markdown 文本轉化爲 HTML 文本的服務。
有不少 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"
開啓 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 \App\Services\Markdowner(); } public function testSimpleParagraph() { $this->assertEquals( "<p>test</p>\n", $this->markdown->toHTML('test') ); } }
保存文件後,你應該會接收到測試失敗通知。
這裏須要說明的是,儘管測試有時候會失敗,但有時候這也是件好事情,由於經過失敗信息能夠推斷哪裏出錯了,從而方便咱們迅速解決問題。此時錯誤的緣由是 App\Services\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"], ]; } }
這裏咱們修改測試類同時進行多個轉化測試。
這裏咱們不想列出 Laravel 5.1 中全部可用的測試方法,由於PHP中的測試方法不是單一的,也不是固定不變的,在 Laravel 中一樣也是如此。可是這裏,咱們仍是想要列出一些其它可選的測試方法。
除了 PHPUnit 以外,Laravel 5.1還提供了開箱即用的 phpspec。這是另外一個流行的 PHP 單元測試工具,聚焦於行爲驅動開發(BDD)。
下面是 phpspec 的一些說明:
vendor/bin
目錄下,所以能夠在項目根目錄中直接運行 phpspec
phpspec.yml
mix
對象上的 phpSpec()
函數App
改爲了其它的,須要修改 phpspec.yml
中相應的配置儘管說到 PHP 單元測試,PHPUnit 已經成爲事實上的標準方式,但仍是有一些其餘單元測試包可供使用:
這種測試是對整個應用進行測試而不是僅僅驗證應用中的某個片斷。當使用 Laravel 5.1 提供的測試方法時,還可使用 PHPUnit 進行一些功能測試。ExampleTest.php
中提供了一個簡單的示例,可是還有專門的測試框架專一於功能測試:
BDD 有兩個分支:SpecBDD 和 StoryBDD
SpecBDD 專一於代碼的技術層面,Laravel 5.1 自帶的 phpspec 是標準的SpecDD
StoryBDD 則強調商業或者功能測試,Behat 是最流行的 StoryBDD 框架,此外,Codeception 也能夠用做 StoryBDD。