国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

測(cè)試驅(qū)動(dòng)開(kāi)發(fā):意圖導(dǎo)向編程下的接口開(kāi)發(fā)

2018-11-21 21:20 更新

有的時(shí)候?qū)幵父跺X讓你一周在床上待著,也不想讓你用這周剩下的時(shí)間去調(diào)試你在周一所寫的代碼。 --丹·所羅門

2.14.1 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)

做正確的事,比把事情做正確更為重要。

當(dāng)明確需要做何事后,再通過(guò)事先編寫單元測(cè)試來(lái)準(zhǔn)確表達(dá)我們將要實(shí)現(xiàn)的功能,是相當(dāng)具有指導(dǎo)意義的。你會(huì)發(fā)現(xiàn)接下來(lái)你的開(kāi)發(fā)歷程就是:?jiǎn)卧獪y(cè)試-設(shè)計(jì)-重構(gòu),而且這種正向循環(huán)是很有創(chuàng)造性的,并且進(jìn)行到一定程度后會(huì)慢慢體會(huì)到浮現(xiàn)式設(shè)計(jì)的樂(lè)趣。

關(guān)于測(cè)試驅(qū)動(dòng)開(kāi)發(fā)TDD,有很多資料已進(jìn)行了說(shuō)明,這里不再贅述。

如果還沒(méi)了解PHPUnit,可先閱讀:PHPUnit 手冊(cè)
如果還沒(méi)了解PHPUnit,可先閱讀:PHPUnit 手冊(cè)
如果還沒(méi)了解PHPUnit,可先閱讀:PHPUnit 手冊(cè)

2.14.2 意圖導(dǎo)向編程

apic

在編寫代碼前,先寫測(cè)試代碼,更容易提高 關(guān)注點(diǎn) 

因?yàn)?,在開(kāi)發(fā)過(guò)程中, 大多時(shí)候會(huì)被外界打斷(如需求溝通、線上問(wèn)題處理、臨時(shí)會(huì)議等),而通過(guò)單元測(cè)試則可以讓你“幾乎忘卻需要做什么”的情況下重新讓你回到之前的狀態(tài),特別在并行開(kāi)發(fā)多個(gè)不同項(xiàng)目的需求時(shí)尤其重要。

除此之外,遵循“紅-綠-重構(gòu)”這樣的流程,我們可以在更高的層面關(guān)注需要實(shí)現(xiàn)的功能需求,并自頂而下地進(jìn)行設(shè)計(jì)優(yōu)化,精益代碼。

2.14.3 編寫測(cè)試的原則、模式和指導(dǎo)

首先應(yīng)該意識(shí)到,測(cè)試代碼和生產(chǎn)代碼一樣重要。其次,測(cè)試代碼也應(yīng)該和生產(chǎn)代碼一樣被同步維護(hù)更新,這樣才能保持生氣,更大地發(fā)揮作用。只有當(dāng)不斷地對(duì)測(cè)試的代碼進(jìn)行修修補(bǔ)被,我們才能保持自動(dòng)化測(cè)試這張“安全網(wǎng)”常新。

2.14.4 F.I.R.S.T.原則

  • 快速 Fast
  • 獨(dú)立 Independent
  • 可重復(fù) Repeatable
  • 自足驗(yàn)證 Self-validating
  • 及時(shí) Timely

2.14.5 構(gòu)造-操作-檢驗(yàn)(BUILD-OPERATE-CHECK)模式

這個(gè)模式也可以理解成:“當(dāng)... 做...應(yīng)該...”。其中,構(gòu)造包括測(cè)試環(huán)境的搭建、測(cè)試數(shù)據(jù)前期的準(zhǔn)備;操作是指對(duì)被測(cè)試對(duì)象的調(diào)用, 以及被測(cè)試對(duì)象之間的通信和協(xié)助交互;最后檢驗(yàn)則是對(duì)業(yè)務(wù)規(guī)則的斷言、對(duì)功能需求的驗(yàn)證。

2.14.6 如何編寫高效測(cè)試代碼

  • 1、與產(chǎn)品代碼分開(kāi),與測(cè)試代碼對(duì)齊
  • 2、利用測(cè)試骨架(phpunit-skelgen或者自定義生成器)自動(dòng)生成測(cè)試代碼
  • 3、使用測(cè)試替身、測(cè)試樁構(gòu)建昂貴資源、制造異常情況
  • 4、每個(gè)測(cè)試一個(gè)概念

