NUnit Test với Microsoft Visual Studio

Thứ Năm, 22 tháng 3, 2012

Trong bài này sẽ hướng dẫn một bài Unit Test đơn giản với C# sử dụng NUnit Framework.
Ở đây đã xây dựng sẵn một class đơn giản ngắn dễ hiểu để ai đọc cũng hiểu

using System;
using System.Collections.Generic;
using System.Text;

namespace UnitTest
{
enum CalculatingType
{
Addition,
Subtraction,
Multiplication,
Division
}
class Calculator
{
private List List;
private CalculatingType cType;
public Calculator() { }
public Calculator(List list, CalculatingType type)
{
this.List = list;
this.cType = type;
}
public List CList
{
get { return this.List; }
set { this.List = value; }
}
public CalculatingType CType
{
get { return this.cType; }
set { this.cType = value; }
}
public double GetResult()
{
double result = this.List[0];
for (int i = 1; i < this.List.Count; ++i)
{
if (cType == CalculatingType.Addition)
result += this.List[i];
else if (cType == CalculatingType.Subtraction)
result -= this.List[i];
else if (cType == CalculatingType.Multiplication)
result *= this.List[i];
else
result /= this.List[i];
}
return result;
}
}
}

Như đã thấy ở trên thì class ‘Calculator’ có sở hữu một danh sách các số kiểu double và một kiểu enum cho biết loại phép tính.
Tại project hiện tại, tạo thêm một class mới tên là ‘CalculatorTest’ để test cái class ‘Calculator’ nhé. Thông thường sẽ có test cơ bản cho class là test cho
+ Constructor, destructor
+ Properties
+ Methods
Nhưng vì cái class này bé tẹo chả có gì nhiều nên test rút ngọn properties với constructor làm một nhé
Add thêm Reference cái cục NUnit.Framework.Dll vào project đi.
Cài Nunit ở đâu thì nó ở đó.
Rồi ta thử đoạn test sau

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace UnitTest
{
[TestFixture]
class CalculatorTest
{
[Test]
public void TestCListA()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(new List { 1, 2, 3 }, calc.CList);
}
}
}
Build project rồi gọi NUnit từ VS, sau đó ấn vào nút ‘Run’.
Kết quả thu được là 1 pass xanh lè , vậy là qua!

Nunit Test, Microsoft Visual Studio, .NET Framework


Một chút giải thích nhỉ. Sau khi add NUnit vào thì sẽ có thể sử dụng các lớp thuộc tính chỉ định test cho class và method.
[TestFixture] là cho class, [Test] là cho method
Khá là đơn giản!
Hãy thử tiếp ví dụ dưới

[Test]
public void TestCListB()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(new List { 2, 3, 1 }, calc.CList);
}

Ở đây bị fail rồi, đỏ lòm
UnitTest.CalculatorTest.TestCListB:
Expected and actual are both with 3 elements
Values differ at index [0]
Expected: 2.0d
But was: 1.0d

Tại index đầu tiên ( vị trí 0 ), giá trị đầu tiên của 2 list khác nhau nên fail rồi.
Thường thì cứ nghĩ 2 list có các giá trị giống nhau nhưng sắp xếp vị trí khác nhau thì được nhưng ở đây không như thế mà giá trị tại các index sẽ được lần lượt so sánh nhé. Thế mới gọi là test chứ
Test thử so sánh với một list khác

[Test]
public void TestCListC()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(new List { -1, 2, 3 }, calc.CList);
}

Cái này 100% là fail rõ ràng.
Giờ thử đến so sánh kiểu tính toán CalculatingType
[Test]
public void TestCTypeA()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(CalculatingType.Addition, calc.CType);
}

[Test]
public void TestCTypeB()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(CalculatingType.Subtraction, calc.CType);
}
Đến đây thì chắc là rõ như ban ngày rồi nhỉ.
Tương tự, đem test cái cục GetResult() nhưng vì thằng này có cục logic 4 case của enum CalculatingType nên tách ra test từng case thành từng hàm test nhỏ cho dễ hiểu.

[Test]
public void TestAddition()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Addition);
Assert.AreEqual(6, calc.GetResult());
}

[Test]
public void TestSubtraction()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Subtraction);
Assert.AreEqual(-4, calc.GetResult());
}
[Test]
public void TestMultiplication()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Multiplication);
Assert.AreEqual(6, calc.GetResult());
}
[Test]
public void TestDivisionA()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Division);
Assert.AreEqual(0.1666667, calc.GetResult());
}
Mấy hàm TestAddition(), TestSubtraction(), TestMultiplication() thì pass, nhưng thằng TestDivisionA() thì fail nhé.
Lí do là cái đám số đằng sau dấu chấm nó dài thế so sánh biết bao nhiêu là đúng .
Đến đoạn này thì phải nhanh nhạy một tí, thấy 2 giá trị đầu 1/2 = 0.5 , thế thì vứt béng nó vào làm cái expected result đi

[Test]
public void TestDivisionB()
{
Calculator calc = new Calculator(new List { 1, 2, 3 }, CalculatingType.Division);
Assert.AreEqual( 0.5/3, calc.GetResult());
}

OK! TestDivisionB() pass.
Chưa vội mừng, nhỡ trong list có số 0 thì sao nhở?
Exception throw ra thì teo.
Rất may NUnit đã cung cấp một cái attribute để test exception luôn.
Đây là một demo

[Test,ExpectedException(typeof(DivideByZeroException))]
public void TestDivisionC()
{
Calculator calc = new Calculator(new List { 1, 2, 0 }, CalculatingType.Division);
throw new DivideByZeroException();
}

Như đoạn code ở trên, chúng ta hy vọng là nó sẽ test cái DivideByZeroException được ném ra. Và tất nhiên là ta pass
Bài này chỉ là Unit-Test rất đơn giản không có gì khó hiểu cả. Trông thì dễ đấy nhưng trong Software-Testing nó là cả một khối lượng công việc ngập đầu. Test script viết ra mà chạy fail thì ta cứ lôi thằng code ra mà chửi.
Tags: , , , , , , ,
Liên Hệ Quảng Cáo SĐT:01224193994 Yahoo: xuanthucit

Ý kiến bạn đọc [ 0 ]


Ý kiến của bạn