著名的NUnit是单元测试的优秀工具,但是要在一个测试方法中启动GUI程序,比如Windows Form界面,这比较难做到。NUnitForms就是为解决这个问题产生的,它是NUnit的一个扩展程序,可用于测试Windows Forms 类型的程序。

首先从NUnitForm网站下载安装程序,地址是 http://nunitforms.sourceforge.net/index.html,并执行安装。

在VS2010中新增一个测试项目,添加对两个程序集NUnit.Framework和NUnit.NunitForms引用,添加新测试类型:

using NUnit.Framework;
using NUnit.Extensions.Forms;

Namespace yourTestSuiteNameSpace
{
[TestFixture]
public class myGUITests : NUnitFormTest
… }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果要显示GUID,则测试类型应该继承于NUnitFormTest, 添加TestFixture特性,再添加一个Test方法:

[Test]
pubilc void ShowDilalogTest()
{
Form dlg=new Form();
dlg.Show();
}
 
 

启动GUI界面

如果您的Visual Studio已经安装了Resharper插件,则可以直接点击被测试方法的签名地方,选择调试或是运行测试,上面的测试方面会显示一个GUI界面,关闭窗体,测试完成。

也可以用窗体实例的ShowDialog 方法调出界面,显示为
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }个model对话框。

 

引用控件

如果要引用被测试窗体中的控件,命名空间NUnitForms 中有一些以Tester类型结尾的类型可供使用。这些类型继承于ControlTester ,可以用ControlTester 来测试控件,也可以用它的派生类型。

以ControlTester类来测试任何控件,可以像这样通过属性的索引来访问它的属性.

ControlTester textBox = new ControlTester("nameOfSomeTextBox");
Assertion.AssertEquals("defaultText", textBox["Text"]);
textBox["text"] = "newText";

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

尝试使用FireEvent方法来触发控件的一个事件:

ControlTester button = new ControlTester("nameOfSomeButton");
button.FireEvent("Click");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

比如,为了引用窗体MyFormName类型中的button1的按钮,可以下面的方法引用此控件:

ButtonTester buttonTester = new ButtonTester("button1", "MyFormName");
 

如果你省略了"formName"参数, NUnitForms将在所有打开的Form中查找控件。

对于Panel控件,要引用它的子控件,可参考下面的写法,以逗号分隔多个名称:

 CheckBoxTester uncheckBoxTester = new CheckBoxTester( "aPanelName.checkBoxName", "MyFormName");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 RadioButtonTester radioTester = new RadioButtonTester("mainFormControlName.panelName.radioButtonName",  "MyFormName");

如果NUnitForms找不到你的控件, 会抛出一个NoSuchControlException异常. 如果控件的名称没有资格使它成为一个唯一命名的控件, 将会被抛出AmbiguousNameException异常.

对于层层嵌套控件的命名,请参考下面的例子

 

控件的命名

NUnitForms通过控件的Name属性来查找你要测试的控件. 如果在一个form中有多个相同名称的控件, 那么他们必须像下面这样进行限定:

Form

  PanelA

    UserControl1

      Button           (PanelA.UserControl1.Button)  
    UserControl2

      Button           (UserControl2.Button)

  PanelB

    UserControl1

      Button           (PanelB.UserControl1.Button)

 

Model/Modeless Dialog 模式窗体/非模式窗体

当测试窗体时,如果这个窗体要调出子窗体或是调出对话框,这时需要把窗体的测试逻辑放到一个public void签名的方法中,并用ExprectModel指定方法名称:

[Test]
public void TestOKButtonTest()
{
ExpectModal("FormName", "formNameHandler");
FormName form = new FormName();
form.ShowDialog();

public void formNameHandler ()
{
ButtonTester buttonTester = new ButtonTester("okButton", " FormName");
// Check the OK button's text and then click it
Assert.AreEqual("OK", buttonTester.Text, "FormName’s OK button text is wrong '" + buttonTester.Text + "'");
buttonTester.Click();
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

测试时,如果要调出message box,请参考下面的写法

ExpectModal("messageBoxCaption", "messageBoxClickerMethod");

 

多线程测试
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果运用到多线程测试窗体,应该像下面的例子一样,注册一个委托类型,把测试代码放到该方法中

 public void genericFormHandler()
{
// Do nothing in this method!
}

[Test]
public void MainFormTest()
{

MainGUIForm mainForm = new MainGUIForm();
mainForm.OnFormReady += new EventHandler<EventArgs> (mainFormTestLogic);
ExpectModal("MainGUIForm", "genericFormHandler");
mainForm.ShowDialog();

}
public void mainFormTestLogic (object sender, EventArgs e)

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

目前可以下载到的版本是NUnitFormsV2.0.0.5 alpha4。

 

单元测试的目的是改善代码

既然可以调出窗体,就可以测试自定义控件,这是一种测试自定义控件的好方法。

测试项目与Resharper配合起来,很容易启动,调试,修改,这样做单元测试,才是有益于改善代码的测试。

NUnitForms 测试GUI应用程序的优秀工具的更多相关文章

  1. AutoIT 测试GUI工具

    今天听到同事提到AutoIT,可以用来测试GUI窗口.了解一下这个工具. 以下内容引自: http://www.jb51.net/article/14870.htm (此url非原出处,该博主未注明原 ...

  2. 小程序入口构造工具&二维码测试工具

    小程序入口构造工具&二维码测试工具 本文将介绍我们小程序中隐藏的两个工具页面.原理虽不复杂,收益却实实在在,或许也能给诸君带来启发. 入口构造工具 痛点 PM&运营 投放链接 PM&a ...

  3. 转: GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

    十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...

  4. GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

    十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...

  5. 优秀工具推荐:超实用的 CSS 库,样板和框架

    当启动一个新的项目,使用 CSS 框架或样板,可以帮助您节省大量的时间.在这篇文章中,我编译整理了我最喜欢的 CSS 样板,框架和库,帮助你在建立网站或应用程序时更加高效. 您可能感兴趣的相关文章 精 ...

  6. [原创]推荐一款强大的.NET程序内存分析工具.NET Memory Profiler

    [原创]推荐一款强大的.NET程序内存分析工具.NET Memory Profiler 1 官方网站:http://memprofiler.com/2 下载地址:http://memprofiler. ...

  7. 十大PHP程序员必备工具

    十大PHP程序员必备工具 1.Notepad++ 总结来说就是小而精,7.4版本的软件包只有2.9M,比一般的IDE小数十倍,但是Notepad++的功能确是很全面的,代码高亮,语法折叠,宏功能,内置 ...

  8. Java程序性能定位工具-火焰图

    Java程序性能定位工具-火焰图 前言 Java火焰图是一种新的查看CPU利用率方式.今天就带大家一起使用来自Google大神的工具来生成火焰图.火焰图非常的直观,问题一目了然,希望有一天它能成为JA ...

  9. 程序开发入门工具之CodeBlocks

    程序开发基础工具之CodeBlocks 作为程序开发工作者,我们会接触很多的程序开发软件:但实用以及容易掌握的程序开发软件对于初学者的学习能力是有一定的加成的.今天我就作为一个程序开发者给大家推荐一个 ...

随机推荐

  1. SQL获取所有数据库名、表名、储存过程以及参数列表

    SQL获取所有数据库名.表名.储存过程以及参数列表 1.获取所有用户名:SELECT name FROM Sysusers where status='2' and islogin='1'islogi ...

  2. 高并发访问mysql时的问题(一):库存超减

    如果在对某行记录的更新时不采取任何防范措施,在多线程访问时,就容易出现库存为负数的错误. 以下用php.mysql,apache ab工具举例说明: mysql表结构 CREATE TABLE `yx ...

  3. var关键字详解

    1,var只能定义局部变量,而不能定义成员变量 2,定义的时候必须同时完成初始化,而不能使用var定义变量为null 3,var本身不是一个新类型,只是用来修饰一个可以推断出具体类型的局部变量 var ...

  4. jsp页面不能使用EL表达式

    在页面中添加 <%@ page isELIgnored = "flase" %>

  5. 1201新课程TSQL语句

    1.创建数据库 create datebase 表名称 2.删除数据库 drop datebase 表名称 3.创建表 -create table test(表名称)( code(列名称) varch ...

  6. C# 特殊处理使用方法

    1.时间处理 Model.PiDaiTime.ToString("yyyyMMdd") == "00010101" ? DateTime.Now.ToStrin ...

  7. centos 6.5 + php5.5.31 fastcgi (fpm) 编译安装

    yum intsall zlib zlib-devel //gzip 压缩和解压 yum install openssl openssl-devel yum install libxml2 libxm ...

  8. Ubuntu12.04配置mod_python

    安装: sudo apt-get install libapache2-mod-python python-mysqldb 然后编辑配置文件/etc/apache2/sites-enabled/000 ...

  9. [转] 基于ArcGISServer实现活动地图标注

    ——王嘉彬(Esri中国上海分公司) 1.背景 1.1.主流互联网地图应用的现状 在目前主流的互联网地图应用中,如 Google Map(图 1).搜狗地图(图2),POI 兴趣点的文字标注越来越多的 ...

  10. [f]区间随机数函数

    $.r = function(i, g) { var j = Math.random(), h = arguments.length; return h == 2 ? (i + Math.floor( ...