2.14.7 PhalApi開(kāi)發(fā)下的單元測(cè)試

我們推薦在各自的項(xiàng)目代碼中平行編寫單元測(cè)試,并逐漸完善、保持同步。以下是進(jìn)行單元測(cè)試的參考。

(1)Api接口層的單元測(cè)試

Api接口層,是我們后臺(tái)開(kāi)發(fā)的主要切入點(diǎn),也是直接對(duì)外提供服務(wù)的入口,屬于更高層次的概念并擁有指定的業(yè)務(wù)功能,更是后臺(tái)開(kāi)發(fā)的關(guān)注點(diǎn)。所以在對(duì)新接口進(jìn)行開(kāi)發(fā)前,編寫單元測(cè)試是非常有意義的。

為了可以自動(dòng)生成測(cè)試代碼,我們可以先簡(jiǎn)單定義好接口的函數(shù)簽名(以獲取用戶基本信息接口為例):

//$ vim ./Demo/Api/User.php 
<?php

class Api_User extends PhalApi_Api {

    public function getBaseInfo() {
    }

}

隨后,自動(dòng)生成測(cè)試代碼骨架:

$ mkdir ./Demo/Tests/Api -p
$ cd ./Demo/Tests/Api
$ php ./PhalApi/build_phpunit_test_tpl.php ./Demo/Api/User.php Api_User ./Public/init.php
$ php ./PhalApi/build_phpunit_test_tpl.php ./Demo/Api/User.php Api_User ./Public/init.php > ./Demo/Tests/Api/Api_User_Test.php

根據(jù)接口的需要,驗(yàn)證接口返回的格式,以及業(yè)務(wù)數(shù)據(jù)的正確性。

//$ vim ./Demo/Tests/Api/Api_User_Test.php
    /**
     * @group testGetBaseInfo
     */
    public function testGetBaseInfo()
    {
        //Step 1. 構(gòu)建請(qǐng)求URL
        $str = 'service=User.GetBaseInfo&user_id=1';

        //Step 2. 執(zhí)行請(qǐng)求  
        $rs = PhalApi_Helper_TestRunner::go($url);

        //Step 3. 驗(yàn)證
        $this->assertNotEmpty($rs);
        $this->assertArrayHasKey('code', $rs);
        $this->assertArrayHasKey('msg', $rs);
        $this->assertArrayHasKey('info', $rs);

        $this->assertEquals(0, $rs['code']);

        $this->assertEquals('dogstar', $rs['info']['name']);
        $this->assertEquals('oschina', $rs['info']['note']);
    }

上面的驗(yàn)證意思簡(jiǎn)單明了,結(jié)合 構(gòu)造-操作-檢驗(yàn)(BUILD-OPERATE-CHECK)模式 加以說(shuō)明一下。

構(gòu)造:構(gòu)建請(qǐng)求URL

        //Step 1. 構(gòu)建請(qǐng)求URL
        $str = 'service=User.GetBaseInfo&user_id=1';

此參數(shù)即對(duì)應(yīng)接口請(qǐng)求的URL參數(shù),我們將此參數(shù)追加在接口入口并在瀏覽器打開(kāi)可以得到同樣的接口執(zhí)行效果。但這樣的好處更在于通過(guò)單元測(cè)試幫我們記住了各種接口測(cè)試的業(yè)務(wù)場(chǎng)景。而不再是像以前那樣打開(kāi)N個(gè)瀏覽器窗口人工進(jìn)行調(diào)試,也不用像以前那樣苦苦尋找瀏覽器記錄。

如果接口需要POST數(shù)據(jù),或者其他更多參數(shù),可以使用$params來(lái)傳遞更多參數(shù),一如:

        //Step 1. 構(gòu)建請(qǐng)求URL
        $str = 'service=User.GetBaseInfo&user_id=1';
        $params = array(); //更多參數(shù)

        //Step 2. 執(zhí)行請(qǐng)求  
        $rs = PhalApi_Helper_TestRunner::go($url, $params); //通過(guò)第二個(gè)參數(shù),傳送更多參數(shù)

操作:執(zhí)行請(qǐng)求

