日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一步一步学NUnit

發布時間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步一步学NUnit 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://tech.sina.com.cn/s/2009-07-17/1129988785.shtml

單元測試基礎知識

單元測試是開發者編寫的一小段代碼,用于檢驗被測代碼的一個很小的、很明確的功能是否正確。通常而言,一個單元測試是用于判斷某個特定條件(或者場景)下某個特定函數的行為。例如,你可能把一個很大的值放入一個有序list 中去,然后確認該值出現在list 的尾部。或者,你可能會從字符串中刪除匹配某種模式的字符,然后確認字符串確實不再包含這些字符了。

執行單元測試,是為了證明某段代碼的行為確實和開發者所期望的一致。

當編寫項目的時刻,如果我們假設底層的代碼是正確無誤的,那么先是高層代碼中使用了底層代碼;然后這些高層代碼又被更高層的代碼所使用,如此往復。當基本的底層代碼不再可靠時,那么必需的改動就無法只局限在底層。雖然你可以修正底層的問題,但是這些對底層代碼的修改必然會影響到高層代碼。于是,一個對底層代碼的修正,可能會導致對幾乎所有代碼的一連串改動,從而使修改越來越多,也越來越復雜。從而使整個項目也以失敗告終。

而單元測試的核心內涵:這個簡單有效的技術就是為了令代碼變得更加完美。

NUnit介紹

NUnit 是一個免費開源的產品,它提供了一套測試框架和一個測試運行程序(test runner)。

注意:test tunner 知道如何尋找具有 [TestFixture] 屬性的類和類中的 [Test] 方法。

如何安裝 NUnit

在官網下載NUnit,當前最新的版是2.4.8,我下的是NUnit-2.4.8-net-2.0.zip。

NUnit第一個演示

我們用Visual Studio 2008新建一個NUnit項目:

?

為了便于演示,我們把默認的Program.cs改成Calculator.cs,在Calculator類里,我們實現簡單的加減乘除四個方法。完整代碼如下:

using?System;

namespace
?NUnitTest
{
???
public?class
?Calculator
??? {
???????
///?<summary>

???????
///?加法
???????
///?</summary>

???????
///?<param name="a"></param>
???????
///?<param name="b"></param>
???????
///?<returns></returns>
???????
public?int?Add(int?a,int?b)
??????? {
???????????
return?a?+
?b;
??????? }

???????
///?<summary>

???????
///?減法
???????
///?</summary>

???????
///?<param name="a"></param>
???????
///?<param name="b"></param>
???????
///?<returns></returns>
???????
public?int?Minus(int?a,?int?b)
??????? {
???????????
return?a?-
?b;
??????? }

???????
///?<summary>

???????
///?乘法
???????
///?</summary>

???????
///?<param name="a"></param>
???????
///?<param name="b"></param>
???????
///?<returns></returns>
???????
public?int?Multiply(int?a,?int?b)
??????? {
???????????
return?a?*
?b;
??????? }

???????
///?<summary>

???????
///?除法
???????
///?</summary>

???????
///?<param name="a"></param>
???????
///?<param name="b"></param>
???????
///?<returns></returns>
???????
public?int?Divide(int?a,?int?b)
??????? {
???????????
return?a?/
?b;
??????? }

???????
static?void Main(string
[] args)
??????? {
??????????? Calculator cal?
=?new
?Calculator();
???????????
int?result?=?cal.Add(2,3
);
??????????? Console.WriteLine(result);

??????????? Console.ReadKey(
true
);
??????? }
??? }
}

???????? 如果沒有單元測試,我們普通的測試方法就像是Main方法一樣,這樣的測試是一個很邪惡的測試方法,花時間且很難得到我們
想要的結果。

那么,我們應該如何來用NUnit做單元測試呢?

我們再新建一個項目:

?

為這個NUnitTestTest引用“NUnitTest項目”和“nunit.framewor類庫”。我們再新建一個測試類,命名為“CalculatorTest.cs”。并鍵入如下代碼:

using?System;
using
?NUnit.Framework;
using
?NUnitTest;

