成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

用phpunit進(jìn)行TDD入門

amc / 2064人閱讀

摘要:新的構(gòu)造函數(shù)接下來,我想到,用戶可能需要一個(gè)不同的構(gòu)造函數(shù),當(dāng)創(chuàng)建對象時(shí),可以傳入一個(gè)值作為賬戶余額。修改構(gòu)造函數(shù)為這樣調(diào)用時(shí),相當(dāng)于傳遞了給構(gòu)造函數(shù),滿足了需求。

  

用phpunit實(shí)戰(zhàn)TDD系列

從一個(gè)銀行賬戶開始

假設(shè)你已經(jīng) 安裝了phpunit.

我們從一個(gè)簡單的銀行賬戶的例子開始了解TDD(Test-Driven-Development)的思想。

在工程目錄下建立兩個(gè)目錄, srctest,在src下建立文件 BankAccount.php,在test目錄下建立文件BankAccountTest.php

按照TDD的思想,我們先寫測試,再寫生產(chǎn)代碼,因此BankAccount.php留空,我們先寫BankAccountTest.php


現(xiàn)在我們運(yùn)行一下,看看結(jié)果。運(yùn)行phpunit的命令行如下:

phpunit --bootstrap src/BankAccount.php test/BankAccountTest.php

--bootstrap src/BankAccount.php是說在運(yùn)行測試代碼之前先加載 src/BankAccount.php,要運(yùn)行的測試代碼是test/BankAccountTest.php。

如果不指定具體的測試文件,只給出目錄,phpunit則會(huì)運(yùn)行目錄下所有文件名匹配 *Test.php 的文件。因?yàn)?b>test目錄下只有BankAccountTest.php一個(gè)文件,所以執(zhí)行

phpunit --bootstrap src/BankAccount.php test

會(huì)得到一樣的結(jié)果。

There was 1 failure:

1) Warning
No tests found in class "BankAccountTest".

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

一個(gè)警告錯(cuò)誤,因?yàn)闆]有任何測試。

賬戶實(shí)例化

下面我們添加一個(gè)測試。注意,TDD是一種設(shè)計(jì)方法,可以幫助你自底向上地設(shè)計(jì)一個(gè)模塊的功能。我們寫測試的時(shí)候,要從用戶的角度出發(fā)。如果用戶使用我們的BankAccount類,他首先做什么事呢?一定是新建一個(gè)BankAccount的實(shí)例。那么我們第一個(gè)測試就是對于 實(shí)例化 的測試。

public function testNewAccount(){
    $account1 = new BankAccount();
}

運(yùn)行phpunit,意料之中地失敗。

PHP Fatal error:  Class "BankAccount" not found in /home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php on line 5

沒有發(fā)現(xiàn)BankAccount類的定義,下面我們就要寫生產(chǎn)代碼。使測試通過。在src/BankAccount.php(后面稱之為源文件)中輸入以下內(nèi)容:


運(yùn)行phpunit,測試通過。

OK (1 test, 0 assertions)

接下來,我們要增加測試,使得測試失敗。如果新建一個(gè)賬戶,賬戶的余額應(yīng)該是0。于是我們添加了一個(gè)assert語句:

public function testNewAccount(){
    $account1 = new BankAccount();
    $this->assertEquals(0, $account1->value());
}

注意value()BankAccount的一個(gè)成員函數(shù),當(dāng)然這個(gè)函數(shù)還沒有定義,作為使用者我們希望BankAccount提供這個(gè)函數(shù)。

運(yùn)行phpunit,結(jié)果如下:

PHP Fatal error:  Call to undefined method BankAccount::value() in /home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php on line 6

結(jié)果告訴我們BankAccount并沒有value()這個(gè)成員函數(shù)。添加生產(chǎn)代碼:

class BankAccount {
    public function value(){
        return 0;
    }
}

為什么要讓value()直接返回0,因?yàn)闇y試代碼中希望value()返回0。TDD的原則就是不寫多余的生產(chǎn)代碼,剛好讓測試通過即可。

賬戶的存取

運(yùn)行phpunit通過后,我們先假設(shè)BankAccount的實(shí)例化已經(jīng)滿足要求了,接下來,用戶希望怎么使用BankAccount呢?一定希望往里面存錢,嗯,希望BankAccount有一個(gè)deposit函數(shù),通過調(diào)用該函數(shù),可以增加賬戶余額。于是我們增加下一個(gè)測試。

public function testDeposit(){
    $account = new BankAccount();
    $account->deposit(10);
    $this->assertEquals(10, $account->value());
}

賬戶初始余額是0,我們往里面存10元,其賬戶余額當(dāng)然應(yīng)該為10。運(yùn)行phpunit,測試失敗,因?yàn)閐eposit函數(shù)還沒有定義:

