自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ZOMBIES:我的軟件開發(fā)和測(cè)試簡(jiǎn)便指南(一)

開發(fā)
編程過(guò)程有時(shí)候就像一場(chǎng)與喪尸群之間的戰(zhàn)斗。在這個(gè)系列文章中,我將帶你了解怎樣將 ZOMBIES 方法應(yīng)用到實(shí)際工作中。

很久以前,在我還是一個(gè)萌新程序員的時(shí)候,我們?cè)?jīng)被分配一大批工作。我們每個(gè)人都被分配了一個(gè)編程任務(wù),然后回到自己的小隔間里噼里啪啦地敲鍵盤。我記得團(tuán)隊(duì)里的成員在自己的小隔間里一呆就是幾個(gè)小時(shí),為打造無(wú)缺陷的程序而奮斗。當(dāng)時(shí)流行的思想是:能一次性做得越多,能力越強(qiáng)。

對(duì)于我來(lái)說(shuō),能夠長(zhǎng)時(shí)間編寫或者修改代碼而不用中途停下來(lái)檢驗(yàn)這些代碼是否有效,就像榮譽(yù)勛章一樣。那個(gè)時(shí)候我們都認(rèn)為停下來(lái)檢驗(yàn)代碼是否工作是能力不足的表現(xiàn),菜鳥才這么干。一個(gè)“真正的開發(fā)者”應(yīng)該能一口氣構(gòu)建起整個(gè)程序,中途不用停下來(lái)檢查任何東西!

然而事與愿違,當(dāng)我停止在開發(fā)過(guò)程中測(cè)試自己的代碼之后,來(lái)自現(xiàn)實(shí)的檢驗(yàn)狠狠地打了我的臉。我的代碼要么無(wú)法通過(guò)編譯,要么構(gòu)建失敗,要么無(wú)法運(yùn)行,或者不能按預(yù)期處理數(shù)據(jù)。我不得不在絕望中掙扎著解決這些煩人的問(wèn)題。

避開喪尸群

如果你覺(jué)得舊的工作方式聽起來(lái)很混亂,那是因?yàn)樗_實(shí)是這樣的。我們一次性處理所有的任務(wù),在問(wèn)題堆里左砍右殺,結(jié)果只是引出更多的問(wèn)題。著就像是跟一大群?jiǎn)适g的戰(zhàn)斗。

如今我們已經(jīng)學(xué)會(huì)了避免一次性做太多的事情。在最初聽到一些專家推崇避免大批量地開發(fā)的好處時(shí),我覺(jué)得這很反直覺(jué),但我已經(jīng)從過(guò)去的犯錯(cuò)中吸取了教訓(xùn)。我使用被 James Grenning 稱為 ZOMBIES 的方法來(lái)指導(dǎo)我的軟件開發(fā)工作。

ZOMBIES 方法來(lái)救援!

ZOMBIES 表示以下首字母縮寫:

  • Z – 最簡(jiǎn)場(chǎng)景(Zero)
  • O – 單元素場(chǎng)景(One)
  • M – 多元素場(chǎng)景(Many or more complex)
  • B – 邊界行為(Boundary behaviors)
  • I – 接口定義(Interface definition)
  • E – 處理特殊行為(Exercise exceptional behavior)
  • S – 簡(jiǎn)單場(chǎng)景用簡(jiǎn)單的解決方案(Simple scenarios, simple solutions)

我將在本系列文章中對(duì)它們進(jìn)行分析講解。

最簡(jiǎn)場(chǎng)景

最簡(jiǎn)場(chǎng)景指可能出現(xiàn)的最簡(jiǎn)單的情況。

人們傾向于最開始的時(shí)候使用硬編碼值,因?yàn)檫@是最簡(jiǎn)單的方式。通過(guò)在編碼活動(dòng)中使用硬編碼值,可以快速構(gòu)建出一個(gè)能即時(shí)反饋的解決方案。不需要幾分鐘,更不用幾個(gè)小時(shí),使用硬編碼值讓你能夠馬上與正在構(gòu)建的系統(tǒng)進(jìn)行交互。如果你喜歡這個(gè)交互,就朝這個(gè)方向繼續(xù)做下去。如果你發(fā)現(xiàn)不喜歡這種交互,你可以很容易拋棄它,根本沒(méi)有什么可損失。

本系列文章將以構(gòu)建一個(gè)簡(jiǎn)易的購(gòu)物系統(tǒng)的后端 API 為例進(jìn)行介紹。該服務(wù)提供的 API 允許用戶創(chuàng)建購(gòu)物筐、向購(gòu)物筐添加商品、從購(gòu)物筐移除商品、計(jì)算商品總價(jià)。

