转载地址:http://www.oschina.net/question/12_252

引言

单元测试是应用程序设计的一个重要部分,它可应用于程序的多个层次。本文将主要关注用户界面层的单元测试。我们将使用WatiN 测试ASP.NET应用程序。

什么是WatiN?

WatiN 是一个源自Watir的工具,用于测试Web页面。WatiN表示Web Application Testing in .NET。

我们要测试什么?

在本文中我们将测试一个简单的ASP.NET页面,用这个页面来演示认同、接受(agreement acceptance)的场景。用户在文本框中输入名字,点击“I agree”复选框,然后按下submit按钮。这显然是一个非常简单的页面,在你熟悉了WatiN框架的工作机制后,就可以将这里的理念用于大型页面的 测试了。

这里是待测页面的截图:

测试认同(Agreement)页面:

向解决方案添加一个类库项目,并为其添加对测试工具(我这里用的是MbUnit,但你完全可以使用NUnit或VSTS的测试项目)和WatiN库的引用。你可以在这里下载WatiN。

下面的测试代码用来确保用户已经认同。

[TestFixture(ApartmentState = ApartmentState.STA)]
public class TestAgreementPage
{
    [Test]
    public void TestCanAcceptUserAgreement()
    {
        IE ie = new IE(ConfigurationManager.AppSettings["DefaultPageUrl"]);
        ie.TextField("txtName").TypeText("Mohammad Azam");
        ie.CheckBox("chkAgree").Checked = true;
        ie.Button("btnAgree").Click();
 
        Assert.AreEqual("Valid", ie.Span("lblMessage").Text);
    }
}

这个类有TestFixture特性(Attribute),STA值确保该测试运行于STA(Single Threaded Apartment)状态下。这是因为测试代码要加载IE。

WatiN中的IE类完成了主要工作。IE类打开IE,通过name或id来引用html控件。这一行ie.TextField("txtName").TypeText("Mohammad Azam"), 引用了id为“txtName”的文本框。浏览器加载后,WatiN会将值“Mohammad Azam”写入id为“txtName”的文本框。这个过程在测试时你会看到的。然后id为“chkAgree”的复选框会被选中。最后,WatiN会按 下提交按钮,窗体被提交。

运行测试,失败。因为名为“lblMessage”的Label从未被赋值为“Valid”。加上这段代码:

protected void btnAgree_Click(object sender, EventArgs e)
{
    lblMessage.Text = "Valid";
}

现在,如果你运行测试它会通过。但是,好像不太正确。如果我们把这一行测试代码删掉:

ie.CheckBox("chkAgree").Checked = true;

再次运行测试,依然能通过。这可不对!应当只有在CheckBox选中时才可通过。将页面的Code behind代码改一下。

protected void btnAgree_Click(object sender, EventArgs e)
{
    if (chkAgree.Checked)
    {
        lblMessage.Text = "Valid";
    }
}

现在,测试只有在CheckBox选中时才可通过了。

以编程方式运行Web服务器:

在上例中我们需要运行WebServer,要么是通过命令行工具,要么是通过运行Web项目。但有时我们需要单元测试项目能够动态打开一个WebServer。一起来看看。

首先,如果你需要打开ASP.NET内部服务器(WebDev.WebServer),可以使用命令行。语法如下:

WebDev.WebServer.exe /port:1950 /path:"C:\Projects\MyWebApplication"

需要定位到WebDev.WebServer所在的目录,默认情况下它在:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe

好了,现在来看看如何在单元测试中打开服务器。首先,添加必要的配置(App.config中)。

<configuration>
    <appSettings>
        <add key="WebServerExePath" value="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe"/>
        <add key="Port" value="4463"/>
        <add key="WebApplicationPath" value="c:\projects\demowatiN\demowatiN" />
        <add key="DefaultPageUrl" value="http://localhost:4463/Default.aspx" />
    </appSettings>
</configuration>

BaseTestPage类可以通过这些信息运行服务器,所有继承了它的测试类都可以使用这个功能了。

下面是BaseTestPage类的完整代码:

public class BaseTestPage
{
    static Process server = null;
 
    static BaseTestPage()
    {
        if (Process.GetProcessesByName("WebDev.WebServer").Length == 0)
        {
            string webServerExePath = (string)ConfigurationManager.AppSettings["WebServerExePath"];
            server = new Process();
            Process.Start(webServerExePath, GetWebServerArguments());
        }
    }
 
    public static string GetWebServerArguments()
    {
        string args = String.Format("/port:{0} /path:\"{1}\"", GetPort(), GetWebApplicationPath());
        if (String.IsNullOrEmpty(args)) throw new ArgumentNullException("Arguments is not defined");
        return args;
    }
 
    public static string GetPort()
    {
        string port = ConfigurationManager.AppSettings["Port"] as String;
        if (String.IsNullOrEmpty(port)) throw new ArgumentNullException("Port is null or empty");
 
        return port;
    }
 
    public static string GetWebApplicationPath()
    {
        string webApplicationPath = ConfigurationManager.AppSettings["WebApplicationPath"] as String;
        if (String.IsNullOrEmpty(webApplicationPath)) throw new ArgumentNullException("WebApplicationPath is null or empty");
 
        return webApplicationPath;
    }
}

