1.谁来阅读本文
使用watin做web页面的单元测试的开发人员,故
重点在于总结和分析实际使用中的问题以及资料的收集,而不是入门教程 :)
2. 官方网站
3.附件内容解释// 忽略我吧 呵呵
a.UnitTest.rar 为单元测试的示例解决方案
ConsoleApplication为控制台程序版本
WebApplication为web页面版本
POUnitTests为公安网办项目实际测试用例的部分示例代码,里面附有部分watin代码的使用说明,下面的主题会一一概述
b.watin相关软件及文档.rar
_WatinRecorder Setup Lite为自动记录工具,比较弱智,改进中
NUnit-2.4.0-r2-net-2.0为基于.net2.0的测试工具
HtmlElement_Mappings.xls为watin和页面控件的映射关系
IEDevToolBarSetup.msi为微软的ie开发帮助工作栏
WatiN-1.0.0.4000-net-2.0.zip为包含源码的watin
So have a fun~
让我们的思想改变世界 “)
让我们的思想改变世界 “)
--------------------------------------------------
常见问题的分析和解决方案
0.如何构建web单元测试
本质上为3步:
找到控件;触发事件;断言判断
如何覆盖功能点?
在已有的功能模块下,自己按照
测试的用例手册来细分功能点,每一个功能点用region块划分,各自实现自己的操作和验证
譬如:先把region的功能点覆盖到,注释好,再写实现过程和验证代码
[Test]
public void CreateCaseInfo()
{
#region 新建案件基本信息
#region 1.错误信息提示
//行政案件
//直接保存
Assert.IsTrue(ie.Html.Contains("请输入案件名称!"));
Thread.Sleep(1000);
#endregion
#region 2.时间控件验证
//1.填写必要信息,填错报案和发案时间
Assert.IsTrue(ie.Html.Contains("发案开始时间不能晚于报案时间"));
//2.填错发案时间
//发案开始时间迟于结束时间
Assert.IsTrue(ie.Html.Contains("发案结束时间不能晚于发案开始时间!"));
//3.填错发案时间
//发案结束时间迟于报案时间
Assert.IsTrue(ie.Html.Contains("发案结束时间不能晚于当前时间!"));
#endregion
#region 3.取消保存
//正确发案结束时间
//保存按钮
//弹出类似案件检查页面
Assert.IsFalse(ie.Html.Contains("保存成功!"));
#endregion
#region 4.成功保存
//保存按钮
Assert.IsTrue(ie.Html.Contains("保存成功!")); Assert.AreEqual("2007-03-29",ie.TextField("ctl00_MainContentPlaceHolder_FoldingPanel2_case_EditCtrl_caseInfo_EditCtrl_HappenTime_End_DTP_txtDate").Text);
Assert.AreEqual("陈永春", ie.TextField("ctl00_MainContentPlaceHolder_FoldingPanel2_case_EditCtrl_caseInfo_EditCtrl_HandleUserList_TB").Text);
#endregion
//给下一个测试方法预留反应时间
Thread.Sleep(1000);
#endregion
}
---------------------------------
1.ie.waitforcomplete 和 thread.sleep 的使用
上述的两个方法,用来等待ie的加载
watin的专门的waitforcomple通过侦探ie的busy和ready状态来判断,实际使用时候有自己的局限性
一般而言可以用ie.waitforcomplete来代替sleep,后来发现如果有类似AJAX postbacks之类的请求时,不是ie的状态能指出的,也即是ie.waitforcomplete失效,此时加上assert断言,页面加载并没有完成,必须手动来sleep足够的时间
譬如 Atlas UpdatePanel 控件,就必须sleep
当然,还有一个解决办法,就是在ajax之类的postback后,页面肯定存在或肯定不存在的控件的值或状态,譬如
- 1.look for an element that will exist after the "AJAX postback":
ie.Element(findBy).WaitUntilExists();
- 2. wait until an element does not exist anymore
ie.Element(findBy).WaitUntilRemoved();
- 3. wait until an element has a certain (known) value that indicates the "AJAX postback" has finished:
ie.Element(Find.ById("...") && Find.ByCustom("atributename","knownvalue").WaitUntilExists();
即将发布的1.1版本的解决方法:
ie.Element(Find.ById("...")).WaitUntil(Find.ByCustom("atributename","known value");
---------------------------
ie.Element(findBy).WaitUntilExists();
- 2. wait until an element does not exist anymore
ie.Element(findBy).WaitUntilRemoved();
- 3. wait until an element has a certain (known) value that indicates the "AJAX postback" has finished:
ie.Element(Find.ById("...") && Find.ByCustom("atributename","knownvalue").WaitUntilExists();
即将发布的1.1版本的解决方法:
ie.Element(Find.ById("...")).WaitUntil(Find.ByCustom("atributename","known value");
---------------------------
2 如果发现watin不支持的html标签时
例如 nobr ,可以自定义一个属性 new Attribute()
注意system也有这个System.Attribute,所以要加上全部的限定符
ElementCollection nobrElements = ie.Elements.Filter(new
WatiN.Core.Attribute("tagname", new
StringEqualsAndCaseInsensitiveComparer("nobr")));
//从控制台检查是否找到了对应的值
for(int i=0;i
Console.WriteLine(nobrElements[i].InnerHtml);
----------------------------------
3. 事件的精确控制
譬如当新开页面关闭自己并刷新父页面时候,新开的页面的“保存并关闭”按钮的前台事件可以简单的通过调用
similarSuspectIE.Button("ctl00_MainContentPlaceHolder_Save").FireEventNoWait("onclick");
FireEventNoWait会只触发指定元素的指定事件并忽略waitForComplete(该返回值在弹出窗口的处理上,没有考虑很周全),在面临开了2个以上新窗口,并依次关闭且刷新父页面的情况下,会让测试走过去 --!以往的测试策略无法走通
这个是公安网办 新建嫌疑人-->编辑 -->类似嫌疑人对比 ,然后关闭类似嫌疑人页面,自动关闭当前页面并依次刷新父页面碰到的问题
----------------------------------
4. confirm等modeless弹出窗口以及弹出的ie窗口的定位
confirm窗口:
//注册Confirm窗口处理方法
ConfirmDialogHandler deleteConfirm = new ConfirmDialogHandler();
ie.AddDialogHandler(deleteConfirm);
ConfirmDialogHandler deleteConfirm = new ConfirmDialogHandler();
ie.AddDialogHandler(deleteConfirm);
//删除按钮,弹出Confirm对话框
//出现Model类型对话框时候,如Confirm、Alert等,父窗口的按钮点击事件必须为ClickNoWait()
ie.Button("ctl00_MainContentPlaceHolder_FoldingPanel2_Delete_Button2").ClickNoWait();
//出现Model类型对话框时候,如Confirm、Alert等,父窗口的按钮点击事件必须为ClickNoWait()
ie.Button("ctl00_MainContentPlaceHolder_FoldingPanel2_Delete_Button2").ClickNoWait();
//确认删除
deleteConfirm.WaitUntilExists();
deleteConfirm.OKButton.Click();
deleteConfirm.WaitUntilExists();
deleteConfirm.OKButton.Click();
//有忽略弹出的Confirm引起的ie返回状态代码和平时不一致的作用
ie.WaitForComplete();
ie.WaitForComplete();
弹出新ie窗口的定位:
IE newIE= IE.InternetExplorers()[IE.InternetExplorers().Length - 1];