.PHP Fatal error:  Call to undefined method BankAccount::deposit() in /home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php on line 11

接下來在源文件中增加deposit函數(shù):

public function deposit($ammount) {
}

再運(yùn)行phpunit,得如下結(jié)果:

1) BankAccountTest::testDeposit
Failed asserting that 0 matches expected 10.

這時(shí)因?yàn)槲覀冊赿eposit函數(shù)中并沒有操作賬戶余額,余額初始值為0,deposit函數(shù)執(zhí)行之后依然是0,不是用戶期望的行為。我們應(yīng)該往余額上增加用戶存入的數(shù)值。

為了操作余額,余額應(yīng)該是BankAccount的一個(gè)成員變量。這個(gè)變量不允許外界隨便更改,因此定義為私有變量。下面我們在生產(chǎn)代碼中加入私有變量$value,那么value函數(shù)應(yīng)該返回$value的值。

class BankAccount {
    private $value;

    public function value(){
        return $this->value;
    }

    public function deposit($ammount) {
        $this->value = 10;
    }
}

運(yùn)行 phpunit,測試通過。接下來,我們想,用戶還需要什么?對,取錢。當(dāng)取錢時(shí),賬戶余額要扣除這個(gè)值。如果給 deposit函數(shù)傳遞負(fù)數(shù),就相當(dāng)于取錢了。
于是我們在測試代碼的testDeposit函數(shù)中增加兩行代碼。

$account->deposit(-5);
$this->assertEquals(5, $account->value());

再運(yùn)行 phpunit,測試失敗了。

1) BankAccountTest::testDeposit
Failed asserting that 10 matches expected 5.

這時(shí)因?yàn)樵谏a(chǎn)代碼中我們簡單地把$value設(shè)成10的結(jié)果。改進(jìn)生產(chǎn)代碼。

public function deposit($ammount) {
    $this->value += $ammount;
}

再運(yùn)行phpunit,測試通過。

新的構(gòu)造函數(shù)

接下來,我想到,用戶可能需要一個(gè)不同的構(gòu)造函數(shù),當(dāng)創(chuàng)建BankAccount對象時(shí),可以傳入一個(gè)值作為賬戶余額。于是我們在testNewAccount增加這種實(shí)例化的測試。

public function testNewAccount(){
    $account1 = new BankAccount();
    $this->assertEquals(0, $account1->value());
    $account2 = new BankAccount(10);
    $this->assertEquals(10, $account2->value());
}

運(yùn)行phpunit,結(jié)果為:

1) BankAccountTest::testNewAccount
Failed asserting that null matches expected 10.

這時(shí)因?yàn)?b>BankAccount沒有帶參數(shù)的構(gòu)造函數(shù),因此new BankAccount(10)會(huì)返回一個(gè)空對象,空對象的value()函數(shù)自然返回的也是null。為了通過測試,我們在生產(chǎn)代碼中增加帶參數(shù)的構(gòu)造函數(shù)。

public function __construct($n){
    $this->value = $n;
}

再運(yùn)行測試:

1) BankAccountTest::testNewAccount
Missing argument 1 for BankAccount::__construct(), called in /home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php on line 5 and defined

/home/wuchen/projects/jolly-code-snippets/php/phpunit/src/BankAccount.php:5
/home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php:5

2) BankAccountTest::testDeposit
Missing argument 1 for BankAccount::__construct(), called in /home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php on line 12 and defined

/home/wuchen/projects/jolly-code-snippets/php/phpunit/src/BankAccount.php:5
/home/wuchen/projects/jolly-code-snippets/php/phpunit/test/BankAccountTest.php:12

兩個(gè)調(diào)用new BankAccount()的地方都報(bào)告了錯(cuò)誤,增加了帶參數(shù)的構(gòu)造函數(shù),不帶參數(shù)的構(gòu)造函數(shù)又不行了。從c++/java過渡來的同學(xué)馬上想到增加一個(gè)默認(rèn)的構(gòu)造函數(shù):

public function __construct() {
    $this->value = 0;
}

但這樣是不行的,因?yàn)閜hp不支持函數(shù)重載,所以不能有多個(gè)構(gòu)造函數(shù)。

怎么辦?對了,我們可以為參數(shù)增加默認(rèn)值。修改構(gòu)造函數(shù)為:

public function __construct($n = 0){
    $this->value = $n;
}

這樣調(diào)用 new BankAccount()時(shí),相當(dāng)于傳遞了0給構(gòu)造函數(shù),滿足了需求。
phpunit運(yùn)行以下,測試通過。