如果服务器没有运行,我们会新建一个进程运行它,否则就使用已有的进程。GetWebServerArguments()、GetPort()和GetWebApplicationPath()仅仅是辅助方法,可以提高可读性。

最后,你可以让单元测试类继承该类:

public class TestAgreementPage : BaseTestPage

现在,运行单元测试项目时,它会运行WebServer,然后再执行所有测试。

结论:

在本文中,我们学习了如何对用户界面层进行单元测试,这些测试可帮助我们理解UI的需求,并快速地看到基于用户输入所得到的结果。而如果手动进行测试,就要花费很多时间了。

源码:点击这里

转载于:https://www.cnblogs.com/lianou2009/archive/2012/04/28/2475052.html

【转载】使用WatiN对ASP.NET页面进行单元测试相关推荐

  1. 在ASP.NET页面中实现数据饼图(转载)

    ASP.NET之所以能够在客户端浏览器中形成各种数据图片,是因为在ASP.NET中提供了绘图功能,具体的作法是先在服务器端创建一个Bitmap实例,然后利用ASP.NET中提供的绘图功能,按照要生成的 ...

  2. [转]ASP.NET页面生命周期描述

    ASP.NET页面生命周期描述 vigorID:Vigorcsdn 在以前写个一篇关于ASP.NET页面生命周期的草稿,最近又看了看ASP.NET,做个补充,看看页面初始过程到底是怎么样的 下面是AS ...

  3. ASP.NET页面缓存介绍

    尽管本文的作者写的很简单,但是相信通过这些文字,还是能对大家了解ASP.NET页面缓存有很大的帮助. 前几天遇到个问题,百思不得其解.后来查阅了一些资料心里才有了点思路.把自己遇到的问题记录下来希望能 ...

  4. 利用EntLib授权机制实现对ASP.NET页面的自动授权

    ASP.NET默认采用UrlAuthorizationModule和FileAuthorizationModule分别实现针对请求地址和物理文件的授权,但是在很多情况下我们需要额外的授权方式.Entl ...

  5. ASP.NET页面的生命周期

    当一个获取网页的请求(可能是通过用户提交完成的,也可能是通过超链接完成的)被发送到Web服务器后,这个页面就会接着运行从创建到处理完成的一系列事件. ASP.NET页面初始的过程: 1.Page_In ...

  6. 如何在asp.net页面使用css和js

    一.如何在asp.net页面中使用css 1.可以直接写在需要样式控制的控件里  例如:<div style="border:#ff6100 1px solid">&l ...

  7. 技巧:Silverlight应用程序中如何获取ASP.NET页面参数

    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://terrylee.blog.51cto.com/342737/87093 ...

  8. JavaScript 与 ASP.NET 页面的完美结合(转)

           ASP.NET提供了一个强大的开发平台,但是一些已经很成熟的技术你也不要忽略,例如像JavaScript这样的技术,本文笔者将向您讲解如何将JavaScript代码联结到ASP.NET控 ...

  9. 【转】Asp.net页面的生命周期

    介绍 Asp.net是微软.Net战略的一个组成部分.它相对以前的Asp有了很大的发展,引入了许多的新机制.本文就Asp.net页面的生命周期向大家做一个初步的介绍,以期能起到指导大家更好.更灵活地操 ...

最新文章

  1. 使用Spring框架实现远程服务暴露与调用
  2. 临床观察性研究论文如何撰写“方法”?
  3. 华为鸿蒙发布会新手机,曝华为 P50/Pro 系列最终版确定,6 月 2 日揭晓鸿蒙手机发布时间...
  4. 周鸿祎称不理解35岁程序员被「抛弃」,网友:你招吗?
  5. freemark循环map_java与freemarker遍历map
  6. 如何获取e.printStackTrace()的内容
  7. 【数据结构算法】一:线性表
  8. 在Java中如何遍历Map对象
  9. 刚才读《基于Lucene的中文自然语言搜索引擎》后感
  10. java 语音发声_单词打字练习java程序(发音、朗读)
  11. Java word转pdf字体格式和样式变乱的问题
  12. 蓝牙解码格式哪个最好_拆解报告:山灵UP2 蓝牙音频接收器
  13. Git官网下载文件提示无法访问此网站的解决办法
  14. L1-078 吉老师的回归 (15 分) C语言
  15. 【GetFeature】返回来自数据源的特征选择,包括几何和属性值
  16. html网站设计基础
  17. android 陀螺仪源码,陀螺仪源码 android
  18. txt文本文件数据转ArcGIS中的tif文件
  19. 拿到一个网站,怎么判断该网站是否存在sql注入漏洞?
  20. Golang for循环

热门文章

  1. Intellij关闭自动更新
  2. sqoop把mysql数据导入hive
  3. mysql优化积累(持续更新中)
  4. linux运行星际争霸1
  5. 下采样downsample代码
  6. 红黑树 删除某节点后 旋转3次 举例
  7. springboot连接SQL数据库配置application
  8. php调用linux摄像头,Linux_在Linux操作系统上使用摄像头,我的公家笔记本的摄像头一直 - phpStudy...
  9. cytoscape使用方法_7种方法 ,订制你的专属venn图!-代谢组学/蛋白组学研究
  10. Shell脚本自动备份数据库