Skip to content

Zeroplex 生活隨筆

軟體開發和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

標籤: PHP

由網頁觸發、執行 PHPUnit

Posted on 2018 年 5 月 31 日2021 年 3 月 12 日 By 日落 在〈由網頁觸發、執行 PHPUnit〉中尚無留言

通常都是在 console 底下執行 PHPUnit 跑測試:

$ phpunit Test.php 
... Run by vendor/bin/phpunit ...
PHPUnit 7.1.5 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 30 ms, Memory: 4.00MB

OK (1 test, 1 assertion)

但若開發環境無法使用 console 的話,只能靠寫 PHP script 來 require PHPUnit library 來執行。在這邊發現其實 PHPUnit 有保留 interface 讓使用者可以不透過 console 來操作 PHPUnit,可以在 PHP script 裡面 require library 來使用。

先使用 composer 把 library 拉下來:

composer require 'phpunit/phpunit'

在 PHPUnut/TextUI 底下,有實作幾個 controller 來模擬 console 的操作。以下使用 Command 來執行 PHPUnit:

<?php

require __DIR__ . '/vendor/autoload.php';

use PHPUnitTextUICommand;

$cmd = new Command();

$cmd->run([
    'phpunit',  // 1st arg
    'Test.php', // 2nd arg
]);

如果執行上面這段 PHP script,會得到與在 console 執行 PHPUnit 一樣的結果。
不過要注意的是測試結果會直接輸出到 std out,若另外處理的話,記得用 output buffer 把資料拉回來,直接在瀏覽器看的話會破版。

備註:PHPUnit 不同版本的路徑不同,類別名稱也會不同。

Tags:PHP, PHPUnit

PHP 7.1 的 Symmetric Array Destructuring

Posted on 2018 年 5 月 24 日2021 年 3 月 12 日 By 日落 在〈PHP 7.1 的 Symmetric Array Destructuring〉中尚無留言

PHP 7.1 對 list() 語法做了一些調整,讓 list() 操作使用起來更簡便。

原本的 list() 語法:

list($a, $b) = [1, 2];
// $a = 1, $b = 2

在 7.1 以後可以使用陣列來表示:

[$a, $b] = [1, 2];

這個語法稱為 Symmetric Array Destructuring。

有了這個 feature 以後,不用另外宣告暫存變數也可以對調變數 (swap):

[$b, $a] = [$a, $b];
Tags:PHP, 程式設計

PHP array 新增 element 的方法和效率

Posted on 2018 年 5 月 7 日2021 年 3 月 12 日 By 日落 在〈PHP array 新增 element 的方法和效率〉中尚無留言

新增 element 到 PHP array 的寫法有二種,一種是用 array_push(),一種是使用 $list[] 直接新增。

跑個迴圈塞一千萬筆資料進 array,看看哪一種寫法的速度比較快。

這個是 array_push() 的:

$list = [];

$start = microtime(true);

for ($a = 0; $a < 10000000; $a++ ) {
    array_push($list, 1);
}

$end = microtime(true);

var_dump($end - $start);  // double(7.2292509078979)

同上,若將語法換掉的話:

$list = [];

$start = microtime(true);

for ($a = 0; $a < 10000000; $a++ ) {
    $list[] = 1;
}

$end = microtime(true);

var_dump($end - $start);  // double(2.0703480243683)

小量資料的話,其實二種作法在速度上不會差很多,但資料量變大時,速度差異就會變得很明顯。

Tags:PHP

PHP 中 「…」(three dots) 也可以用在 argument provider

Posted on 2018 年 3 月 9 日2021 年 3 月 12 日 By 日落 在〈PHP 中 「…」(three dots) 也可以用在 argument provider〉中尚無留言

看了 PHPUnit 的 source code,發現有個很有趣的寫法:

function assertSame($expected, $actual, string $message = ''): void
{
    Assert::assertSame(...func_get_args());
}

最初以為「…」只能用在定義 variable-length function argument/param,重新看了文件才發現之前文件沒有看完,也可以拿來把陣列分別當作 argument/param 傳入:

function add($a, $b) {
    return $a + $b;
}

add(...[1, 2]);  // $a = 1, $b = 2

// or ...

$args = [1, 2];
add(...$args);
Tags:PHP

PHPUnit 中「backupGlobals」的作用

Posted on 2018 年 3 月 8 日2021 年 3 月 12 日 By 日落 在〈PHPUnit 中「backupGlobals」的作用〉中尚無留言

複習 PHPUnit 順手寫了小程式做實驗。

PHPUnit 為了讓各個不同的 test case 不會因為 super globals 變數而互相影響,設計了 「backupGlobals」這個功能。先來看範例程式:

class MyTest extends TestCase
{
    public function testOne()
    {
        $GLOBALS['test'] = 123;

        $this->assertArrayHasKey('test', $GLOBALS);
    }

    public function testTwo()
    {
        $this->assertArrayHasKey('test', $GLOBALS);
    }
}

範例中 testOne() 修改了 $GLOBALS 變數的內容,如果在不使用「backupGlobals」的情況下,在 testTwo() 中的 $GLOBALS 也會保留 testOne() 修改過的內容,使 testTow() 抓得到「test」這個 key:

$ phpunit MyTest.php 
PHPUnit 7.0.2 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 40 ms, Memory: 4.00MB

OK (2 tests, 2 assertions)

也就表示 testOne() 影響到了 testTwo() 的測試結果,這在測試時是不樂見的,各個測試應該有獨立的測試環境,不應該互相影響。

使用「backupGlobals」功能,PHPUnit 會在 test case 執行之前,使用 serialize() 對 super globals 做備份,並在測試結束以後 unserialize() 復原,所以 testOne() 中做的修改就不會影響到 testTwo() 了:

$ phpunit --globals-backup MyTest.php 
PHPUnit 7.0.2 by Sebastian Bergmann and contributors.

.F                                                                  2 / 2 (100%)

Time: 52 ms, Memory: 4.00MB

There was 1 failure:

1) MyTest::testTwo
Failed asserting that an array has the key 'test'.

/home/johnroyer/tmp/MyTest.php:16

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

重點來了,因為是使用 serialize() 和 unserialize(),所以只能針對 primitive type 進行備份和還原,如果使用了 object 或是 singleton 時,「backupGlobals」就派不上用場了。這個時候要使用殺手鐧「runTestsInSeparateProcesses」:

/**
 * @runTestsInSeparateProcesses
 */
class MyTest extends TestCase
{
    ....
}

使用這個 annotation 會讓 PHPUnit 為每個 test case 分別 fork 出新的 proccess 進行測試,因此不同 test case 就可以在完全獨立的環境下執行不受影響:

$ phpunit MyTest.php 
PHPUnit 7.0.2 by Sebastian Bergmann and contributors.

.F                                                                  2 / 2 (100%)

Time: 303 ms, Memory: 4.00MB

There was 1 failure:

1) MyTest::testTwo
Failed asserting that an array has the key 'test'.

/home/johnroyer/tmp/MyTest.php:19

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

但使用這個殺手鐧也是要付出一點代價:時間。最前二次執行 PHPUnit 時,跑完二個 test case 只花費了 50ms 左右,而開 proccess 來進行測試則花了 300ms。

Tags:PHP, PHPUnit

文章分頁

上一頁 1 ... 12 13 14 ... 27 下一頁

其他

關於我  (About me)

  文章 RSS Feed

  留言 RSS Feed

Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Raspberry Pi Ubuntu Unix Vim Web Windows XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.