namespace
?NUnitTestTest
{
??? [TestFixture]
???
public?class
?CalculatorTest
??? {
??????? [Test]
???????
public
?void TestAdd()
??????? {
??????????? Calculator cal?
=?new
?Calculator();
???????????
int?expected?=?5
;
???????????
int?actual?=?cal.Add(2,?3
);
??????????? Assert.AreEqual(expected, actual);
??????? }
??? }
}

?

這就是一個簡單的單元測試方法了。首先我們使用using NUnit.Framework和using NUnitTest,因為接下來的代碼需要用到這兩個命名空間。在這里,我們要注意幾點,NUnit測試用的類前面一定要加上[TestFixture],以表示這是NUnit測試類;測試方法一定是public的,且沒有返回值。這里的TestFixture和Test都是NUnit的Attribute,下表給出了NUnit常用的Attribute:
?

?

????????? Assert.AreEqual是斷言,在測試框架中,斷言是單元測試的核心,我們在測試中要對其程序斷言。如果某個斷言失敗,方法的調用不會返回值,并且會報告一個錯誤。如果一個測試包含多個斷言,那些緊跟失敗斷言的那些斷言都不會執行,因此每個測試方法最好只有一個斷言。 NUnit.Framework.Assert有23個重載方法,大部分的情況它都有考慮到,當然,不排除需要自己寫一個復雜的斷言方法。

上面的代碼中,int expected = 5;是指我們期望程序執行的結果是5,int actual = cal.Add(2, 3);則執行Calculator.Add方法得到實際的值。

順便說一下,CalculatorTest(類名)還有TestAdd(方法名)并不是一定要這樣寫,你可以自由的命名你的名稱,不過為了讓你的代碼可讀性更好,請遵循一個命名規范,這個規范可以是公司定的也可以是網上主流的命名規則。

對Add()方法的單元測試代碼已經完成了,接下來我們運行下載解壓后文件夾中的nunit.exe,程序界面如圖:

?

?

打開對話"File"/"Open Project..."對話框,或者按"Ctrl + O",把第二個單元測試項目NUnitTestTest生成的NUnitTestTest.dll加載進來:

?


我們點右邊的"Run"按鈕執行單元測試:

?

?

太棒了,綠色!通過!Keep the bar green to keep the code clean.

一個簡單的單元測試過程就是這樣的。

我們再為除法寫一個單元測試方法:

[Test]

public
?void TestDivide()

{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Divide(25,?5
);

Assert.AreEqual(expected, actual);

}

重新生成NUnitTestTest項目,NUnit會自動把TestDivide方法加進去。

?

再點"Run",通過測試。大家都知道除法中除數不能為0,如果這里除數是0呢?會有什么樣的結果?

[Test]

public
?void TestDivide()

{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Divide(25,?0
);

Assert.AreEqual(expected, actual);

}

生成項目并重新運行單元測試:

?
?

測試沒有通過 “NUnitTestTest.CalculatorTest.TestDivide:System.DivideByZeroException : 試圖除以零。”這時,我們要返回到Calculator類中修改Divide方法使之除數為0時返回其它的值。

NUnit第一個簡單示例就先到這里,在NUnit的官網也有簡單教程,大家可以看看。

在單元測試中,我們在做正面的測試的同時也要做一些反面測試,這樣才能讓我們的代碼更健壯。

在Visual Studio 2008 中打開上一章的示例,Calculator類有4個最簡單的方法:加、減、乘、除。CalculatorTest類中的四個方法是Calculator類四個方法的單元測試。

[TestFixture]

public?class
?CalculatorTest