首先,創(chuàng)建項(xiàng)目的基本結(jié)構(gòu)(將購(gòu)物程序的代碼和測(cè)試代碼分別放到 app 和 tests 目錄下)。我們的例子中使用開源的 xUnit 測(cè)試框架。

現(xiàn)在擼起你的袖子,在實(shí)踐中了解最簡(jiǎn)場(chǎng)景吧!

[Fact]
public void NewlyCreatedBasketHas0Items() {    
    var expectedNoOfItems = 0;
    var actualNoOfItems = 1;
    Assert.Equal(expectedNoOfItems, actualNoOfItems);
}

這是一個(gè)偽測(cè)試,它測(cè)試的是硬編碼值。新創(chuàng)建的購(gòu)物筐是空的,所以購(gòu)物筐中預(yù)期的商品數(shù)是 0。通過(guò)比較期望值和實(shí)際值是否相等,這個(gè)預(yù)期被表示成一個(gè)測(cè)試(或者稱為斷言)。

運(yùn)行該測(cè)試,輸出結(jié)果如下:

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.57] tests.UnitTest1.NewlyCreatedBasketHas0Items [FAIL]
  X tests.UnitTest1.NewlyCreatedBasketHas0Items [4ms]
  Error Message:
   Assert.Equal() Failure
Expected: 0
Actual: 1
[...]

這個(gè)測(cè)試顯然無(wú)法通過(guò):期望商品數(shù)是 0,但是實(shí)際值被硬編碼為了 1。

當(dāng)然,你可以馬上把硬編碼的值從 1 改成 0,這樣測(cè)試就能通過(guò)了:

[Fact]
public void NewlyCreatedBasketHas0Items() {
    var expectedNoOfItems = 0;
    var actualNoOfItems = 0;
    Assert.Equal(expectedNoOfItems, actualNoOfItems);
}

與預(yù)想的一樣,運(yùn)行測(cè)試,測(cè)試通過(guò):

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 1.0950 Seconds

你也許會(huì)認(rèn)為執(zhí)行一個(gè)被強(qiáng)迫失敗的測(cè)試完全沒(méi)有意義,但是不管一個(gè)測(cè)試多么簡(jiǎn)單,確保它的可失敗性是絕對(duì)有必要的。只有這樣才能夠保證如果在后續(xù)工作中不小心破壞了程序的處理邏輯時(shí)該測(cè)試能夠給你相應(yīng)的警告。

現(xiàn)在停止偽造數(shù)據(jù),將硬編碼的值替換成從 API 中獲取的值。我們已經(jīng)構(gòu)造了一個(gè)能夠可靠地失敗的測(cè)試,它期望一個(gè)空的購(gòu)物筐中有 0 個(gè)商品,現(xiàn)在是時(shí)候編寫一些應(yīng)用程序代碼了。

就跟常見的軟件建模活動(dòng)一樣,我們先從構(gòu)造一個(gè)簡(jiǎn)單的接口開始。在 app 目錄下新建文件 IShoppingAPI.cs(習(xí)慣上接口名一般以大寫 I 開頭)。在該接口中聲明一個(gè)名為 NoOfItems() 的方法,它以 int 類型返回商品的數(shù)量。下面是接口的代碼:

using System;
namespace app {    
    public interface IShoppingAPI {
        int NoOfItems();
    }
}

當(dāng)然這個(gè)接口什么事也做不了,在你需要實(shí)現(xiàn)它。在 app 目錄下創(chuàng)建另一個(gè)文件 ShoppingAPI。在其中將 ShoppingAPI 聲明為一個(gè)實(shí)現(xiàn)了 IShoppingAPI 的公有類。在類中定義方法 NoOfItems 返回整數(shù) 1:

using System;
namespace app {
    public class ShoppingAPI : IShoppingAPI {
        public int NoOfItems() {
            return 1;
        }
    }
}

從上面代碼中你發(fā)現(xiàn)自己又在通過(guò)返回硬編碼值 1 的方式來(lái)偽造代碼邏輯。現(xiàn)階段這是一件好事,因?yàn)槟阈枰3忠磺谐?jí)無(wú)敵簡(jiǎn)單。現(xiàn)在還不是仔細(xì)構(gòu)想如何實(shí)現(xiàn)購(gòu)物筐的處理邏輯時(shí)候。這些工作后續(xù)再做!到目前為止,你只是通過(guò)構(gòu)建最簡(jiǎn)場(chǎng)景來(lái)檢驗(yàn)自己是否滿意現(xiàn)在的設(shè)計(jì)。

