博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《软件测试自动化之道》读书笔记 之 底层的Web UI 测试
阅读量:5784 次
发布时间:2019-06-18

本文共 15258 字,大约阅读时间需要 50 分钟。

《软件测试自动化之道》读书笔记 之 底层的Web UI 测试

2014-09-28

 
 
 
 
 
 

测试自动化程序的任务

底层技术的核心是,通过直接调用mshtml.dll和shdocvw.dll库来访问并且操纵IE客户区域的HTML对象。

待测程序

新建一个网站“WebAUT”,删除原来的Default.aspx,创建一个新的Default.aspx。在其中添加3个Label控件、2个RadioButton控件、1个TextBox控件、1个Button控件和1个ListBox控件。

图1 Web UAT

待测程序代码:

1 using System; 2 using System.Collections.Generic; 3  4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7  8 public partial class _Default : System.Web.UI.Page 9 {10     private System.Collections.ArrayList al = new System.Collections.ArrayList();11     protected void Page_Load(object sender, EventArgs e)12     {13         Product p1 = new Product("widgets", "1A11A", 11.11);14         Product p2 = new Product("gadgets", "2B22B", 22.22);15         Product p3 = new Product("foozles", "3C33C", 33.33);16 17         al.Add(p1);18         al.Add(p2);19         al.Add(p3);20         Label3.Text = "Search Complete";21         Label3.Visible = false;22     }23     protected void Button1_Click(object sender, EventArgs e)24     {25         ListBox1.Items.Clear();26         string filter = TextBox1.Text;27         ListBox1.Items.Add("ProdName ProdID Price");28         ListBox1.Items.Add("=====================");29 30         if (RadioButtonList1_1.Checked)31         {32             foreach (Product p in al)33             {34                 if (p.name.IndexOf(filter) >= 0)35                     ListBox1.Items.Add(p.name + ", " + p.id + ", " + p.price);36             }37         }38         else if (RadioButtonList1_2.Checked)39         {40             foreach (Product p in al)41             {42                 if (p.id.IndexOf(filter) >= 0)43                     ListBox1.Items.Add(p.name + ", " + p.id + ", " + p.price);44             }45         }46         Label3.Visible = true;47     }48 49     public class Product50     {51         public string name;52         public string id;53         public double price;54         public Product(string name, string id, double price)55         {56             this.name = name;57             this.id = id;58             this.price = price;59         }60     }61 }
View Code

测试程序

启动IE并连接到这个实例

