PHPUnit 加速技巧分享

file

具有高效的測試一如編寫高效的應用同樣重要。做爲開發者來講,迅速得知你剛編寫的代碼是否可以正常運行,可以讓開發效率大大提高。接下來咱們將會介紹一些能夠快速實現的小技巧,讓你的代碼測試變得更快。php

該示例測試套件有意地模擬更普遍的測試集合,並突出改進的可行性。真實狀況下,效率的提高可能有所差別。html

ParaTest

這個包 是一個用來運行你的測試套件的 PHPUnit 擴展。 和 PHPUnit 不同的是它能夠利用你的多核 CPU 來並行的運行測試用例。laravel

你能夠經過 composer 來將它做爲一個開發依賴安裝之後開始使用 ParaTestgit

composer require --dev brianium/paratest

如今咱們就能夠像調用 PHPUnit 同樣來調用 ParaTest 了。它會自動的根據你機器 CPU 核心數來判斷要啓動多少個進程。github

<img src="https://user-gold-cdn.xitu.io...;h=611&f=png&s=233798" class="rm-style">算法

上面,你能夠看到在控制檯中輸出了運行測試用例啓動了5個並行的進程。對比一下,下面用 PHPUnit 運行了一樣的測試用例。sql

<img src="https://user-gold-cdn.xitu.io...;h=177&f=png&s=20131" class="rm-style">數據庫

1.49 秒 和 6.15秒 !bootstrap

儘管 ParaTest 能夠本身肯定進程數,你也能夠嘗試設置進程數針對你的機器進行優化。使用  ---processes 選項,你能夠增長或減小進程數,由於並非進程數越多測試效果越好。緩存

./vendor/bin/paratest --processes 6

警告: 使用 ParaTest 測試數據庫前,須要考慮如何準備數據。若是使用 Lavarel 的  RefreshDatabase ,運行測試用例後會回滾或者遷移數據庫來寫入 。 相反的是,經過  DatabaseTransactions  跳過數據持久化, 這在運行測試期間不會嘗試修改數據。

重試失敗的測試

PHPUnit 有個很是方便的功能就是,容許你從新只運行上次測試中失敗的測試.。若是你正在進行紅綠復建風格的 TDD 開發,它將會加快你的開發週期。讓咱們從一個經過全部現存測試的測試套件來了解一下它這個功能。

<img src="https://user-gold-cdn.xitu.io...;h=162&f=png&s=13166" class="rm-style">

接下來,新增一個 red-green-refactor 測試模型的測試用例,預期失敗:

<img src="https://user-gold-cdn.xitu.io...;h=151&f=png&s=12965" class="rm-style">

在更改代碼庫以後你認爲新測試會經過,你想從新運行該測試套件以期能按預期運行。問題在於這個套件如今已經要花 1.3 秒的時間才能運行,隨着測試代碼量的增長,所需嚴重等待的時間也隨之增長。

若是咱們只能運行失敗的測試,那不是很好? 很是幸運的是 PHPUnit v7.3添加了這樣作的能力

<img src="https://user-gold-cdn.xitu.io...;h=151&f=png&s=11977" class="rm-style">

爲了實現這個功能,請將 cacheResult =「true」 添加到 phpunit.xml配置中。 PHPUnit 會始終記住之前哪些測試失敗了。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit cacheResult="true"
         backupGlobals="false"
         ...>

如今,當咱們運行咱們的測試單元時, PHPUnit 將記住哪些測試失敗並使用如下選項讓咱們能夠從新運行那些失敗的測試單元。

./vendor/bin/phpunit --order-by=defects --stop-on-defect

咱們再也不須要等待整個測試單元運行,以查看咱們試圖解決的一個測試是否正在經過。

將緩存文件 .phpunit.result.cache 添加到 .gitignore 也是一個好主意,這樣它就不會最終被提交到你的倉庫裏。

慢測試分組

PHPUnit 容許你用 @group 註解來將測試用例添加到不一樣的「分組」。若是你有一些測試用例尤爲的慢的話,最好是將他們分到同一個組。

class MyTest extends TestCase
{
    public function test_that_is_fast()
    {
        $this->assertTrue(true);
    }

    /**
     * @group slow
     */
    public function test_that_is_slow()
    {
        sleep(10);

        $this->assertTrue(true);
    }

    /**
     * @group slow
     */
    public function test_that_is_slow_2_adrians_revenge()
    {
        sleep(10);

        $this->assertFalse(false);
    }
}

