写这个主要原因是为了总结。之前为了在VS上使用Nunit费了不少功夫,很多文章和书籍都写的很冗长(可能是老版本的缘故),后来发现其实没那么复杂。资料来源主要来自于《单元测试的艺术 第二版》这本书,所以相当于这本书的读书笔记。
俗话说万事开头难,首先需要在待测试的工程下配置Nunit。
工具-扩展和更新-联机-搜索Nunit,看到Nunit 3 Test Adapter 和 Test Generator NUnit extension毫不犹豫猛击下载之。
下载书上提供的测试代码,代码地址https://github.com/royosherove/aout2
找到待测试的类(这里选择Chapter2_files下的LogAnalyzer类),双击类名—右键—创建单元测试—猛击确定
然后你会发现VS很贴心的自动生成一个LogAnTests项目,其中有LogAnalyzerTests.cs文件初始默认的测试代码。之后打开测试—窗口—测试资源管理器以备用。
现在准备的差不多了,可以写测试了。现在问题是什么是测试?简单的说是期望值与实际值比较,如果结果与期望一致测试就通过,不一致就不过。检测期望与结果的工具是Assert类,它可以检测一个布尔表达式是否为TRUE/FALSE,检测两个对象是否相等,检测一个对象是否为NULL等等等等。
//检测两个对象是否相同
Assert.AreEqual(2, 1+1, “Math is broken”);
//检测两个参数是否指向同一对象
Assert.AreSame(int.Parse("1"), int.Parse("1"), "Test fail");
//检测结果是否为true
Assert.True(result);
写测试之前还是先看看待测试的代码比较好
public class LogAnalyzer
{
public bool IsValidLogFileName(string fileName) {
if (fileName.EndsWith(".SLF",StringComparison.CurrentCultureIgnoreCase))
return false;
return true;
}
}
功能是检测文件是否以.slf作为后缀,我们在if的判断语句中将!去掉,这样当遇到.slf文件时会返回false。现在我们假装不知道这个错误,所以现在目标是检测出代码的缺陷。测试的步骤是给这个方法传递一个有效的文件名,并确认是否返回ture。
开始写测试代码,并点击测试资源管理器全部运行运行测试代码,发现测试果然出错了,将之前去掉的!加回去即可保证测试通过。
刚才的测试可以保证错误的文件被识别,但是测试需要覆盖所有的情况。所以我们又加入几个测试,分别测试大写后缀和小写后缀(其实就是恳求C恳求V换换方法名之类的)。
[TestFixture()]
public class LogAnalyzerTests
{
[Test()]
public void IsValidLogFileNameLowercaseTest()
{
LogAnalyzer analyzer = new LogAnalyzer();
bool result = analyzer.IsValidLogFileName("123.slf");
Assert.True(result);
}
[Test()]
public void IsValidLogFileNameUppercaseTest()
{
LogAnalyzer analyzer = new LogAnalyzer();
bool result = analyzer.IsValidLogFileName("123.SLF");
Assert.True(result);
}
}
测试通过,因为待测试代码中的if条件表达式很机智的忽略了大小写。
然而又有新的问题:如果类LogAnalyzer的构造函数加入新的参数,三个测试都不能正常编译,所以就要写一个更加通用的测试(实际编写代码的时候都比较怕new,因为构造函数是经常发生变化的部分之一,不仅如此实例化的对象也会根据各种原因变更,所以一个写不好就要加班)(解决此类问题使用创建型设计模式,关于设计模式总览可以参考维基百科设计模式词条)
测试方法也是可以传递参数的,这个参数可以是待测试用例集等经常变更的部分。传递参数可以解决之前硬编码所造成的问题。变更方法如下图所示
第一版的截图,第二版似乎没有电子书的版本
修改之前的代码,其中TestCase是可以随意添加的,相当于添加任意多的测试用例集,这样就达到复用的目的了。
[TestFixture()]
public class LogAnalyzerTests
{
[TestCase("123.slf")]
[TestCase("123.SLF")]
public void IsValidLogFileNameTest(string file)
{
LogAnalyzer analyzer = new LogAnalyzer();
bool result = analyzer.IsValidLogFileName(file);
Assert.True(result);
}
[TestCase("123.foo")]
[TestCase("123.txt")]
public void IsValidLogFileNameBadExtensionTest(string file)
{
LogAnalyzer analyzer = new LogAnalyzer();
bool result = analyzer.IsValidLogFileName(file);
Assert.False(result);
}
}
文章的最后还有几个问题
问题1:如何做到测试集覆盖所有的情况?
问题2:如何定位测试代码的错误之处?
这些问题以后再解决吧_(:з」∠)_
这些Blog对我帮助甚大,感谢之:
http://www.cnblogs.com/xishuai/p/3728576.html;
http://blog.csdn.net/loongsking/article/details/54572551;
Nunit doc:https://github.com/nunit/docs/wiki/NUnit-Documentation