1         static void Main(string[] args) 2         { 3                 //... 4  5                 SHDocVw.InternetExplorer ie = null; 6                 Console.WriteLine("\nLaunching an instance of IE"); 7                 Process p = Process.Start("iexplore.exe", "about:blank"); 8                 System.Threading.Thread.Sleep(2000); 9                 if (p == null)10                     throw new Exception("Could not launch IE");11                 Console.WriteLine("Process handle = " + p.MainWindowHandle.ToString());                12 13                 SHDocVw.ShellWindows allBrowsers = new SHDocVw.ShellWindows();14                 Console.WriteLine("Number active browsers = " + allBrowsers.Count);15 16                 if (allBrowsers.Count == 0)17                     throw new Exception("Cannot find IE");18 19                 Console.WriteLine("Attaching to IE");20                 int i = 0;21                 22                 while (i < allBrowsers.Count && ie == null)23                 {24                     InternetExplorer e = (InternetExplorer)allBrowsers.Item(i);25                     if (e != null)26                     {27                         if (e.HWND == (int)p.MainWindowHandle)28                             ie = e;                       29                     }30                     ++i;31                 }32 33                 if (ie == null)34                     throw new Exception("Failed to attach to IE");35 36                 //...37         }
View Code

如何判断待测web程序完全加载到浏览器

1         static void Main(string[] args) 2         { 3                 SHDocVw.InternetExplorer ie = null; 4                 //把ie对象连接到IE程序所在的进行 5  6                 ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete); 7  8                 Console.WriteLine("\nNavigating to the Web app"); 9                 object nil = new object();                10                 ie.Navigate("http://localhost:30614/WebAUT/Default.aspx", ref nil, ref nil, ref nil, ref nil);            11 12                 documentComplete.WaitOne();13 14                 //...15         }16         private static void ie_DocumentComplete(object pDisp, ref object URL)17         {18             documentComplete.Set();19         }
View Code

测试程序有可能在待测程序尚未完全加载的情况下试图对其进行操作,这么做,很可能引发异常。测试程序可通过事件DocumentComplete和AutoResetEvent类,对自动化程序进行同步。

AutoResetEvent类还有带参数的WaitOne()方法,用于指定最大等待时间,超过就不再等待:

//9000毫秒,true标识可以再等待结束之前推出同步域documentComplete.WaitOne(9000,true)

操纵并检查IE Shell

1         static void Main(string[] args) 2         { 3                 SHDocVw.InternetExplorer ie = null; 4                 //把ie对象连接到IE程序所在的进行 5  6                 Console.WriteLine("Setting IE to size 450x360"); 7                 ie.Width = 450; 8                 ie.Height = 360; 9                 Thread.Sleep(1000);10 11                 if (ie.StatusText.IndexOf("Done") == -1)12                     Console.WriteLine("could not find 'Done' in status bar");13                 else14                     Console.WriteLine("Find 'Done' in status bar");15                 //...16         }
View Code

当编写针对Web UI的自动化测试程序师,需要把IE的3个区域考虑在内:

  • 客户区域,即待测页面所在区域;
  • Shell区域,即诸如地址栏和回退按钮等IE控件所在的区域;
  • 以及其他窗口,比如alert对话框等,这些窗口与IE是分开的。

SHDocVw.InternetExplorer对象提供了一些属性和方法用于操纵(可用来模拟用户操作)和检查Shell(可用来判断某个测试场景通过与否)。下面是几种属性和方法:

  • GoBack(), GoForward(), GoHome(), Refresh(), Quit();
  • Height, Width: 设置IE外壳的高度和宽度(以像素为单位)。
  • Top, Left: 设置IE外壳左上角的位置(以像素为单位)。
  • FullScreen:如果IE在全屏模式下运行,则返回true。
  • MenuBar:如果IE菜单栏可见,则返回true。
  • Resizable:如果可以调整IE的大小,则返回true。
  • LocationURL:返回IE当前显示页面的URL。
  • StatusText:返回IE状态栏的文本。

操作待测Web页面上的HTML元素的值

示例代码:

using mshtml;  // .NET component = Microsoft.mshtml. HTML interfaces        static void Main(string[] args)        {                //...                HTMLDocument theDoc = (HTMLDocument)ie.Document;                Console.WriteLine("\nSelecting 'ID' radio button");                HTMLInputElement radioButton = (HTMLInputElement)theDoc.getElementById("RadioButtonList1_2");                radioButton.@checked = true;                Console.WriteLine("Setting text box to '2B'");                HTMLInputElement textBox = (HTMLInputElement)theDoc.getElementById("TextBox1");                textBox.value = "2B";                Console.WriteLine("Clicking search button");                HTMLInputElement butt = (HTMLInputElement)theDoc.getElementById("Button1");                butt.click();                documentComplete.WaitOne();                //...        }
View Code

在上述代码中,要模拟用户选中radio button控件,必须使用@checked,因为checked是C#语言的一个关键字。

在上述代码中,按钮控件和文本控件的类型都是HTMLInputElement,而下拉空间的类型则是HTMLSelectElement。可通过下面代码知道到底该用哪个类:

HTMLInputElement textBox = (HTMLInputElement)theDoc.getElementById("TextBox1");Console.WriteLine("The textbox has type" + textBox.GetType().ToString());

注意:因为我们是通过getElementById()方法获得HTML元素/控件的引用的,所以这个控件必须要有ID attribute,从而可以唯一的表示这个控件。若Web页面是由Visual Studio .NET UI设计器创建的,那么所有控件都有一个ID attribute。但是如果Web程序是手工创建(比如通过Notepad),那么最好修改这个程序,给他们加上一个ID attribute。

验证Web页面上HTML元素

通过mshtml.dll库里的getElementByTagName()方法和item()方法得到你想要的特定的元素。然后可以通过InnerText属性取回HTML元素的实际值。

设想某个待测页面含有几个<P>元素,和一个ID为“div2”的<div>元素。下面的代码在<p>元素中查找“aloha”,在<div>元素中查找"adios":

1                 Console.WriteLine("Seek 'aloha' in 

[2]"); 2 Console.WriteLine("

type is:" + theDoc.getElementsByTagName("p").GetType().ToString()); 3 HTMLParaElement paraElement = (HTMLParaElement)theDoc.getElementsByTagName("p").item(1, null); 4 if (paraElement.innerText.ToString().IndexOf("aloha") >= 0) 5 Console.WriteLine("Found target 'aloha'"); 6 else 7 Console.WriteLine("Target string not found"); 8 9 Console.WriteLine("Seek 'adios' in

");10 HTMLDivElement divElement = (HTMLDivElement)theDoc.getElementsByTagName("div").item("div2", null);11 if (divElement.innerText.ToString().IndexOf("adios") >= 0)12 Console.WriteLine("Found target 'adios'");13 else14 Console.WriteLine("Target string not found");
View Code

上述代码中,item()方法:

  • 第一个参数可以为整数(整数时为从0开始的索引值)或字符串(字符串时为tag名字);
  • 第二个参数是个索引值,但只有当item()返回得是一个集合时才用得到。

有时候这些元素的值并不属于任何子的HTML元素,可用以下代码解决:

1                 // non-HTML element 2                 Console.WriteLine("Seeking 'Search Complete' in body"); 3                 HTMLBody body = (HTMLBody)theDoc.getElementsByTagName("body").item(0, null); 4                 if (body.createTextRange().findText("Search Complete", 0, 4) == true) 5                 { 6                     Console.WriteLine("Found target string"); 7                 } 8                 else 9                 {10                     Console.WriteLine("*Target string not found*");11                     pass = false;12                 }
View Code

上述代码中,findText()方法:

  • 第一个参数是必添的目标字符串
  • 第二个参数用于制定查找起始位置
  • 第二个参数用于指定查找类型

示例代码

1 // Chapter 7 - Low-Level Web UI Testing  2 // Example Program: LowLevelUITest  3   4   5 using System;  6 using SHDocVw; // COM component = Microsoft Internet Controls. IE object  7 using mshtml;  // .NET component = Microsoft.mshtml. HTML interfaces  8 using System.Diagnostics; // Process  9 using System.Threading;   // Sleep() 10  11 namespace RunTest 12 { 13     class Class1 14     { 15         static AutoResetEvent documentComplete = new AutoResetEvent(false); 16  17         [STAThread] 18         static void Main(string[] args) 19         { 20             try 21             { 22                 Console.WriteLine("\nStarting test run"); 23  24                 bool pass = true; // assume test run will pass 25                  26                 SHDocVw.InternetExplorer ie = null; 27                 Console.WriteLine("\nLaunching an instance of IE"); 28                 Process p = Process.Start("iexplore.exe", "about:blank"); 29                 System.Threading.Thread.Sleep(2000); 30                 if (p == null) 31                     throw new Exception("Could not launch IE"); 32                 Console.WriteLine("Process handle = " + p.MainWindowHandle.ToString());                 33  34                 SHDocVw.ShellWindows allBrowsers = new SHDocVw.ShellWindows(); 35                 Console.WriteLine("Number active browsers = " + allBrowsers.Count); 36  37                 if (allBrowsers.Count == 0) 38                     throw new Exception("Cannot find IE"); 39  40                 Console.WriteLine("Attaching to IE"); 41                 int i = 0; 42                  43                 while (i < allBrowsers.Count && ie == null) 44                 { 45                     InternetExplorer e = (InternetExplorer)allBrowsers.Item(i); 46                     if (e != null) 47                     { 48                         if (e.HWND == (int)p.MainWindowHandle) 49                             ie = e;                        50                     } 51                     ++i; 52                 } 53  54                 if (ie == null) 55                     throw new Exception("Failed to attach to IE"); 56  57                 ie.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete); 58  59                 Console.WriteLine("\nNavigating to the Web app"); 60                 object nil = new object();                 61                 ie.Navigate("http://localhost:30614/WebAUT/Default.aspx", ref nil, ref nil, ref nil, ref nil);             62  63                 documentComplete.WaitOne(); 64  65                 Console.WriteLine("Setting IE to size 450x360"); 66                 ie.Width = 450; 67                 ie.Height = 360; 68                 Thread.Sleep(1000); 69  70                 //if (ie.StatusText.IndexOf("Done") == -1) 71                 //    Console.WriteLine("could not find 'Done' in status bar"); 72                 //else 73                 //    Console.WriteLine("Find 'Done' in status bar"); 74  75                 HTMLDocument theDoc = (HTMLDocument)ie.Document; 76  77                 Console.WriteLine("\nSelecting 'ID' radio button"); 78                 HTMLInputElement radioButton = (HTMLInputElement)theDoc.getElementById("RadioButtonList1_2"); 79                 radioButton.@checked = true; 80  81  82                 Console.WriteLine("Setting text box to '2B'"); 83                 HTMLInputElement textBox = (HTMLInputElement)theDoc.getElementById("TextBox1"); 84                 Console.WriteLine("The textbox has type" + textBox.GetType().ToString()); 85                 textBox.value = "2B"; 86  87                 Console.WriteLine("Clicking search button"); 88                 HTMLInputElement butt = (HTMLInputElement)theDoc.getElementById("Button1");                 89                 butt.click(); 90  91                 documentComplete.WaitOne(); 92  93                 Console.WriteLine("Seek 'aloha' in 

[2]"); 94 Console.WriteLine("

type is:" + theDoc.getElementsByTagName("p").GetType().ToString()); 95 HTMLParaElement paraElement = (HTMLParaElement)theDoc.getElementsByTagName("p").item(1, null); 96 if (paraElement.innerText.ToString().IndexOf("aloha") >= 0) 97 Console.WriteLine("Found target 'aloha'"); 98 else 99 Console.WriteLine("Target string not found");100 101 Console.WriteLine("Seek 'adios' in

");102 HTMLDivElement divElement = (HTMLDivElement)theDoc.getElementsByTagName("div").item("div2", null);103 if (divElement.innerText.ToString().IndexOf("adios") >= 0)104 Console.WriteLine("Found target 'adios'");105 else106 Console.WriteLine("Target string not found");107 108 // non-HTML element109 Console.WriteLine("Seeking 'Search Complete' in body");110 HTMLBody body = (HTMLBody)theDoc.getElementsByTagName("body").item(0, null);111 if (body.createTextRange().findText("Search Complete", 0, 4) == true)112 {113 Console.WriteLine("Found target string");114 }115 else116 {117 Console.WriteLine("*Target string not found*");118 pass = false;119 }120 121 if (pass)122 Console.WriteLine("\nTest result = Pass\n");123 else124 Console.WriteLine("\nTest result = *FAIL*\n");125 126 Console.WriteLine("Closing IE in 4 seconds . . . ");127 Thread.Sleep(4000);128 ie.Quit();129 130 }131 catch (Exception ex)132 {133 Console.WriteLine("Fatal error: " + ex.Message);134 Console.ReadLine();135 }136 137 } // Main()138 139 private static void ie_DocumentComplete(object pDisp, ref object URL)140 {141 documentComplete.Set();142 }143 144 } // class Class1145 } // ns RunTest
View Code

 

转载地址:http://huvyx.baihongyu.com/

你可能感兴趣的文章
DeviceIOControl与驱动层 - 缓冲区模式
查看>>
感悟贴2016-05-13
查看>>
vim使用教程
查看>>
JDK在LINUX系统平台下的部署案例与总结
查看>>
跨vlan通信-----单臂路由技术
查看>>
百度编辑器ueditor 光标位置的坐标
查看>>
DEV-C++ 调试方法简明图文教程(转)
查看>>
VS2017+EF+Mysql生成实体数据模型(解决闪退的坑)
查看>>
C++多态、继承的简单分析
查看>>
库克称未来苹果用户可自己决定是否降频 网友:你是在搞笑吗?
查看>>
6倍性能差100TB容量,阿里云POLARDB咋实现?
查看>>
linux 安装 MySQLdb for python
查看>>
Sublime Text 2 技巧
查看>>
使用fscanf()函数从磁盘文件读取格式化数据
查看>>
网站一些error_log报错
查看>>
参加婚礼
查看>>
h5 audio相关手册
查看>>
JDK文章列表-转载列表
查看>>
umask--设置用户文件和目录的文件创建缺省屏蔽值
查看>>
磁盘管理-quota
查看>>