為了確定這一點(diǎn),將硬編碼值換成這個(gè) API 在運(yùn)行中收到請(qǐng)求時(shí)應(yīng)該返回的值。你需要通過(guò) using app; 聲明來(lái)告訴測(cè)試你使用的購(gòu)物邏輯代碼在哪里。

接下來(lái),你需要 實(shí)例化instantiate IShoppingAPI 接口:

IShoppingAPI shoppingAPI = new ShoppingAPI();

這個(gè)實(shí)例用來(lái)發(fā)送請(qǐng)求并接收返回的值。

現(xiàn)在,代碼變成了這樣:

using System;
using Xunit;
using app;
namespace tests {
    public class ShoppingAPITests {
        IShoppingAPI shoppingAPI = [new][3] ShoppingAPI();
 
        [Fact]        
        public void NewlyCreatedBasketHas0Items() {
            var expectedNoOfItems = 0;
            var actualNoOfItems = shoppingAPI.NoOfItems();
            Assert.Equal(expectedNoOfItems, actualNoOfItems);
        }
    }
}

顯然執(zhí)行這個(gè)測(cè)試的結(jié)果是失敗,因?yàn)槟阌簿幋a了一個(gè)錯(cuò)誤的返回值(期望值是 0,但是返回的是 1)。

同樣的,你也可以通過(guò)將硬編碼的值從 1 改成 0 來(lái)讓測(cè)試通過(guò),但是現(xiàn)在做這個(gè)是在浪費(fèi)時(shí)間。現(xiàn)在設(shè)計(jì)的接口已經(jīng)跟測(cè)試關(guān)聯(lián)上了,你剩下的職責(zé)就是編寫代碼實(shí)現(xiàn)預(yù)期的行為邏輯。

在編寫應(yīng)用程序代碼時(shí),你得決定用來(lái)表示購(gòu)物筐得數(shù)據(jù)結(jié)構(gòu)。為了保持設(shè)計(jì)的簡(jiǎn)單,盡量選擇 C# 中表示集合的最簡(jiǎn)單類型。第一個(gè)想到的就是 ArrayList。它非常適合目前的使用場(chǎng)景——可以保存不定個(gè)數(shù)的元素,并且易于遍歷訪問(wèn)。

因?yàn)?nbsp;ArrayList 是 System.Collections 包的一部分,在你的代碼中需要聲明:

using System.Collections;

然后 basket 的聲明就變成這樣了:

ArrayList basket = new ArrayList();

最后將 NoOfItems() 中的因編碼值換成實(shí)際的代碼:

public int NoOfItems() {
    return basket.Count;
}

這次測(cè)試能夠通過(guò)了,因?yàn)樽畛踬?gòu)物筐是空的,basket.Count 返回 0。

這也是你的第一個(gè)最簡(jiǎn)場(chǎng)景測(cè)試要做的事情。

更多案例

目前的課后作業(yè)是處理一個(gè)喪尸,也就是第 0 個(gè)喪尸。在下一篇文章中,我將帶你了解單元素場(chǎng)景和多元素場(chǎng)景。不要錯(cuò)過(guò)哦!

責(zé)任編輯:龐桂玉 來(lái)源: Linux中國(guó)
相關(guān)推薦

2023-05-16 17:34:49

ZOMBIES軟件開發(fā)

2023-05-30 18:19:23

ZOMBIES開發(fā)軟件

2023-05-30 18:26:49

ZOMBIES軟件開發(fā)

2023-02-09 16:48:12

軟件開發(fā)測(cè)試結(jié)對(duì)測(cè)試

2018-01-09 18:33:24

軟件開發(fā)測(cè)試軟件測(cè)試

2021-12-06 09:00:00

開發(fā)WebDjango

2023-06-09 19:01:03

軟件開發(fā)

2021-07-20 09:00:00

開發(fā)軟件債務(wù)

2023-06-08 16:47:09

軟件開發(fā)工具

2022-05-20 10:41:22

SDLC開發(fā)模型

2015-09-14 15:13:52

2016-09-28 19:16:36

軟件開發(fā)安全CISSPSDLC

2009-02-10 17:11:53

SaaSSaaS開發(fā)PaaS

2015-03-02 09:35:07

軟件開發(fā)

2010-12-13 10:34:09

Visual Stud

2020-10-16 10:21:23

大數(shù)據(jù)開發(fā)軟件開發(fā)技術(shù)

2009-06-12 11:35:28

模式框架軟件設(shè)計(jì)

2023-02-27 15:18:43

軟件開發(fā)優(yōu)化軟件

2017-03-17 08:15:17

敏捷軟件開發(fā)軟件開發(fā)

2012-06-18 09:34:14

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)