单元测试和回归测试

发表于:2015-03-27来源:uml.org.cn作者:SoftwareTeacher点击数: 标签:单元测试
这一章讲的是两人合作,既然程序是两个人写的,那就会出现一个人写的模块被另一个人写的模块调用的情况。很多误解、疏忽都发生在两个模块之间。如何能让自己写的模块尽量无懈

  你的RP是由你的程序质量决定的。

  ——阿超

  这一章讲的是两人合作,既然程序是两个人写的,那就会出现一个人写的模块被另一个人写的模块调用的情况。很多误解、疏忽都发生在两个模块之间。如何能让自己写的模块尽量无懈可击?单元测试就是一个很有效的解决方案。

  1、用VSTS写单元测试

  例子:我们写一个比较常用的类型,看看它的单元测试应该怎么写?比如在各种网站应用程序中都会用到的“用户”这一类型。谁自告奋勇上来表演一下写代码?小飞,好,请上台。

  小飞创建了一个C#的类库(Class Library),并写了如代码清单11-1的代码:

  代码清单11-1

  namespace DemoUser

  {

  public class User

  {

  public User(string userEmail)

  {

  m_email = userEmail;

  }

  private string m_email; //user email as user id

  }

  }

  好,现在右键选中User,就可以看到“Create Unit Tests”的菜单,这样就可以创建新的单元测试(如图11-2所示)。

  图11-2 创建单元测试项目

  创建单元测试后,注意到在Solution Explorer中出现了三个新的文件(如图11-3所示)。

  图11-3 新的单元测试文件

  Class1.cs是程序的文件,而Class1Test.cs是与之对应的单元测试文件。

  DemoUser.vsmdi:测试管理文件。

  Localtestrun.testrunconfig:本地测试运行设置文件。

  如何管理设置文件呢?右键再选属性(Property)并不对。你得双击文件才能进入管理及设置界面。在设置界面中,你可以让单元测试产生“demouser.dll”的代码覆盖报告。

  注意在单元测试中,VSTS自动为你生成了测试的骨架,但是你还是要自己做不少事情,最起码要把那些//TODO的事情给做了(如代码清单11-2所示)。在这个时候,单元测试还都是用的Assert. Inconclusive,表明这是一个未经验证的单元测试。

  代码清单11-2

  ///

  ///A test for User (string)

  ///

  [TestMethod()]

  public void ConstructorTest()

  {

  string userEmail = null; // TODO: Initialize to an appropriate

  // value

  User target = new User(userEmail);

  // TODO: Implement code to verify target

  Assert.Inconclusive("TODO: Implement code to verify target");

  }

  进行简单的修改后,我们得到了一个如代码清单11-3正式的单元测试:

  代码清单11-3

  [TestMethod()]

  public void ConstructorTest()

  {

  string userEmail = "someone@somewhere.com";

  User target = new User(userEmail);

  Assert.IsTrue(target != null);

  }

  //我们还可以进一步测试E-mail是否的确是保存在User类型中。

  解释单元测试的结构

  从上面这个例子可以看到创建单元测试函数的主要步骤:

  (1)设置数据(一个假想的正确的E-mail地址);

  (2)使用被测试类型的功能(用E-mail地址来创建一个User类的实体);

  (3)比较实际结果和预期的结果(Assert.IsTrue(target != null);)。

  现在可以运行单元测试了,同时可以看看代码覆盖报告“code coverage report”,代码百分之百地都被覆盖了。

  当然这时候的代码还有很多情况没有处理,同学们在台下杂曰——

  处理空的字符串,长度为零的字符串,都是空格的串……

  小飞熟练地用Copy/Paste又写了下面的三个测试,如代码清单11-4所示。

  代码清单11-4

  [TestMethod()]

  [ExpectedException(typeof (ArgumentNullException))]

  public void ConstructorTestNull()

  {

  User target = new User(null);

  }

  [TestMethod()]

  [ExpectedException(typeof(ArgumentException))]

  public void ConstructorTestEmpty()

  {

  User target = new User("");

原文转自:http://www.ltesting.net