设计之道:使用NUnit测试和验证程序用例

问说网 · 发布于 2014-12-02 · 字数5046 · 浏览 1202 · 评论 0

测试用例定义了一系列输入,同时也可以定义一系列输出,以验证被执行的某些程序特性没有引入任何Bug。测试可能会失败是因为产品里有Bug,但也可能是测试代码自身有Bug——可以称为false negative。相似的,测试能通过也有可能恰好是因为测试中有Bug,而非你的产品准确无误,我们称为false positive。[译注:意思是测试中有Bug,而产品中也有Bug,巧的是这两处的Bug恰好负负得正,抵消了Bug所带来的影响,反而使测试通过。]好的测试应该避免出现false negatives,且绝对不能包含false positives。另外,好的测试包不仅要测试正确的场景,也要测试错误的用例。

测试对象和其环境在测试用例被执行前总是保持相同的状态,因此一旦有必要就需重复执行并给出恒定的结果。当测试失败时,定位到错误的地方就能获得相关的信息。通过这些信息就能推断出问题能否被纠正。这就是为什么要求你对每个测试用例都要验证其合法性的原因所在。

现在我们为Quad例子写一些测试用例来实践上述的原理。在Visual Studio和NUnit 中打开Quad 项目,和起初打开Money 项目的方法一样——选择文件| 打开菜单,并定位到QuadApp.csproj。选择项目| 添加引用,找到文件nunit.framework.dll(在NUnit安装目录的bin子目录下),单击确定,添加引用nunit.framework。

在Visual Studio中创建QuadTest类:选择项目| 添加类,输入名字QuadTest.cs,然后单击“打开”。输入下列代码到QuadTest中:

using System;
using NUnit.Framework;
namespace QuadApp{
    [TestFixture]
    public class QuadTest{
        [TestFixtureSetUp]
        public void DoTestSuiteSetUp(){
            Console.WriteLine("TestSuiteSetUp");
        }
        [TestFixtureTearDown]
        public void DoTestSuiteTearDown(){
            Console.WriteLine("TestSuiteTearDown");
        }
        [TearDown]
        public void DoTestCaseTearDown(){
            Console.WriteLine("TestCaseTearDown");
        }
        [SetUp]
        public void DoTestCaseSetup(){
            Console.WriteLine("TestCaseSetup");
        }
        [Test]
        public void Area(){
            Quad q = new Quad();
            Assert.IsTrue( q.Area(2, 3) == 6);
            Console.WriteLine("Area");
        }
        [Test]
        public void Perimeter(){
            Quad q = new Quad();
            Assert.IsTrue( q.Perimeter(2, 3) == 10);
            Console.WriteLine("Perimeter");
        }
    }
}

编译后,在NUnit 中运行测试。单击NUnit 右侧的Console.Out 标签,可以查看执行的顺序。

现在你可以看到,不同的Setup 和TearDown 方法是怎样允许你控制测试环境,从而保证你的测试用例能根据需要而重复执行并给出恒定的结果。这些方法将帮助你确保运行一个测试用例而不会影响到另外的用例(测试用例独立性test case isolation)。测试独立性的最佳证明就是具备以任意顺序运行测试用例的能力。试着改变一下测试用例的顺序,以确认他们是否具有独立性。

测试套件和测试包

一个测试套件是一个或多个测试用例共享的一个对象,这些测试用例都与测试对象的初始化或提供相应资源有关。在NUnit 的术语中,测试套件是一个具备特性(attribute)[TestFixture]的类,并提供下列方法:

  • [Test]方法形成不同的测试用例。这些测试样例应该是测试的核心操作,并且与其它测试无关。
  • [SetUp]和[TearDown]方法提供测试用例间的环境设置。它们分别在测试开始前和结束后执行。
  • [TestFixtureSetUp]和[TestFixtureTearDown]方法要求对象被测试用例共享。它们分别在测试套件开始和结束时执行。

你希望运行测试的任意对象都可以在[TestFixture]类(被所有测试用例共享)里创建实例变量,也可以在方法(对于单个测试用例中是私有的)中创建局部变量,这就是为什么要描述为测试套件(test fixture)的原因。然而,你也可以将NUnit 的[TestFixture]看作是组织测试包的一种方法,它将测试包组织为每个类,形成treeview的每一个分支。

既然你已经能够为自己的项目创建测试包,并且通过NUnit来运行它们,那么就让我们开始TDD之旅吧。当然,首先还要看看我们在开发工作中可能会遇到的问题。

在现实世界中使用TDD

在使用TDD时,首先要考虑的是:既然商业产品是设计用来组织你的程序的,那么产品代码就应该很容易从代码中分离出来,以用来测试。在产品开发期间,你可以运行你的测试程序,而为了发布产品,你仍然能够轻易地将其从代码中移除。

你可能会遇到的另一个难题就是测试GUI 应用程序的困难,因为GUI 应用程序是被鼠标和键盘输入而驱动的。举例来说,你应该怎样写测试程序来激活用户点击dropdown list控件的事件呢?如果用户选择的是国名列表,那么又该怎样验证选中的内容呢?

解决这些问题的方案就是:将代码根据编译、测试和部署分类为不同的组件。举例来说,我们不应创建一个作为主应用程序的Quad类,生成相同的可执行文件;而应该允许这个类能够被包含在一个单独的库文件(.dll)中。[译注:实质就是将Quad 以类库的形式创建,而非应用程序。] 这样我们就可以开发单独的测试程序和域程序作为各自的可执行文件(.exe),并共享同一个包含Quad类的公共库文件(.dll)。注意,如果你仅仅创建了库,NUnit和你的测试包会被当作接口使用,而不是所需的单独的业务外观(separate harness)。