在這個例子中,咱們有兩個測試用例要運行10秒鐘。 在咱們開發週期內最後一件要作的事情就是運行測試用例,尤爲是在作測試驅動開發的時候須要測試用例瞬時執行完成。

因爲兩個慢的測試用例都在同一個分組因此你能夠經過 PHPUnit 的 --exclude-group 選項在某一次測試運行中來排除他們。

./vendor/bin/phpunit --exclude-group slow

這個命令將會運行你測試用例中除了 slow 分組的全部測試用例。 測試用例分組還有一個好處,好比說你須要將你全部的慢測試用例整理成文檔以便後面再來優化他們。

然而在部署到生產環境前進行一些檢查確保全部測試用例能經過,包括慢的測試用例。 設置一個 CI 管道來運行測試用例會是個不錯的方法。

過濾測試

PHPUnit 有一個 --filter 選項,它接受一個模式來肯定運行哪些測試。例如,若是您將全部測試配置命名空間 ,則能夠經過指定命名空間來運行特定的測試子集。 如下命令僅在 Tests\Unit\Models 命名空間中運行測試並排除全部其餘命令。

./vendor/bin/phpunit --filter 'Tests\\Unit\\Models'

--filter 選項是靈活的,容許經過 methodNameClass::methodName 進行過濾,甚至能夠經過帶有 /path/to/my/test.php 的文件路徑進行過濾。您應該查看此選項的 PHPUnit docs 並查看更多的內容。

密碼哈希次數

Laravel 默認使用 bcrypt 密碼哈希算法,這種設計在系統資源上緩慢且昂貴。若是您的測試是驗證用戶密碼,能夠經過設置算法使用的次數來減小測試運行的時間,由於它執行的次數越多,所需的時間就越長。

若是你的應用程序與 laravel/laravelproject 中的最新更改保持同步,你會發現哈希次數的數量可使用環境變量進行自定義。bcrypt 容許的最小次數已經設置爲4,在 phpunit.xml file.

可是,若是您沒有同步最新的更新,可使用 Hash 門面在CreatesApplication trait 中設置它。

public function createApplication()
{
    $app = require __DIR__.'/../bootstrap/app.php';

    $app->make(Kernel::class)->bootstrap();

    // 設置 bcrypt 哈希次數...
    Hash::rounds(4);

    return $app;
}

內存數據庫

利用內存數據庫 SQLite ,是另外一種加速測試的方式。 你能夠經過在 phpunit.xml  配置文件裏添加兩個環境字段,來迅速開啓它。

<php>
    ...
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value=":memory:"/>
</php>

說明:儘管這樣看上去很容易,你應該考慮生產環境數據庫一致性問題。若是你在生產環境使用了 MySQL 數據庫,你應該警戒引入不一樣數據庫所帶來的測試上的不一樣,好比 SQLite。我在這篇文章 my feature test suite setup 裏描述了不少細節上的不一樣點。我認爲相比經過提高一點速度帶來的好處,保持生產環境一致更重要。

禁用 Xdebug

若是你平時用不到 Xdebug 的話,能夠禁用掉它,由於它會下降 PHP 執行速度,致使測試用例運行緩慢。若是你平常使用它來調試的話,爲了執行測試而禁用它可能不是一個好的選擇 —— 但你始終要知道這一點當你關注測試用例執行速度時。

你能夠在下面這個測試用例看到,一旦咱們禁用了 Xdebug,執行速度將會有極大的提升。下面是這個測試用例在 Xdebug 啓用時的執行狀況:

<img src="https://user-gold-cdn.xitu.io...;h=151&f=png&s=11703" class="rm-style">

以及一樣的測試用例在 Xdebug 禁用時的執行狀況:

<img src="https://user-gold-cdn.xitu.io...;h=151&f=png&s=11374" class="rm-style">

修復測試速度過慢

固然咱們最但願看到的段落是是:修復測試速度過慢!若是您正在努力肯定哪些測試致使測試單元變慢時,您可能須要查看 PHPUnit Report 。它是一個開源工具,容許您經過生成以下所示的雲可視化您的測試單元的性能,其中較大的氣泡表明慢速測試。這將使您可以在單元中找到最慢的測試並逐步提升其性能。

file

轉自 PHP / Laravel 開發者社區 https://laravel-china.org/top...
相關文章
相關標籤/搜索