這里的操作,顯然就是對(duì)應(yīng)我們接口的調(diào)用。簡(jiǎn)單地如:

        //Step 2. 執(zhí)行請(qǐng)求  
        $rs = PhalApi_Helper_TestRunner::go($url);

這樣,便可以在服務(wù)端模擬進(jìn)行一次接口的請(qǐng)求調(diào)度,注意這里是在服務(wù)端進(jìn)行的接口請(qǐng)求,而不是客戶端。
此外,如果需要傳遞更多參數(shù),可以參考前面的示例。這里簡(jiǎn)單補(bǔ)充一下PhalApi_Helper_TestRunner測(cè)試輔助類的接口簽名說(shuō)明:

<?php
class PhalApi_Helper_TestRunner {

    /**
     * @param string $url 請(qǐng)求的鏈接
     * @param array $param 額外POST的數(shù)據(jù)
     * @return array 接口的返回結(jié)果
     */
    public static function go($url, $params = array()) {

        ... ...

檢驗(yàn):驗(yàn)證

在對(duì)接口返回的結(jié)果中,我們可以這樣依次進(jìn)行正確性的驗(yàn)證:

  • 1、先驗(yàn)證接口返回的格式是否正確,有無(wú)字段遺漏;
  • 2、返回的業(yè)務(wù)數(shù)據(jù)是否正確;
        //Step 3. 驗(yàn)證
        $this->assertNotEmpty($rs);
        $this->assertArrayHasKey('code', $rs);
        $this->assertArrayHasKey('msg', $rs);
        $this->assertArrayHasKey('info', $rs);

        $this->assertEquals(0, $rs['code']);

        $this->assertEquals('dogstar', $rs['info']['name']);
        $this->assertEquals('oschina', $rs['info']['note']);

由于測(cè)試環(huán)境的數(shù)據(jù)變動(dòng)頻繁,所以我們可以針對(duì)個(gè)別的接口進(jìn)行更精確的驗(yàn)證,而對(duì)類似列表獲取這樣的大批量的數(shù)據(jù),則校驗(yàn)其結(jié)構(gòu)格式。
除此之外,還有一種情況也是需要納入檢驗(yàn),即除了上面的正常請(qǐng)求情況下的 異常請(qǐng)求 。

接下來(lái)的即是之前文檔里面所說(shuō)的單元測(cè)試執(zhí)行和接口開(kāi)發(fā),此處略。

(2)Domain層和Model層的單元測(cè)試

下面繼續(xù)簡(jiǎn)單補(bǔ)充一下之前沒(méi)談及到的Domain層和Model層的單元測(cè)試。

顯然,這兩層的開(kāi)發(fā),已經(jīng)在前面的接口測(cè)試驅(qū)動(dòng)開(kāi)發(fā)的指導(dǎo)下很好地完成了。現(xiàn)在可以快速追加對(duì)這兩層的單元測(cè)試。得益于我們的生成測(cè)試骨架的腳本,操作如下:

$ php ./PhalApi/build_phpunit_test_tpl.php ./Demo/Domain/User.php Domain_User > ./Demo/Tests/Domain/Domain_User_Test.php
$ php ./PhalApi/build_phpunit_test_tpl.php ./Demo/Model/User.php Model_User > ./Demo/Tests/Model/Model_User_Test.php

接著,修改一下測(cè)試環(huán)境 test_env.php的引用路徑:

//$ vim ./Demo/Tests/Domain/Domain_User_Test.php 
//$ vim ./Demo/Tests/Model/Model_User_Test.php

require_once dirname(__FILE__) . '/../test_env.php';

各自完善一下單元測(cè)試:

//$ vim ./Demo/Tests/Domain/Domain_User_Test.php

    /**
     * @group testGetBaseInfo
     */
    public function testGetBaseInfo()
    {
        $userId = '1';

        $rs = $this->domainUser->getBaseInfo($userId);

        $this->assertArrayHasKey('id', $rs);
        $this->assertArrayHasKey('name', $rs);
        $this->assertArrayHasKey('note', $rs);

        $this->assertEquals('dogstar', $rs['name']);
    }

執(zhí)行一下:

$ phpunit ./Demo/Tests/Domain/Domain_User_Test.php 
PHPUnit 4.3.4 by Sebastian Bergmann.

.

Time: 49 ms, Memory: 6.25Mb

OK (1 test, 4 assertions)

(3)Model層的單元測(cè)試

Model層的單元測(cè)試類似,不再贅述。

2.14.7 更進(jìn)一步的單元測(cè)試套件

到目前為止,我們有了如下的產(chǎn)品代碼:

dogstar@ubuntu:Demo$ tree
.
├── Api
│   └── User.php
├── Domain
│   └── User.php
├── Model
│   └── User.php

并擁有了與之平行對(duì)應(yīng)的單元測(cè)試:

dogstar@ubuntu:Tests$ tree
.
├── Api
│   └── Api_User_Test.php
├── Domain
│   └── Domain_User_Test.php
├── Model
│   └── Model_User_Test.php
└── test_env.php

這樣是一個(gè)很好的開(kāi)始,但若我們每次測(cè)試都分別調(diào)用三次這些不同層次的單元測(cè)試,顯然有點(diǎn)不科學(xué)。所以,利用PHPUnit的配置文件,我們可以輕松管理我們的測(cè)試套件,如:

dogstar@ubuntu:Tests$ vim ./phpunit_user_getbaseinfo.xml 

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
    ...

    <testsuites>
        <testsuite name="Test Suite">
            <file>./Api/Api_User_Test.php</file>
            <file>./Domain/Domain_User_Test.php</file>
            <file>./Model/Model_User_Test.php</file>
        </testsuite>
    </testsuites>
</phpunit>

啊哈!終于,當(dāng)需要調(diào)用這些分布在不同目錄位置的單元測(cè)試時(shí),只需要這么簡(jiǎn)單的一行命令:

dogstar@ubuntu:Tests$ phpunit -c ./phpunit_user_getbaseinfo.xml 
PHPUnit 4.3.4 by Sebastian Bergmann.

.....

Time: 54 ms, Memory: 7.25Mb

OK (5 tests, 28 assertions)

2.14.8 這樣的好處?

上面的過(guò)程,細(xì)節(jié)較多,而且需要實(shí)際操作的部分也比較多。對(duì)于之前沒(méi)有接觸過(guò)單元測(cè)試這塊的同學(xué),可能會(huì)有點(diǎn)迷茫,對(duì)于不愿意接受單元測(cè)試的同學(xué)來(lái)說(shuō)更加枯燥。

然而,然而。 當(dāng)我們把越痛苦的事情越早完成后,我們后面就順暢多了。正如在某一次培訓(xùn)中的某一位敏捷開(kāi)發(fā)的專家所說(shuō)的: 要逐步對(duì)小問(wèn)題做優(yōu)化,而不是要等到大問(wèn)題到來(lái)時(shí)再做變革 。

那這樣的好處在于哪里呢?

這里不就理論回答,而是以我個(gè)人的經(jīng)歷來(lái)簡(jiǎn)單說(shuō)明。

首先,正如上面所說(shuō)的,單元測(cè)試幫你很好地記住并整理了各種接口測(cè)試的場(chǎng)景,而不用再像以前那樣打開(kāi)N個(gè)瀏覽器窗口逐個(gè)人工校對(duì)。
其次,在單元測(cè)試的論證下我們可以更有信心地跟測(cè)試說(shuō)、跟產(chǎn)品說(shuō)、跟發(fā)布說(shuō)我們的代碼沒(méi)問(wèn)題,因?yàn)槲覀兺ㄟ^(guò)嚴(yán)格的單元測(cè)試,而不是人為主觀上的想當(dāng)然應(yīng)該不會(huì)有問(wèn)題吧。
最后,也是最重要的,在后期的接口升級(jí)、改動(dòng)和維護(hù)中,單元測(cè)試再一次為我們提供了保護(hù),猶如一張安全網(wǎng),涵蓋我們改動(dòng)的每一處代碼。與此同時(shí),對(duì)于重構(gòu)也亦然。

但單元測(cè)試所帶給你的,不僅僅是上面所說(shuō)的簡(jiǎn)單這幾點(diǎn)。更多地完全不一樣的開(kāi)發(fā)歷程,而其中滋味和令人興奮的體現(xiàn),只有當(dāng)你親自去嘗試才會(huì)明白其中滋味。So, try it by yourself.

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)