记住这个原则:“使主程序尽量简单,而将复杂的业务作为类放到库中”。它将帮助你解决测试GUI应用程序的问题。TDD的其中一个原则就是你不能测试第三方代码,因此你没有必要测试GUI 框架类,虽然当框架相对简单的时候,有时会用来测试接口。这意味着你可以捕捉类里的用户事件,因为你知道这个类是怎么工作的;然后再将其传递到类里进行处理。此外,你也可以将测试程序和域程序从单独的可执行文件中分离出来,而该执行文件则共享了你竭尽心力开发的公共库。

让我们看看怎样实际运用TDD来开发包含有Combobox控件的简单窗体应用程序。

本文系作者 问说网 授权问说网发表,并经问说网编辑,转载请注明出处和 本文链接

相关文章

  • 2015-01-22使用CSS3和JavaScript如何制作3D的云朵动画
  • 2015-07-28Uploader主题使用和服务端设置
  • 2015-12-26分享jQuery快速开发小技巧代码片段
  • 2017-01-19用JavaScript实现给出的盒子的序列是否可连为一矩型
  • 2016-12-02FlyJSONP轻量级的跨域AJAX请求插件
  • 2016-03-29详解Web中PJAX的实现与应用实例
  • 2016-04-02Webkit内核下的Mouseup后Mousemove自动触发问题及解决方法
  • 2016-05-14萌萌哒!教你用AI绘制一只打坐的可爱奶牛
  • 发布评论

    为您推荐

    用JavaScript实现给出的盒子的序列是否可连为一矩型
    AustenJuliet · 发布于 2017-01-19

    用JavaScript实现给出的盒子的序列是否可连为一矩型

    by cpglkg <script>var arr=[5,10,15];function rect(arr,width){ arr.sort(fun…

    问说网 · 发布于 2016-12-02

    FlyJSONP轻量级的跨域AJAX请求插件

    FlyJSONP是一个JavaScript库,用于实现跨域GET和POST请求服务,支持JSONP,并取得一个JSON格式的数据响应,这个Library具有易于…

    在Photoshop中创建绚丽的草木文字混合效果

    本次PS教程,主要向您展示“草木合成新颖视觉效果图”的制作过程,此次合成图片的制作将涉及到蒙板,图像调整,滤镜效果等工具,先来看看最终预览效果。

    • 在Photoshop中创建绚丽的草木文字混合效果
    • 在Photoshop中创建绚丽的草木文字混合效果
    • 在Photoshop中创建绚丽的草木文字混合效果
    • 在Photoshop中创建绚丽的草木文字混合效果
    问说网 · 发布于 2016-04-20 · 浏览 1589 · 评论 0

    大开眼界!20个炫酷好玩儿的网页导航设计

    今天CYHD给大家带来的是一些有趣的、创意类的导航设计,这些优秀的设计非常引人注目,令人难忘。这些网站的导航栏设计,比起传统的导航会相对更复杂一些,但是绝对会令…

    • 大开眼界!20个炫酷好玩儿的网页导航设计
    • 大开眼界!20个炫酷好玩儿的网页导航设计
    • 大开眼界!20个炫酷好玩儿的网页导航设计
    • 大开眼界!20个炫酷好玩儿的网页导航设计
    NancyDylan · 发布于 2016-05-14 · 浏览 1213 · 评论 0
    问说网 · 发布于 2016-12-02

    Response JS创建高性能的支持移动设备的网站

    Response JS 是一个轻量级的 jQuery 插件,用来创建高性能的支持移动设备的网站。它提供了一套语法用来根据不同的设备环境动态替换HTML代码。例如…

    问说网 · 发布于 2016-06-06

    PHP遍历目录的三种方法

    我们有时候需要读取目录里面的内容,在PHP有多个函数可以获取文件系统目录信息,今天就给大家分享PHP遍历目录的三种方法,对于上面提到的3个函数,对执行速度没有做…

    Vincent · 发布于 2016-07-06

    Java Web的安全验证机制

    部署描述符中的security-constraint元素允许不通过编程就可以限制对某个资源的访问。

    SVN
    Vincent · 发布于 2016-07-06

    SVN

    下载 Subversion(SVN服务端): 下载地址1 下载地址2 TortoiseSVN(SVN客户端): 下载地址1 下载地址2   安装 SV…

    问说网手机版

    躺着 站着 跪着轻松访问

    更多详情 关于作者

    问说网

    问说网分享与设计有关的文章素材界面和作品,提供设计教程、素材分享、界面欣赏、编程设计、设计书籍、设计师导航等内容,你可以在这里阅读、学习、分享、交流。

    13167 文章
    495 评论
    2068 人气

    更多 热门话题

    APP界面

    关注 APP界面

    文章 41506 · 浏览 3117

    APP欣赏

    关注 APP欣赏

    文章 41427 · 浏览 2883

    APP手机界面

    关注 APP手机界面

    文章 41417 · 浏览 3006

    图片素材

    关注 图片素材

    文章 29463 · 浏览 2418

    高清图片

    关注 高清图片

    文章 26530 · 浏览 2621

    更多 推荐作者

    关注 秋天的孤寂

    文章 99 · 评论 0

    关注 怎麽继续

    文章 90 · 评论 2

    关注 倾听寂寞

    文章 83 · 评论 0

    关注 溫柔的溫柔

    文章 91 · 评论 0

    关注 走了留下什么

    文章 110 · 评论 0

    关注 莪很迷茫

    文章 97 · 评论 0

    
    顶部 反馈 评论 底部

    意见反馈

    感谢您对问说网的支持,提出您在使用过程中遇到的问题或宝贵建议,您的反馈对我们产品的完善有很大帮助。

    您的反馈我们已收到!

    感谢您提供的宝贵意见,我们会在1-2个工作日,通过您留下的联系方式将处理结果反馈给您!