這時(shí),我們的生產(chǎn)代碼為:

value = $n;
    }

    public function value(){
        return $this->value;
    }

    public function deposit($ammount) {
        $this->value += $ammount;
    }
}
?>
總結(jié)

雖然我們的代碼并不多,但是每一步都寫得很有信心,這就是TDD的好處。即使你對php的語法不是很有把握(比如我),也可以對自己的代碼很有信心。

用TDD的方式寫程序的另一個(gè)好處,就是編碼之前不需要對單個(gè)模塊進(jìn)行仔細(xì)的設(shè)計(jì),可以在寫測試的時(shí)候進(jìn)行設(shè)計(jì)。這樣開發(fā)出來的模塊既可以滿足用戶需要,也不會(huì)冗余。

后面將會(huì)介紹 phpunit 的更多用法。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/20937.html

相關(guān)文章

  • [譯] Laravel 5 之美 - 單元測試

    摘要:事實(shí)上,這是討論測試的惟一一章。因此,在中沒有單一的測試方法。包含了這是的標(biāo)準(zhǔn)強(qiáng)調(diào)業(yè)務(wù)或特性測試是最流行的框架。然后我們在這個(gè)項(xiàng)目中使用進(jìn)行單元測試。在隨后的章節(jié)中,將不再進(jìn)行測試。 原文地址: Laravel 5.1 Beauty - Testing Note 本系列第四節(jié)內(nèi)容. 本章會(huì)創(chuàng)建一個(gè)以后可以用到的項(xiàng)目便于以后我們的課程使用, 同時(shí)也會(huì)查課各種測試選項(xiàng). 以后一段時(shí)間內(nèi)會(huì)開...

    fuyi501 評論0 收藏0
  • 8 個(gè) PHP 的軟件質(zhì)量控制工具推薦(包含 QA 工具和測試工具)

    摘要:然而,市面上的測試工具范圍太廣了,很難做出選擇。這篇熱門文章將會(huì)選出最受歡迎的測試工具并且它已經(jīng)被更新過以便反映出年的工具狀態(tài)。是一個(gè)根據(jù)規(guī)范創(chuàng)建的驗(yàn)收測試框架。 為了傳播有質(zhì)量的代碼, 我們必須在編碼時(shí)有測試的觀念 (如果不是在做 TDD)。 然而,市面上的PHP測試工具范圍太廣了,很難做出選擇。 這篇熱門文章將會(huì)選出最受歡迎的測試工具并且它已經(jīng)被更新過以便反映出2017年的 QA...

    wenyiweb 評論0 收藏0
  • PHPUnit 加速技巧分享

    摘要:接下來我們將會(huì)介紹一些可以快速實(shí)現(xiàn)的小技巧,讓你的代碼測試變得更快。該示例測試套件有意地模擬更廣泛的測試集合,并突出改進(jìn)的可行性。真實(shí)情況下,效率的提升可能有所差異。我認(rèn)為相比通過提升一點(diǎn)速度帶來的好處,保持生產(chǎn)環(huán)境一致更重要。 showImg(https://segmentfault.com/img/remote/1460000017962057?w=1440&h=736); 具備高...

    weizx 評論0 收藏0
  • 使 TDD 測試驅(qū)動(dòng)開發(fā)來構(gòu)建 Laravel REST API

    摘要:以及敏捷開發(fā)的先驅(qū)者之一的有句名言如果你沒有進(jìn)行測試驅(qū)動(dòng)開發(fā),那么你應(yīng)該正在做開發(fā)后堵漏的事今天我們將進(jìn)行一場基于的測試驅(qū)動(dòng)開發(fā)之旅。使用生成測試類。現(xiàn)在使用命令來生成模型并將其添加到我們的模型中。 showImg(https://segmentfault.com/img/remote/1460000018404936?w=1440&h=900); TDD 以及敏捷開發(fā)的先驅(qū)者之一的?...

    AlphaWallet 評論0 收藏0
  • 使 TDD 測試驅(qū)動(dòng)開發(fā)來構(gòu)建 Laravel REST API

    摘要:以及敏捷開發(fā)的先驅(qū)者之一的有句名言如果你沒有進(jìn)行測試驅(qū)動(dòng)開發(fā),那么你應(yīng)該正在做開發(fā)后堵漏的事今天我們將進(jìn)行一場基于的測試驅(qū)動(dòng)開發(fā)之旅。使用生成測試類?,F(xiàn)在使用命令來生成模型并將其添加到我們的模型中。 showImg(https://segmentfault.com/img/remote/1460000018404936?w=1440&h=900); TDD 以及敏捷開發(fā)的先驅(qū)者之一的?...

    dackel 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<