WatiN自动化测试
简介
WatiN - Watir的.NET版:
Welcome at the WatiN (pronounced as What-in) website.Inspired by Watir developmentof WatiN started in December 2005 to make a similar kind of Web ApplicationTesting possible for the .Net languages. Since then WatiN has grown into aneasy to use, feature rich and stable framework. WatiN is developed in C# andaims to bring you an easy way to automate your tests with InternetExplorer and FireFox using .Net.
目前最新版本:WatiN2.0 RC 1
http://watin.sourceforge.net/releasenotes-2-0-20-1089.html
支持的测试环境:
| Windows XP | Windows Vista | Windows 2003 | Windows 2008 |
IE 6 | OK | - | - | - |
IE 7 | OK | - | - | OK |
IE 8 | OK | - | - | - |
Firefox 2 | OK | - | - | - |
Firefox 3 | OK | - | - | OK |
WatiN 的脚本录制器 - WatiN Test Recorder:
http://watintestrecord.sourceforge.net/
2.0 beta版本需要IE7以上
WatiN vs. Selenium RC
Item | WatiN | Selenium RC |
Explorer Supported | Known work Ø IE 6 and IE 7 | Known work Ø IE 6 and IE 7 Ø Firefox 1.5.0 and 2.0 Ø Opera 8.5.4 and 9.0.2 Should work Ø Firefox 0.8 to 2.0 Ø Mozilla Suite 1.6+, 1.7+ Ø Sea monkey 1.0 |
System supported | Known work Ø Windows XP and 2003 | Known work Ø Windows XP and 2003 Ø Windows 2000(need to install install reg.exein order to use IE) Ø Mac OS X Ø Linux |
Language supported | Ø C# | Ø C# Ø Java Ø Perl Ø PHP Ø Python Ø Ruby |
Test environment supported | Ø Visual Studio 2005 Team System | Ø Visual Studio 2005 Team System |
AJAX | Supports AJAX website testing | l Selenium Server communicates directly with the browser using AJAX (XmlHttpRequest) l The Selenium Server is great for testing complex AJAX-based web user interfaces under a Continuous Integration system |
Get/Post requests |
| We can send commands directly to the Server using simple HTTP GET/POST requests |
Https supported |
| Support for https |
Javascrīpt Supported | Void Document.Runscrīpt(string) | l We can write selenium RC tests in Javascrīpt with JsUnit. l it Allows a Selenium-enabled browser to run Javascrīpt on arbitrary websites. |
HTML | Automates all major HTML elements and find elements by multiple attributes |
|
HTML dialogs | Supports HTML dialogs (modal and modeless) |
|
Frame | Supports frame (Cross domain) and iframes |
|
Popup dialogs | Supports popup dialogs like alert, confirm, login etc |
|
Screenshots | Support creating screenshots of web pages |
|
|
| 对现有控件的兼容性不好。比如文件上传控件和日历控件就无法在Selenium RC中捕捉 http://bbs.51testing.com/thread-84131-1-6.html |
Developing Info
Item | WatiN | Selenium RC |
Developing Language | Ø C# | Ø Java and so on |
Methods Example
Item | WatiN Example | Selenium RC Example |
Set element event | Document.button(Find.ById(btnG”)).click() | DefaultSelenium.Type(“q”,”hello world”) |
Get element attributes | Document.button (Find.ById(btnG”)).Style. Height | DefaultSelenium.GetElementHeight(“q”) |
especial methods |
Then we can’t hanle the time used for pages loading. ===》
Ø Link[1].Click() Ø Link(Find.ByIndex(1)).Click() We can use these two methods to click the links that the value is null. | Ø WaitForPageToLoad(“5000”) (if we want to go to another page and get the elements in the new page, we have to use the method, or we will in the old page.)
《== We can’t find the links that the value is null |
WatiN测试Google的例子
using System;
using System.Collections.Generic;
using System.Text;
using WatiN.Core;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
[STAThread]
staticvoid Main(string[]args)
{
//Open a new Internet Explorer window and
//goto the google website.
IEie = new IE("http://www.google.com.hk", true);
// Find thesearch text field and type Watin in it.
ie.TextField(Find.ByName("q")).TypeText("WatiN");
//Click the Google search button.
ie.Button(Find.ByValue("Google 搜索")).Click();
//Uncomment the following line if you want to close
//Internet Explorer and the console window immediately.
//ie.Close();
}
}
}
获取页面元素内容:
//Open an new Internet Explorer Window and
//goto the google website.
IEie = new IE("http://www.google.com.hk",true);
//Find the search text field and type Watin in it.
ie.TextField(Find.ByName("q")).TypeText("WatiN");
//Click the Google search button.
ie.Button(Find.ByValue("Google 搜索")).Click();
//Find the table cell which shows the search result statistics.
Elementelement = ie.Element(Find.By("id", "resultStats"));
stringresultStats = element.Text;
//Write these statistics to the console window.
Console.WriteLine(resultStats);
//Uncomment the following line if you want to close
//Internet Explorer and the console window immediately.
//ie.Close();
参考:
Getting started with WatiN
http://watin.sourceforge.net/gettingstarted.html
WatiN and Thread.ApartmentState
http://watin.sourceforge.net/apartmentstateinfo.html
WatiN支持的页面元素
Html element | WatiN Class | WatiN Collection | Example | Version |
|
|
|
|
|
<a /> | Link | LinkCollection | Ie.Link(linkId) | 0.7 |
<area /> | Area | AreaCollection | ie.Area(Find.ByAlt(alttext)) | 1.2 |
<button /> | Button | ButtonCollection | Ie.Button(buttonId) | 0.9 |
<div /> | Div | DivCollection | Ie.Div(divId) | 0.7 |
<form /> | Form | FormCollection | Ie.Form(formId) | 0.7 |
<frame /> | Frame | FrameCollection | Ie.Frame(frameId) | 0.7 |
<frameset /> | - | FrameCollection | Ie.Frames | 0.7 |
<iframe /> | Frame | FrameCollection | Ie.Frame(iframeId) | 0.9 |
<img /> | Image | ImageCollection | Ie.Image(imageId) | 0.7 |
<input type=button/> | Button | ButtonCollection | Ie.Button(buttonId) | 0.7 |
<input type=checkbox/> | CheckBox | CheckBoxCollection | Ie.CheckBox(checkboxId) | 0.7 |
<input type=file/> | FileUpload | FileUploadCollection | Ie.FileUpload(fileuploadId) | 0.9 |
<input type=hidden/> | TextField | TextFieldCollection | Ie.TextField(hiddenId) | 0.7 |
|
|
|
| no longer supported as of 2.0 beta 1 |
<input type=image/> | Image | ImageCollection | Ie.Image(imageId) | 0.9.5 |
<input type=password/> | TextField | TextFieldCollection | Ie.TextField(passwordId) | 0.7 |
<input type=radio/> | RadioButton | RadioButtonCollection | Ie.RadioButton(radioId) | 0.7 |
<input type=reset/> | Button | ButtonCollection | Ie.Button(resetId) | 0.7 |
<input type=submit/> | Button | ButtonCollection | Ie.Button(submitId) | 0.7 |
<input type=text/> | TextField | TextFieldCollection | Ie.TextField(textId) | 0.7 |
<label /> | Label | LabelCollection | Ie.Label(elementId) | 0.7 |
<option /> | Option | OptionCollection | Ie.Select(selectId).Options | 1.0 |
<p /> | Para | ParaCollection | Ie.Para(pId) | 0.7 |
<select /> | Select | SelectCollection | Ie.Select(selectId) | 0.7 |
<span /> | Span | SpanCollection | Ie.Span(spanId) | 0.7 |
<table /> | Table | TableCollection | Ie.Table(tableId) | 0.7 |
<tbody /> | TableBody | TableBodyCollection | Ie.TableBody(tablebodyId) Ie.Table(tableid).TableBodies | 1.0 |
<td /> | TableCell | TableCellCollection | Ie.TableCell(tablecellId) or Ie.Table(TableId).TableRows[0].TableCells[0] | 0.7 |
<textarea /> | TextField | TextFieldCollection | Ie.TextField(textareaId) | 0.7 |
<tr /> | TableRow | TableRows | Ie.TableRow(tablerowId) or Ie.Table(TableId).TableRows[0] | 0.7 |
All elements, also the ones not mentioned in this list | Element and ElementsContainer | ElementCollection | Ie.Element(elementId) Ie.Element(tagname, elementId) | 0.9
1.2 |
HTML Mapping Table
http://watin.sourceforge.net/htmlelementmapping.html
WatiN中所有的控件以及控件的识别方法
在WatiN的源代码中可以看到所有的控件识别设计类都是在继承了与element相关的类
包括Element,ElementAttributeBag, ElementCollection, ElementContainer, ElementSupport,ElementTag。
首先来看Element的类可以看到它继承IAttributeBag类,在Elemental类中写到的方法有:
1. Classname: Get the name of thestylesheet class assigned to this element;得到传输给此控件默认格式类的名称。返回值为string.
2. Complete: Boolean Value, Get a valueindicating whether the element is completely loaded;得到一个波尔值,查看是否此对当前控件的操作完全加载。返回值为波尔值.
3. Enabled: Get a Value indicating whetherthis element is enabled.得到一个波尔值来确认当前的控件是否是可用的.返回值为波尔值.
4. ID: Get the if of this element asspecified in the HTML ,返回当前控件在此HTML页面中的识别ID, 返回值为string。
5.TEXT: Get the inner text of thiselement(or all the inner text of all the elements contained in this elment). 返回当前控件中的文本,或者是返回当前控件所包含的控件中的所有文本,返回值为string.
6.TextBefore: Returns the text displayedbefore this element when it’s wrapped in a Label element, otherwise it returns null. 返回当前控件前面的Label的文本内容,如果当前控件前面的控件不是Label则返回null, 返回值为string.
7. InnerHtml: Gets the inner HTML of thiselement. 返回当前控件的内部HTML代码。返回值不用说当然为string.
8. OuterText: Gets the outer text, 返回外部文档,返回值为string.
Shit,这个控件我还真不知道怎么用,呵呵。查了一下解释如下:
InnerText:不包括标志,标志以内的纯文本
OuterText:包括标志,连标记及标志内的文本
InnerHtml:不包括标志,标志以内的Html内容
OuterHtml:包括标志,连标记及标志内的Html内容
9. TagName: Gets the tag name of thiselement 返回当前控件的标签。返回值为string.
10. Title: Get the title. 返回当前页面的标题。返回值为stieng.
11. NextSibling: Gets the next sibling ofthis element in the Dom of the HTML page.返回当前标签在此HTML页面Dom控件中的下一个兄弟控件。返回值为控件即(element)
12. PreviousSibling: Gets the previoussibling of this element in the Dom of the HTML page. 返回当前标签在此HTML页面Dom控件中的下一个兄弟控件,返回值为控件即(element)。
13. Parent: Gets the parent element of thiselement, If the parent type is known you can cast it to that type. 返回当前控件的父级控件,如果父级的控件类型知道,可以定义一个和父级同类型的变量控件。返回类型为控件(element).这个比较难理解,下面是举例:
Div
a id="watinlink" href="http://watin.sourceforge.net"/
ahref="http://sourceforge.net/projects/watin" /
Div
上面的HTML所示第二个超链接没有id,如何点击它来实现超链接?这时可以使用Parent这个方法:
首先定义一个变量Div,然后把这两个超链接所在的div赋值给这个Division变量。
DivwatinDiv = ie.Link(“watinlink”).Parent;
然后去找第二个Link, 可以把第一个Link看做是Links[0],那么第二个Link就是Link[1]
watinDiv.Links[1].Click();
14.Style: Style is the element’s style, 返回当前控件的格式。返回类型为Style.
15.GetAttributeValue: This method can beused is the attribute is not available as a property of the element of asubclass of the element. Need a parameter’attributeName’, this parameter shouldbe the name of the property exposed by IE on it’s element object. The return isthe value of the attribute if available, otherwise null is returned. 当控件的属性不存在或者或者属性属于此控件的一个子类时此方法可以使用。但是需要传递给此方法一个参数即属性名称(它应该是被IE暴露的一个空间实体),返回值为控件的属性值或者为null.
16. ToString: Returns a string thatrepresents the current object, or null.返回代表当前实体的值,如果没有则返回空。返回类型为string.
17.Click: Click this element and waits tillthe event is completely finished(Page is loaded and ready). 点击当前控件然后等待,知道整个事件完成即:页面被完全加载。无返回值.
18.ClickNoWait: Click this instance andreturns immediately. Use this method when you want to continue without waitingfor the click event to be finished. Mostly used when a HTML Dialog is displayedafter clicking the element. 触发事件并立刻返回信息然后去判断需要如何执行,通常是在点击或者跳转页面还没完成时你需要其它操作。一般情况下是在当弹出对话框时使用这个方法。无返回值。
19.Focus: Gives the input focus to thiselement. 聚焦在当前这个输入控件,我不是很明白这个方法。无返回值。
20.DoubleClick: Doubleclicks this element. 双击当前的控件。无返回值。
21.KeyDown, KeyPress, KeyUp 三个方法分别为按下键盘不放, 按一下键盘,和松开按键盘。很绕口. 这个应该是从.Net继承的。
22. Blur: Fires the blur event on thiselement. 这个应该是和focus相反的方法。取消对这个控件的focus.
QTP + WatiN
Set IE =DotNetFactory.CreateInstance("WatiN.Core.IE","C:\Documents andSettings\Administrator\桌面\WatiN-2.0.10.928-net-2.0\WatiN-2.0.10.928-net-2.0\bin\WatiN.Core.dll")
SetFind=DotNetFactory.CreateInstance("WatiN.Core.Find","C:\Documentsand Settings\Administrator\桌面\WatiN-2.0.10.928-net-2.0\WatiN-2.0.10.928-net-2.0\bin\WatiN.Core.dll")
IE.GoTo("http://www.zbitedu.com")
IE.WaitForComplete
IE.TextField(Find.ByName("searchkey")).TypeText("vbs测试webservice")
IE.Button(Find.ByName("subjectsearch")).Click()
Set IEpage = IE.AttachToIE(Find.ByUrl("http://www.zbitedu..com"))
Set LinkObj = IEpage. Link(Find.ByUrl("http://www.zbitedu.com/)
IF LinkObj.Exists Then
LinkObj.Click()
' IE.AttachToIE(Find.ByUrl("http://www.zbiteducom)
Set ConsoleObj=DotNetFactory.CreateInstance("System.Console","System")
Consoleobj.Write("PASS")
' Msgbox("PASS")
else
Msgbox("FAILL")
End If
IE.Close
IEpage.Close
IE.AttachToIE(Find.ByUrl("http://www.zbitedu.com).Close
WatiN中常用的类
WatiN.Core.Find
最普遍使用的类就是Find类的,它是一个工厂类,主要使用它的静态方法来实现一些查询条件。比如像上面的例子中的这个语句“ie.Button(Find.ByName("btnG")).Click();”就调用了Find的静态方法ByName来查询一个name属性为指定值的HTML元素,然后再调用IE对象的Button方法把这个元素转换为按钮对象。
WatiN.Core.IE
这应该是最关键的类了。他常用的方法是和属性为
属性
HtmlDialogs 返回当前对象用JavaScript打开的模式窗口(需然帮助文档中说非模式窗口也包括在内,但在试用中发现用window.open打开的窗口没有被)
Frames 返回当前的象里的所有Frames
方法
静态方法 AttachToIE 与一个已经找开的IE关连。
Button,TextField,Image,Div 等一系列方法。与Find对象共同使用用于返回IE中特定的按钮,输入框,等HTML元素。
WatiN应用中的一些技巧
1、如何去捕获一个新弹出的窗口。
背景:有些链接是从一个新弹出的窗口中打开的,我如果关连上这类型的窗口。
方案:下面以一个具体例子为例。系统中有一个登陆界面:login.aspx 登陆成功能后会调用JAVASCRIPT的window.open方法打开系统的主窗口,然后关闭当前这个窗login.aspx。
刚开始时,我的代码是这样写的
public void Login(string uid, stringpasswd)
{
string url = Host +"login.aspx";
ie = new IE();
ie.GoTo(url);
ie.WaitForComplete();
ie.TextField(Find.ById("txtUserName")).Value= uid;
ie.TextField(Find.ById("txtPwd")).Value = passwd;
ie.Button(Find.ById("btnLogin")).Click;//注意这里,我每次执行到这里都出错。下面会说明原因。
ie =IE.AttachToIE(Find.ByTitle(new WatiN.Core.Comparers.RegexComparer(newSystem.Text.RegularExpressions.Regex(".*综合信息系统.*"))));
ie.WaitForComplete();
MainFrame =ie.Frame(Find.ByName("MainFrame_00001"));
MenuFrame =ie.Frame(Find.ById("leftMenu"));
}
看到上面的注译没有?那么执行完后WatiN都会出现一个等待完成超时的异常,这是因为点击了登陆按钮后,如果登陆成功的话,系统已经把这个窗口关闭了,因为它根本不可能完成。呵呵~~```所以要修改一下。
public void Login(string uid, stringpasswd)
{
string url = Host +"frmlogon.aspx";
ie = new IE();
ie.GoTo(url);
ie.WaitForComplete();
ie.TextField(Find.ById("txtUserName")).Value = uid;
ie.TextField(Find.ById("txtPwd")).Value = passwd;
ie.Button(Find.ById("btnLogin")).ClickNoWait();//这个方法改成这样,那点击后就不会等代码IE完成了。
//下面这句就是处理登陆的技巧所在,系统打开了另一个窗口。
//下面这句就是用正则表达式捕获这个窗口。
ie =IE.AttachToIE(Find.ByTitle(new WatiN.Core.Comparers.RegexComparer(newSystem.Text.RegularExpressions.Regex(".*综合信息系统.*"))));
ie.WaitForComplete();
MainFrame = ie.Frame(Find.ByName("MainFrame_00001"));
MenuFrame =ie.Frame(Find.ById("leftMenu"));//把系统里的Frame先保存下来。
}
2、对于alert 、confirm 等javascript弹出的窗口的捕获。
背景:一个系统经常会使用以上这些javascript来弹出一些提示信息,如果捕获这些窗口,并模拟用户点击这些窗口上的OK或Cancel按钮?
方案:其实WatiN在默认情况下,都会自动地去点击这些弹出式窗口上的Cancel按钮的,但如果用户要明确点击哪些事件的话可以对IE对象增加一个“查看器”()
//错误事例
protected void f()
{
WatiN.Core.DialogHandlers.ConfirmDialogHandler dh = newWatiN.Core.DialogHandlers.ConfirmDialogHandler();
ie.AddDialogHandler(dh);//这句增加了一个控制器
/**/
/*
假设yzp_dic_btn_cls这个按钮的onclick事件会用JS弹出一个Confirm窗口。
错误,测会在这里弹出一个窗口,然后等待用户进行操作(随便点击一个按钮才继续执行)
然后因为用户已经点击了按钮关闭 弹出窗口。下一句的dh.WaitUntilExists(3);将会超时,抛出异常
*/
doc.Button(Find.ByName("yzp_dic_btn_cls")).Click();
dh.WaitUntilExists(3);//等待弹出窗口的出来。最多等三秒。
dh.OKButton.Click();//点击这个窗口的OK按钮
ie.RemoveDialogHandler(dh);
doc.Button(Find.ByName("btn_close")).Click();
}
正确的示例应该是:
protected void f()
{
WatiN.Core.DialogHandlers.ConfirmDialogHandler dh = newWatiN.Core.DialogHandlers.ConfirmDialogHandler();
ie.AddDialogHandler(dh);
doc.Button(Find.ByName("yzp_dic_btn_cls")).ClickNoWait();//把原来的Click改成这个方法。
dh.WaitUntilExists(3);//等待弹出窗口的出来。最多等三秒。
dh.OKButton.Click();//点击这个窗口的OK按钮
ie.RemoveDialogHandler(dh);
doc.Button(Find.ByName("btn_close")).Click();
}
3、关于用JS弹出的Modal窗口(模式窗口)的处理.
背景:有些地方需要弹出模式窗口来处理数据。
方解:当点击了弹出模式窗口的按钮或连接后马上用IE对像的HtmlDialogs属生来获取模式窗口。
protected void f()
{
//假设下面这行代码会弹出一个模式窗口把原来的Click改成这个方法。
//记住这里要用ClickNoWait而不能用Click,否则在模式窗口关闭之前代码不会继续执行。
ie.Button(Find.ByName("yzp_dic_btn_cls")).ClickNoWait();
ie.HtmlDialogs[ie.HtmlDialogs.Length -1].TextField(Find.ByName("Q")).Value = "Hello";
ie.HtmlDialogs[ie.HtmlDialogs.Length -1].Button(Find.ByName("btn_query")).Click();
}
WatiN插件 – QAliber
http://www.qaliber.net/Wiki/index.php?title=WatinN_Plug-in
Qaliber主页:
作者:BennyCohen
包括两个版本,其中QAliberTest Developer版本作为VS.NET的插件使用:
QAliber Test Developer (free open source) is a VisualStudio plug-in.
Create test cases as an integral part of yourdevelopment solution.
QAliber Test Builder (free open source) is a robust testingframework for creating and executing tests with no coding skills.
TestAndTry.com对这款工具的评价是“VeryFast GUI Automation With Free QAliber”:
http://www.testandtry.com/2010/03/04/very-fast-gui-automation-with-free-qaliber/
主要特点:
Create test cases as an integral part of yourdevelopment solution.
Create GUI / API level test quick!
Record / Play GUI automation.
Supports Win32 / .NET forms / WPF / WEB GUI testing.
Run on all windows platforms with .NET framework 3.0and up (XP,Vista,Win 7)
Write C#/VB.net code, use the .NET frameworkcapabilities.
下载地址:
http://sourceforge.net/projects/qaliber/files/