亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

單元測試和事先測試開發

2019-11-17 04:40:00
字體:
來源:轉載
供稿:網友
摘要:Eric Gunnerson 介紹了事先測試開發的思想,并提供了一個實用實例來演示如何在您自己的應用程序中應用它。
  本專欄末尾有我的簡介,假如您讀過的話,就會知道我在擔任程序經理之前曾出任 C# 編譯器的測試組長,而在此之前是 C++ 編譯器的測試組長。這些工作經歷使我對分析和盡量避免軟件錯誤非凡感愛好。   要減少軟件中的錯誤數目,方法之一就是擁有一個專業的測試組,其工作就是盡一切可能使軟件崩潰。不幸的是,假如擁有測試組,那么即使是經驗豐富的開發人員,也會傾向于花費較少的時間來保證代碼的可靠性。   軟件界有一句俗語:“開發人員不應該測試他們自己的代碼”。這是因為開發人員對自己的代碼了如指掌,他們很清楚如何采用適當的方法對代碼進行測試。盡管這句俗語很有道理,但卻忽略了非常重要的一點 - 假如開發人員不對自己的代碼進行測試,又如何知道代碼能否按照預期的方式運行?  簡單說來,他們根本無從得知。開發人員編寫那種運行不正?;蛑辉谀承┣闆r下運行正常的代碼是一個嚴重的問題。他們通常只測試代碼能否在很少的情況下正常運行,而不是驗證代碼能夠在所有情況下均正常運行?! “l現軟件錯誤

  發現軟件錯誤的情況有很多:   1、由首次編寫代碼的開發人員發現。
  2、由嘗試運行代碼的開發人員發現。
  3、由組中的其他開發人員或測試人員發現。
  4、作為產品大規模測試的一部分。
  5、由最終用戶發現。

  假如在第一種情況下發現軟件錯誤,則修復錯誤比較輕易,成本也很低。情況越靠后,修復軟件錯誤的成本就越高;修復一個由最終用戶發現的軟件錯誤可能要耗費 100 或 1000 倍的成本。更不用說用戶通常因為軟件錯誤導致工作無法繼續,而一直等到下一個版本才能解決問題。  假如開發人員能夠在編寫代碼期間發現所有的軟件錯誤,那就再好不過了。為此,您必須編寫能在編寫代碼時運行的測試。有一種很不錯的方法,它恰好可以做到這一點。   事先測試開發

  所謂的事先測試開發是指在編寫代碼前編寫測試。假如所有測試均正常運行,便可以斷定代碼運行正常;添加新功能時,這些測試會繼續驗證您是否破壞了代碼的任何部分。  此概念于 20 世紀 90 年代初誕生于 Smalltalk 世界,Kent Beck 在當時編寫了 SmalltalkUnit。在過去的幾年中,大部分環境都具備了單元測試工具,其中有一個很出色的適用于 .NET Framework 領域的工具,即 nUnit(英文)?! ∈纠?br />
  下面我將編寫一個 IntegerList 類來介紹事先測試開發的工作原理。IntegerList 是 ArrayList 類的變體,用于在本地存儲整數,因此不存在裝箱和取消裝箱的開銷。  第一步是創建一個控制臺項目,并向其中添加一個 IntegerList.cs 源文件。要連接 nUnit 框架,需要添加對 nUnit 框架的引用。在我的系統中,它們位于 d:/PRogram files/nUnit v2.0/bin。   第二步是花些時間考慮如何對該類進行測試。這與確定類應該具備哪些功能的過程類似,但重點放在功能的特定用途(將值 1 添加到列表并檢查是否成功),而不是功能本身(將一個項目添加到列表)。要生成此類,我們首先要提供一個要使用的測試列表:   1、測試該類可以構造
  2、將兩個整數添加到列表,并確保數目和項目都正確。
  3、執行同一操作,但針對更多的項目。
  4、將此列表轉換為一個字符串。
  5、使用 foreach 枚舉此列表。

  此示例從某種程度上代表了我開始時的想法,即希望這個類執行的操作。多數類一次只會創建一小部分,測試應隨著類的增長而添加。   現在我可以開始了。我創建一個名為 IntegerListTest.cs 的新 C# 類文件,用于存放所有測試。下面是包含第一個測試的文件:using System;
