通常的單元測試架構都以他們支援的語言的開頭字母加上Unit作為名字,他們統稱為xUnit架構。C++的叫做CppUnit,Java的叫做JUnit,.Net的叫做NUnit。當然不是所有的都這麼命名,但大部分如此。下面我主要講解一下NUni的一些基本操作。
1:Nunit兩個重要屬性
1.1:[TestFixture]
這個是辨別包含自動化測試的類,可能改成TestClass大家更加了解。但是代碼是無法編譯過去的。
1.2:[Test]
這個是辨別這個方法需要自動化測試的。記得把這個屬性加在要測試的方法上。
2:編寫第一個單元測試
2.1:一個單元測試通常包含三個行為:
2.1.1:準備對象(就是對哪個對象就行操作)
2.1.2:操作對象(對對象進行一些邏輯處理)
2.1.3:斷言(Assert)和預判産生的結果對比
2.2:編寫一個判斷字尾名的方法
public bool IsValidExtensions(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentNullException("fileName");
var extension = Path.GetExtension(fileName);
if (extension.Contains("pdf"))
{
return true;
}
return false;
}
2.3:編寫測試方法
2.3.1:Assert這個類
Assert.IsFalse(bool condition, string message)
參數1:傳回的結果 參數2:展示失敗的資訊
Assert.AreEqual(int expected, int actual, string message)
參數1:期望的結果 參數2:實際的結果 參數3:展示失敗的資訊
當然Assert很多方法可以自己去學習。
[Test]
public void IsValidExtensions_BadExtension_ReturnsFalse()
{
var arithmetic=new Arithmetic();
bool restlt = arithmetic.IsValidExtensions("log.pdf");
Assert.IsFalse(restlt,"沒有傳回正确值");
}
2.3.2:編譯項目然後打開Nunit,點選NUnit的File打開這個編譯的dll檔案然後如下圖
2.3.3:我們要修改單元測試方法
右鍵點選上圖的ArithmeticTest選擇LoadFixture就會重新導入這個ArithmeticTest。ClearFixTure清理這個ArithmeticTest
2.4:使用參數重構測試
比喻上面我們的參數叫做log.pdf但是現在又要測試log.txt怎麼辦,如果說2個可以寫,10個乃至100個呢不用擔心NUnit給我們提供了兩個特性
[TestCase]
ok我們來修改上面的單元測試代碼
[TestCase("log.pdf")]
[TestCase("log.txt")]
public void IsValidExtensions_BadExtension_ReturnsFalse(string fileName)
{
var arithmetic=new Arithmetic();
bool restlt = arithmetic.IsValidExtensions(fileName);
Assert.IsFalse(restlt,"沒有傳回正确值");
}
我們在運作NUnit看看效果:
看到效果了吧我們就出現了兩個方法。這樣一來是不是很簡單。
但是有的又說我可不可以指定我預期的效果呢,很明顯是可以的我們在此修改測試方法
[TestCase("log.pdf",true)]
[TestCase("log.txt",false)]
public void IsValidExtensions_BadExtension_ReturnsFalse(string fileName)
{
var arithmetic=new Arithmetic();
bool restlt = arithmetic.IsValidExtensions(fileName);
Assert.IsTrue(restlt,"沒有傳回預期的值");
}
我們運作會發現這2個都能通過編譯這裡就不貼圖了。
2.5:setup和teardown
setup特性以後表示每次運作這個測試類首先就會進入這個方法相當于我們常說的構造函數
teardown表示方法運作結束以後再運作這個方法,我們常說的析構函數。
如
[setup]A()
[test]B()
[teardown]C()
運作順序是A到B到C
2.6:異常檢測
2.6.1:ExpectedException辨別這種辨別是很常見的一種測試異常的方法下面來看它的用法
public bool IsValidExtensions(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentNullException();
var extension = Path.GetExtension(fileName);
if (extension.Contains("pdf"))
{
return true;
}
return false;
}
[Test]
[ExpectedException(typeof(ArgumentNullException),ExpectedMessage = "值不能為 null。")]
public void IsVaildFileName_EmptyFileName_ThrowException()
{
var arithmetic = new Arithmetic();
arithmetic.IsValidExtensions("");
}
第一個參數:表示顯示異常的類
第二個參數:表示期望的異常
注意:這個異常并沒有調用Assert因為ExpectedException本身帶有判斷。
我們看看測試結果:
表示異常和我們期待的一樣,但是這有一個問題如果我們構造函數抛出一個異常測試同樣會通過,是以就會導緻測試出現了不真實性。(我測試過在構造函數抛出空異常同樣測試通過)
那麼就引進了另一個異常的測試方式Lambda表達式來改造一下
[Test]
public void IsVaildFileName_EmptyFileName_ThrowException() {
var arithmetic = new Arithmetic();
var ex = Assert.Catch<Exception>(() => arithmetic.IsValidExtensions(string.Empty));
StringAssert.Contains("值不能為 null。", ex.Message);//可以不寫值不能為Null也能通過測試
}
這樣就避免了上面的情況,隻要是lambda表達式抛出異常就通過測試否則任何地方抛出異常都不能通過測試。
2.7:忽略測試
有時候有些代碼不需要測試,但是你又把它遷入主項目那麼你就可以考慮把他忽略掉(當然這種情況很少的)
[Test]
[Ignore("這個方法目前不用進行測試")]
public void IsVaildFileName_BadExtension_ReturnFalse()
{
var arithmetic = new Arithmetic();
Assert.IsTrue(arithmetic.IsValidExtensions("11"));
}
測試效果:
黃色的就表示暫時不考慮測試的方法。
2.8:設定測試類别
在實際開發中可能我們很多測試,為了分開測試我們可以設定類别,也可以在測試中選擇一些分類測試下面我們看看怎麼實作的
[Test]
[Category("背景單元測試")]
public void IsVaildFileName_BadExtension_ReturnFalse()
{
var arithmetic = new Arithmetic();
Assert.IsTrue(arithmetic.IsValidExtensions("11"));
}
[Test]
[Category("前端單元測試")]
public void IsVaildFileName_EmptyFileName_ThrowException() {
var arithmetic = new Arithmetic();
var ex = Assert.Catch<Exception>(() => arithmetic.IsValidExtensions(string.Empty));
StringAssert.Contains("值不能為 null。", ex.Message);
}
我們看看效果:
大家可以自己動手測試下,實際功能比這強大很多的。
2.9:測試類中某個屬性沒有傳回值怎麼辦
這個比較簡單我直接貼代碼了。
public bool IsOnline { get; set; }
public void IsValidExtensions(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentNullException();
var extension = Path.GetExtension(fileName);
if (!extension.Contains("pdf")) return;
IsOnline = true;
}
[Test]
public void IsVaildFileName_BadExtension_ReturnFalse()
{
var arithmetic = new Arithmetic();
arithmetic.IsValidExtensions("log.pdf");
Assert.IsTrue(arithmetic.IsOnline);
}
這個效果很明顯是通過的。這樣來驗證類的一個屬性(但是有一個依耐項)
以上參考單元測試的藝術