...{

[Test]

public
?void TestAdd()

...{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Add(2,?3
);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestMinus()

...{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Minus(10,?5
);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestMultiply()

...{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Multiply(1,?5
);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestDivide()

...{

Calculator cal?
=?new
?Calculator();

int?expected?=?5
;

int?actual?=?cal.Divide(25,?5
);

Assert.AreEqual(expected, actual);

}

}

這里一定要注意,TestAdd()、TestMinus()、TestMultiply()和TestDivide()方法沒有任何關系,也就是說單元測試中,所有的測試方法都是獨立的。各個方法之間沒有依賴性,刪除任何一個單元測試方法,對其它的測試不會有任何影響。

上一章中,我們已經介紹了[TestFixture]和[Test],現在我們為這個類新增一個方法。

[SetUp]

public
?void InitMethod()

{

Console.WriteLine(
"Initialization method"
);

}

重新生成項目,再運行NUnit,選中"CalculatorTest"進行單元測試:

?

切換到NUnit的"Console.Out"中,我們看到"Initialization method"出現了4次,如果只選中一個測試方法:

?

我們看到,這時只出現一次的"Initialization method"。[SetUp]的意思就是指在運行每個測試方法前執行它。相應的,有開始必然有結束,[TearDown]是指在每個測試方法結束后運行。

我們再新增一個方法:

[TearDown]

public
?void FinalizeMethod()

{

Console.WriteLine(
"Finalize method"
);

}

再來看運行NUnit的結果:

?

知道了[SetUp]和[TearDown]后,我們就可以改寫這個單元測試類了。

請[TestFixture]

public?class
?CalculatorTest

...{

private
?Calculator cal;

private?int
?a, b, expected, actual;

[SetUp]

public
?void InitMethod()

...{

cal?
=?new
?Calculator();

a?
=?10
;

b?
=?2
;

}

[Test]

public
?void TestAdd()

...{

expected?
=?12
;

actual?
=
?cal.Add(a, b);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestMinus()

...{

expected?
=?8
;

actual?
=
?cal.Minus(a, b);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestMultiply()

...{

expected?
=?20
;

actual?
=
?cal.Multiply(a, b);

Assert.AreEqual(expected, actual);

}

[Test]

public
?void TestDivide()

...{

expected?
=?5
;

actual?
=
?cal.Divide(a, b);

Assert.AreEqual(expected, actual);

}

}

因為運行每個測試方法之前,都會運行InitMethod()方法,所以每次都會初始化使第一個操作數為10,第二個操作數為2。在[SetUp]中初始化了的資源,我們就可以在[TearDown]里銷毀釋放。

這里也許有人會問,如果我的項目很大,每個測試方法都需要連接數據庫,在每個方法執行的時候進行連接再釋放,這樣是不是太耗資源太慢了,能不能在一個單元測試類實例化的時候就運行一個指定的方法呢?

這是可以的。在NUnit中,我們使用[TestFixtureSetUp]和[TestFixtureTearDown]就可以實現這樣的功能。[TestFixtureSetUp]是指在這個測試類的整個生命周期中,它在所有的測試方法之前運行一次,而[TestFixtureTearDown]是在所有的測試方法都結束時運行。

這里要注意的,[TestFixtureSetUp]與構造函數是不一樣的,它標識的方法遲于構造函數運行。我們再對這個測試類進行重構:

[TestFixture]

public?class
?CalculatorTest

...{

private
?Calculator cal;

private?int
?a, b, expected, actual;

public
?CalculatorTest()

...{

Console.WriteLine(
"執行構造函數"
);

}

[TestFixtureSetUp]

public
?void InitClass()

...{

Console.WriteLine(
"執行TestFixtureSetUp"
);

cal?
=?new
?Calculator();

a?
=?10
;

b?
=?2
;

}

[TestFixtureTearDown]

public
?void FinalizeClass()

...{

Console.WriteLine(
"執行TestFixtureTearDown"
);

}

[SetUp]

public
?void InitMethod()

...{

Console.WriteLine(
"執行SetUp"
);

}

[TearDown]

public
?void FinalizeMethod()

...{

Console.WriteLine(
"執行TearDown"
);

a?
=?10
;

b?
=?2
;

}

[Test]

public
?void TestAdd()

...{

Console.WriteLine(
"TestAdd() Begin"
);

expected?
=?12
;

actual?
=
?cal.Add(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestAdd() End"
);

}

[Test]

public
?void TestMinus()

...{

Console.WriteLine(
"TestMinus() Begin"
);

expected?
=?8
;

actual?
=
?cal.Minus(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestMinus() End"
);

}

[Test]

public
?void TestMultiply()

...{

Console.WriteLine(
"TestMultiply() Begin"
);

expected?
=?20
;

actual?
=
?cal.Multiply(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestMultiply() End"
);

}

[Test]

public
?void TestDivide()

...{

Console.WriteLine(
"TestDivide() Begin"
);

expected?
=?5
;

actual?
=
?cal.Divide(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestDivide() End"
);

}

}

在NUnit中,我們可以很清楚地看到這個類的執行順序:

?

假如我們的測試項目中有使用到數據庫,就可以把數據庫連接寫在[TestFixtureSetUp]中,把釋放的代碼寫在[TestFixtureTearDown]中。

我相信現在大家對NUnit的這4個屬性都應該有一個直觀的認識了吧。都是4個很簡單的屬性,但是在使用中用處卻是非常大的。

接下來再為大家介紹幾個常用的屬性。

現在的測試中,我們有4個測試方法,但是如果我們想讓其中的一個測試方法不在NUnit中顯示,怎么辦呢?不是注釋,大家不要想歪了,注釋大家都知道。要想讓一個測試方法不在NUnit中顯示,也不運行,我們應該使用[Ignore]屬性。看看把TestAdd()添加[Ignore]屬性后會是什么樣子:

[Test]

[Ignore]

public
?void TestAdd()

{

Console.WriteLine(
"TestAdd() Begin"
);

expected?
=?12
;

actual?
=
?cal.Add(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestAdd() End"
);

}

?


現在有了一個新的顏色了——黃色。它是指被忽略的方法。當然,你在項目中出現最多的肯定是綠色。在NUnit中我們可以用[Ignore]的重載方法[Ignore("忽略原因")]來定義忽略原因。

NUnit有一個與[Ignore]類似的屬性[Explicit],它是指只有在NUnit中被明確的指定時才運行,否則不運行。有點拗口,我們來看例子。改寫TestMinus方法:

[Test,Explicit]

public
?void TestMinus()

{

Console.WriteLine(
"TestMinus() Begin"
);

expected?
=?8
;

actual?
=
?cal.Minus(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestMinus() End"
);

}


這里,

[Test,Explicit]

[Test]

[
Explicit]

是完全一樣的。

我們看它的截圖:

?

"TestMinus"是灰色的,運行的Cases有2個,一個被忽略。而當我們選中TestMinus時:

?

這個測試運行了。

再給大家介紹一個分類屬性[Category(string name)],利用這個分類屬性,我們可以為每個方法定義類別。

[Test, Ignore("Ignore"), Category("Category A")]

public
?void TestAdd()

...{

Console.WriteLine(
"TestAdd() Begin"
);

expected?
=?12
;

actual?
=
?cal.Add(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestAdd() End"
);

}

[Test, Category(
"Category B"
)]

[
Explicit
]

public
?void TestMinus()

...{

Console.WriteLine(
"TestMinus() Begin"
);

expected?
=?8
;

actual?
=
?cal.Minus(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestMinus() End"
);

}

[Test, Category(
"Category A"
)]

public
?void TestMultiply()

...{

Console.WriteLine(
"TestMultiply() Begin"
);

expected?
=?20
;

actual?
=
?cal.Multiply(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestMultiply() End"
);

}

[Test, Category(
"Category B"
)]

public
?void TestDivide()

...{

Console.WriteLine(
"TestDivide() Begin"
);

expected?
=?5
;

actual?
=
?cal.Divide(a, b);

Assert.AreEqual(expected, actual);

Console.WriteLine(
"TestDivide() End"
);

}

重新生成項目,在NUnit中,我們可以看到:

?

這里有我們定義的兩個分類,我們選中"Category A",切換回"Tests"點"Run",我們看:

?

只測試了我們設置的"Category A"的一個方法,另一個方法是因為我們設置了[Ignore]所以沒有執行測試。

好,到這里,我們已經把NUnit主要的屬性學完了,接下來的章節我們將從實例出發學習NUnit。

轉載于:https://www.cnblogs.com/zhaox583132460/p/3442903.html

總結

以上是生活随笔為你收集整理的一步一步学NUnit的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。