using System.Collections;
using NUnit.Framework;namespace IntegerList
{
/// <summary>
/// IntegerClassTest 的摘要說明。
/// </summary>
[TestFixture]
public class IntegerClassTest
{
[Test]
public void ListCreation()
{
IntegerList list = new IntegerList();
Assertion.AssertNotNull(list);
}
}
}  [TestFixture] 屬性將此類標記為測試類,[Test] 屬性將 ListCreation() 方法標記為測試方法。在此方法中,我創建了一個列表,然后使用 Assertion 類測試對象 gets 已經創建。
  我啟動 nUnit GUI 測試程序,打開可執行文件,并執行這些測試。將獲得如下顯示。 單元測試和事先測試開發

圖 1:顯示測試結果的 nUnit GUI  這表明所有測試都已通過。現在我想添加一些真實功能。第一個操作就是向列表中添加一個整數。此測試如下所示:[Test]
public void TestSimpleAdd()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
Assertion.AssertEquals(2, list.Count);
Assertion.AssertEquals(5, list[0]);
Assertion.AssertEquals(10, list[1]);
}  在此測試中,我選擇同時測試兩個操作:   1、列表正確維護 Count 屬性。
  2、列表可以包含兩個項。

  某些測試驅動開發的倡議者提倡測試應盡可能只測試數目,但是假如只測試數目而不測試項目,這對于我而言有些不可思議,因此我所選擇的是兩者一起測試。   編譯這段代碼時,由于 IntegerList 類中沒有方法,因此編譯失敗,為此我加上以下代碼進行編譯:public int Count
{
get
{
return -1;
}
}public void Add(int value)
{
}public int this[int index]
{
get
{
return -1;
}
}  然后我返回并運行測試,這時它們顯示為紅色,表示測試失敗。這很好,因為它意味著測試實際上已測試出程序錯誤?,F在我可以執行此實現。我可以做些簡單的工作,盡管這樣做效率不是很高:public int Count
{
get
{
return elements.Length;
}
}public void Add(int value)
{
int newIndex;
if (elements != null)
{
int[] newElements = new int[elements.Length + 1];
for (int index = 0; index < elements.Length;
index++)
{
newElements[index] = elements[index];
}
newIndex = elements.Length;
elements = newElements;
}
else
{
elements = new int[1];
newIndex = 0;
}
elements[newIndex] = value;
}public int this[int index]
{
get
{
return elements[index];
}
}  我現在已經完成類的一小部分,并已經編寫了可確保其正常工作的測試,但我僅僅測試了項目中很少的一部分。接下來,我要編寫一個用于檢查 1000 個項的測試:[Test]
public void TestOneThousandItems()
{
list = new IntegerList();for (int i = 0; i < 1000; i++)
{
list.Add(i);
}Assertion.AssertEquals(1000, list.Count);
for (int i = 0; i < 1000; i++)
{
Assertion.AssertEquals(i, list[i]);
}
}  此測試運行正常,因此無須進行任何更改。   添加 ToString() 方法

  接下來,我將添加測試代碼,以測試 ToString() 能否正常運行:[Test]
public void TestToString()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
string t = list.ToString();
Assertion.AssertEquals("5, 10", t.ToString());
}失敗了,沒關系。以下代碼可以使其通過:public override string ToString()
{
string[] items = new string[elements.Length];
for (int index = 0; index < elements.Length; index++)
{
items[index] = elements[index].ToString();
}
return String.Join(", ", items);
}進入討論組討論。
啟用 Foreach

  許多用戶希望能夠使用 foreach 遍歷我的列表。為此,我需要在類中實現 Ienumerable,并定義一個單獨的用于實現 Ienumerable 的類。第一步,測試:
