Figure 3. Unit test failed
可以看到,我们在单元测试中提供的例子的期望最大值是9,运行结果却是2147483647。再看一看我们得Largest方法,原来是在对maxNum进行第一次赋值的时候不小心把Int32.MinValue写成了Int32.MaxValue。你看,单元测试就是能够发现一些意向不到的错误。不要以为这里的bug很低级,类似的情况确实会在现实中发生。
我们把上面的错误更正后,再次运行TestMethod1()就会得到test passed的结果(如图4所示)。
Figure 4. Unit test passed
2. 一个例子告诉你该如何写单元测试
我们现在要利用List来写一个模拟栈操作的类,该类提供Push、Pop、Top和Empty方法,现在要对这个类进行单元测试。
首先我们要明确这个类的主要功能:这里的栈用来存储数据,这些数据按照存入时间有序(为方便描述,不妨将最早进入的数据位置称为栈底,最后进来的位置称为栈顶);当需要存入数据时,采用Push操作将该数据放在栈顶;当需要从栈中取出数据时,采用Pop操作将栈顶的数据取出;当需要查看栈顶元素时,采用Top操作即可得到栈顶元素值;当需要知道栈中是否有数据时,采用Empty查看它是否为空。
那我们就针对这些功能来想想我们应用这个栈的场景吧,然后就可以把这些场景写成单元测试。
(1)往一个空栈中Push数据,该操作成功的话栈应该不空,并且栈顶元素就是刚Push进去的那个数据。
(2)连续地往栈中Push数据,每次操作后查看栈顶元素都是刚刚放进去的那个数据。
(3)往栈中Push特殊的数据,我们这里存放的是string,所以添加string.Empty和null也应该是成功的。
(4)连续地Pop操作,确认每次取出的都是栈顶元素。
(5)对空栈进行Pop或Top操作,会抛出异常。
// StackExercise Class
namespace FirstUnitTest
{
public class StackExercise
{
private List _stack;
public StackExercise()
{
_stack = new List();
}
public void Push(string str)
{
_stack.Add(str);
}
public void Pop()
{
if (Empty())
{
throw new InvalidOperationException("Empty stack cannot pop");
}
_stack.Remove(_stack.Last());
}
public string Top()
{
if (Empty())
{
throw new InvalidOperationException("Empty stack cannot get top");
}
return _stack.Last();
}
public bool Empty()
{
return (!_stack.Any());
}
}
}
// Unit Tests
namespace FirstUnitTest
{
[TestClass]
public class TestStackExercise
{
[TestMethod]
public void Test_SuccessAndNotEmpty_AfterPush()
{
// Arrange
var stack = new StackExercise();
var testElement = "testElement";
// Action
stack.Push(testElement);
// Assert
Assert.IsFalse(stack.Empty());
Assert.AreEqual(testElement, stack.Top());
}
[TestMethod]
public void Test_Success_PushMoreThanOnce()
{
// Arrange
var stack = new StackExercise();
var testElement = "testElement_{0}";
// Action & Assert
for (int i = 0; i < 10; ++i)
{
stack.Push(string.Format(testElement, i));
Assert.AreEqual(string.Format(testElement, i), stack.Top());
}
}
[TestMethod]
public void Test_Success_PushEmptyString()
{
// Arrange
var stack = new StackExercise();
string emptyString = string.Empty;
string nullString = null;
原文转自:http://www.jianshu.com/p/7984955720e2