在前面的文章数据驱动测试里,讲到了将测试数据以及表现测试步骤的代码分开的技术。从测试的角度来看,固然希望能够覆盖的测试场景越多越好,但是在设计和编写自动化测试代码的时候,却又可以事先设计好一些固定的测试数据简化自动化测试代码的编写工作。

  之所以要这样做(按照编程的术语讲是硬编码),是因为按照等价类划分,固定的测试数据一般都已经被其他测试用例覆盖了。请考虑下面这个例子,假设你要测试一个博客网站(例如博客园)的文章评论功能,例如测试禁用一篇文章的评论功能,或者是测试文章作者删除评论的功能。按照正常的流程,肯定是需要先编码发布一篇文章,然后再编码指定的评论功能测试用例。这样的流程有以下几个缺点:

 

  1. 需要冗余的编码,因为每个评论测试用例的代码都要包含发布文章的步骤,在编程里面,我们都是极力推荐,什么只要代码在不同的地方重复两次,要考虑是否将它封装成一个函数之类的理念。这种包含冗余编码的方式是我们在测试过程中极力要避免地,否则,程序员可能哪天心情很好,重构一下代码,破坏了一些网页的HTML结构—但是从用户的角度来看又没有任何区别;这种代码重构,作为测试人员只能跟着程序员的代码重构,修改测试代码,那个时候,你当然会希望改的地方越少越好啦。

  对于这个缺点,可能有人要说,在前面的文章“网站测试自动化系统—基于Selenium和VSTT”,创建博客的测试步骤不是已经被有效地封装成一个函数了吗,为什么还会说有冗余?这是因为在自动化测试过程中, 测试人员会定期(一些高规格的软件开发团队要求每天)将所以编写完毕的测试代码批量执行一遍,这涉及到对于任何测试用例编码都非常重要的两个原则:

  1) 一个测试用例可以独自执行成功,是说如果是单独执行这一个测试用例的话,这个测试用例是可以执行成功的—否则是产品编码的失误(Bug)。举个例子,你正要编码测试一个管理博客文章的功能,这个功能通常来说都是登录用户才可以使用的。然而,也许你刚刚编码完毕一个登录方面的测试用例,而且用例执行完毕的时候,没有执行注销操作。这个时候你不能想当然地以为下一个测试用例一定是你现在正在编码的文章管理的测试用例。


  因为测试人员既保留有将多个测试用例任意排列执行的权力,也可以选择单独执行这一个测试用例—比如程序员刚刚重构了文章管理功能的代码,为了节省测试时间,测试人员可能会选择只执行文章管理方面的测试用例。所以不要将自己的命运寄托在别人手里。即除了整个团队都公认的前提以外,不要相信任何前提。


  2) 测试用例可以在任意排列的用例序列中执行通过,因此测试代码应该尽量保护测试环境。举个例子,你设计了一个管理用户权限的测试用例,一般来说这种功能只有管理员才有权限操作的。然而,也许另一个粗心大意的测试工程师编码了一个测试删除用户的用例,恰好将管理员删除了,而你的用例正好在他的用例之后执行……己所不欲,勿施于人,既然你不希望碰到这种情况,那么在编码自己的测试用例之前也应该避免类似的事情发生。

 

  回过头来再举评论管理测试用例的设计,于是你的几个测试代码可能看起来像下面这样:

[TestMethod]

public void BlogCommentIsDisabled()


{

 

    TestLibrary.UserHelper.LogOnAsAdmin();

    var blog = TestLibrary.BlogHelper.CreateBlog("博客文章标题", "文章内容");

    // 去管理文章的网页

 

    TestLibrary.BlogHelper.ManageArticles();


    // 在文章管理的网页的文章列表里依次查找标题为

 

    // "博客文章标题"的文章连接,

    var blogListItem = TestLibrary.BlogHelper.FindBlog(blog.Title);

    // 并且在网页上点击"浏览" 这个链接,打开阅读文章的网页

 

    blogListItem.View();


    // 评论这篇文章

 

    TestLibrary.BlogHelper.Comment(blog);

    // 然后执行一些验证判断评论功能的确被禁用掉了

 

    // ...

}

 


[TestMethod]

public void DeleteBlogComment()


{

 

    TestLibrary.UserHelper.LogOnAsAdmin();

 

    var blog = TestLibrary.BlogHelper.CreateBlog("博客文章标题", "文章内容");

    // 去管理文章的网页

    TestLibrary.BlogHelper.ManageArticles();

    // 在文章管理的网页的文章列表里依次查找标题为

    // "博客文章标题"的文章连接,

    var blogListItem = TestLibrary.BlogHelper.FindBlog(blog.Title);

 

    // 并且在网页上点击"浏览" 这个链接,打开阅读文章的网页

    blogListItem.View();

 

    // 评论这篇文章

 

    var comment = TestLibrary.BlogHelper.Comment(blog);

    // 找到刚才的评论、删除评论,然后执行验证确定

 

    // 评论被删除掉

}