[Test]
public void TestForeach()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
list.Add(15);
list.Add(20);ArrayList items = new ArrayList();foreach (int value in list)
{
items.Add(value);
}Assertion.AssertEquals("Count", 4, items.Count);
Assertion.AssertEquals("index 0", 5, items[0]);
Assertion.AssertEquals("index 1", 10, items[1]);
Assertion.AssertEquals("index 2", 15, items[2]);
Assertion.AssertEquals("index 3", 20, items[3]);
}我還通過 IntegerList 實現 IEnumerable:public IEnumerator GetEnumerator()
{
return null;
}  運行測試時,此代碼生成異常。為了正確地實現此功能,我將使用一個嵌套類作為枚舉器。 class IntegerListEnumerator: IEnumerator
{
IntegerList list;
int index = -1;public IntegerListEnumerator(IntegerList list)
{
this.list = list;
}
public bool MoveNext()
{
index++;
if (index == list.Count)
return(false);
else
return(true);
}
public object Current
{
get
{
return(list[index]);
}
}
public void Reset()
{
index = -1;
}
}  此類將一個指針傳遞給 IntegerList 對象,然后只返回此對象中的元素?! ∵@樣,便可以對列表執行 foreach 操作,但遺憾的是 Current 屬性屬于對象類型,這意味著每個值將被裝箱才能將其返回。此問題可采用一種基于模式的方法加以解決,此方法酷似當前方法,但它通過 GetEnumerator() 返回一個真正的類(而非 IEnumerator),且此類中的 Current 屬性為 int 類型。  然而執行此操作后,我要確保在不支持該模式的語言中仍然可以使用這種基于接口的方法。我將復制編寫的上一個測試并修改 foreach 以轉換為接口:  foreach (int value in (IEnumerable) list)  只需少許改動,列表即可在兩種情況下正常運行。請查看代碼樣例以獲取更多細節和更多測試。   幾點說明

  為本月的專欄文章編寫代碼和文字大約花了我一個小時的時間。事先編寫測試的優點就是您可以對在類中添加哪些內容以使測試通過有一個清楚的熟悉,從而簡化代碼的編寫?! 〖偃缫M行小型、遞增的測試,則使用此方法最合適。我鼓勵您在小型項目中使用此方法。事先測試開發是所謂的“靈敏方法”的一部分。進入討論組討論。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩xxx| 欧美精品aaa| 美女撒尿一区二区三区| 久久久久久成人精品| 日韩视频在线免费观看| 日韩电影视频免费| 日韩小视频在线观看| 狠狠做深爱婷婷久久综合一区| 亚洲免费成人av电影| 亚洲视频电影图片偷拍一区| 国产精品偷伦免费视频观看的| 日韩精品在线观看网站| 精品无人区乱码1区2区3区在线| 欧美成人免费在线观看| 欧美电影《睫毛膏》| 欧美成人三级视频网站| 欧美激情免费看| 97超级碰碰碰| 日本一区二三区好的精华液| 91久久国产精品91久久性色| 久久久久久国产精品久久| 色综合伊人色综合网站| 国产香蕉97碰碰久久人人| 色哟哟亚洲精品一区二区| 中文字幕亚洲欧美日韩在线不卡| 午夜伦理精品一区| 亚洲国产中文字幕久久网| 91日韩在线播放| 亚洲高清久久网| 国产精品扒开腿做爽爽爽的视频| 上原亚衣av一区二区三区| 国外色69视频在线观看| 中国日韩欧美久久久久久久久| 日韩av网址在线| 日韩精品极品视频免费观看| 亚洲精品国产精品久久清纯直播| 精品小视频在线| 97热在线精品视频在线观看| 国产欧美一区二区三区在线看| 在线精品视频视频中文字幕| 国产不卡av在线免费观看| 国产成人小视频在线观看| 国产精品爽黄69| 国产精品一区久久| 国产欧美日韩精品专区| 久久久久久网站| 欧美激情xxxx| 麻豆一区二区在线观看| 97在线视频免费观看| 超在线视频97| 久久久久久亚洲精品中文字幕| 有码中文亚洲精品| 欧美国产日韩精品| 日韩视频免费大全中文字幕| 国产日韩在线精品av| 亚洲成人性视频| 中文字幕在线看视频国产欧美在线看完整| 欧美国产精品va在线观看| 成人在线播放av| 91精品国产91久久久久久不卡| 亚洲人成绝费网站色www| 中文字幕综合一区| 日韩成人小视频| 国产91色在线播放| 欧美日韩一区二区免费视频| 庆余年2免费日韩剧观看大牛| 日韩精品久久久久久久玫瑰园| 欧美激情免费看| 97在线视频免费| 国产精品自拍偷拍| 亚洲精品丝袜日韩| 亚洲一区二区三区成人在线视频精品| 国产精品丝袜一区二区三区| 欧美成人午夜影院| 国产精品福利在线观看| 亚洲人成在线观| www.国产一区| 日韩电影视频免费| 中文字幕欧美视频在线| 欧美综合一区第一页| 中文字幕在线观看亚洲| 日韩专区在线观看| 97国产精品免费视频| 欧美日韩国产丝袜美女| 91产国在线观看动作片喷水| 日本精品一区二区三区在线播放视频| 奇米一区二区三区四区久久| 欧美尤物巨大精品爽| 久久久久久久久国产| 九九热r在线视频精品| 亚洲精品二三区| 亚洲黄色www| 日韩成人在线视频| 国产精品久久久久久久久| 久久久精品国产网站| 亚洲视频欧美视频| 粉嫩av一区二区三区免费野| 欧美午夜影院在线视频| 日本a级片电影一区二区| 欧美国产日韩中文字幕在线| 人妖精品videosex性欧美| 欧美精品电影在线| 国产不卡在线观看| 久久中文字幕在线| 亚洲精品视频播放| 午夜精品在线观看| 亚洲精品国产福利| 色av中文字幕一区| 久久亚洲精品中文字幕冲田杏梨| 亚洲成av人片在线观看香蕉| 韩国三级日本三级少妇99| 欧美激情精品久久久久久久变态| 日韩美女av在线免费观看| 精品国产乱码久久久久久婷婷| 亚洲2020天天堂在线观看| 国产日韩欧美电影在线观看| 久久久久久亚洲精品| 国产精品视频自拍| 国产福利成人在线| 国产欧美日韩高清| 91地址最新发布| 成人国产精品av| 久久亚洲综合国产精品99麻豆精品福利| 激情久久av一区av二区av三区| 97人人模人人爽人人喊中文字| 久久免费观看视频| 国产剧情日韩欧美| 国产在线视频一区| 欧美大成色www永久网站婷| 久久久久久九九九| 日韩成人中文电影| 亚洲精品理论电影| 亚洲成人精品久久久| 欧美激情一区二区三区在线视频观看| 亚洲男人av在线| 欧美激情欧美激情| 欧美日韩另类在线| 欧美综合在线观看| 国模极品一区二区三区| 欧美性猛交xxxx乱大交蜜桃| 2019日本中文字幕| 国产精品wwwwww| 久久久久久久成人| 色樱桃影院亚洲精品影院| 日韩精品中文在线观看| 在线视频中文亚洲| 国产成人综合亚洲| 亚洲伊人久久大香线蕉av| 日韩精品极品视频免费观看| 国产精品久久久久久久久影视| 成人a级免费视频| 亚洲欧美视频在线| 国产精品第一页在线| 亚洲电影av在线| 日韩第一页在线| 日韩在线一区二区三区免费视频| 95av在线视频| 久久手机免费视频| 亚洲欧美变态国产另类| 自拍偷拍免费精品| 亚洲视频专区在线| 日韩在线视频免费观看高清中文| 亚洲国语精品自产拍在线观看| 久久影视电视剧免费网站清宫辞电视|