.Net软件UI界面测试自动化--Windows API
来源:互联网 发布:淘宝直播视频怎么删除 编辑:程序博客网 时间:2024/06/08 19:54
本文将介绍实现软件自动化测试其中一种测试方法------Windows API技术,当然,此种方法仅限于对.Net软件使用,还有一些比较通用的方法,将在后续的文章中进行介绍(使用UIAutomation类).
反射技术具体是什么原理,本文将不做任何介绍,大家可以去网上搜索一下,有很多这方面的文章介绍,本文只介绍如何使用Windows API技术进行.NET软件的UI界面的自动化测试.
废话少说,多做实事!(本文所有代码均在VS2008环境下测试通过)
一. 创建待测试程序
1. 启动VS2008,建立一个C#的WinForm工程,并将工程文件名命名为AUT(Application Under Test)
2. 创建的Form上的按钮布局,如下图所示
3. 一个菜单(包含一个以及菜单File以及一个二级菜单Exit),一个TextBox,一个ComboBox,一个Button以及一个ListBox
private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.ListBox listBox1;4. 给Button按钮添加一个消息响应函数
private void button1_Click(object sender, EventArgs e) { string tb = textBox1.Text; string cb = comboBox1.Text; if (tb == cb) { listBox1.Items.Add("Result is a tie"); } else if (tb == "paper" && cb == "rock" || tb == "rock" && cb == "scissors" || tb == "scissors" && cb == "paper") { listBox1.Items.Add("The TextBox wins"); } else { listBox1.Items.Add("The ComboBox wins"); } }
5. 给Exit菜单添加一个消息响应函数 private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); }
6.给ComboBox控件添加三个Item,分别为paper,rock,scissions7. 编译待测试程序,生成文件名为AUT.exe的待测试程序
二. 创建测试程序
1. 启动VS2008,创建一个C#控制台程序,并命名为WindowsUITest
2. 在工程中添加以下using语句
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.IO; using System.Text;
3. 声明需要使用到的WIndows API [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)] static extern IntPtr FindWindow(string lpClassName, string lpWindowsName); [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)] static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); //用于发送WM_CHAR消息 [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam); //用于发送WM_COMMAND消息 [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam); //用于发送WM_GETTEXT消息 [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam); //用于发送LB_FINDSTRING消息 [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, byte[] lParam); //用于发送WM_LBUTTONDOWN和WM_LBUTTONUP消息 [DllImport("user32.dll", EntryPoint="PostMessage", CharSet=CharSet.Auto)] static extern bool PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam); //菜单函数相关 [DllImport("user32.dll")] static extern IntPtr GetMenu(IntPtr hWnd); [DllImport("user32.dll")] static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos); [DllImport("user32.dll")] static extern int GetMenuItemID(IntPtr hMenu, int nPos);
4. 定义查询窗体的函数 static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries) { IntPtr mwh = IntPtr.Zero; bool formFount = false; int attempts = 0; do { mwh = FindWindow(null, caption); if (mwh == IntPtr.Zero) { Console.WriteLine("Form not yet found"); Thread.Sleep(delay); ++attempts; } else { Console.WriteLine("Form has been found"); formFount = true; } } while (!formFount && attempts < maxTries); if (mwh != IntPtr.Zero) { return mwh; } else { throw new Exception("Could not found Main Window"); } } static IntPtr FindMainWindowHandle(string caption, int delay, int maxTries) { return FindTopLevelWindow(caption, delay, maxTries); } static IntPtr FindMessageBox(string caption) { int delay = 100; int maxTries = 25; return FindTopLevelWindow(caption, delay, maxTries); } static IntPtr FindWindowByIndex(IntPtr hwndParent, int index) { if (index == 0) { return hwndParent; } else { int ct = 0; IntPtr result = IntPtr.Zero; do { result = FindWindowEx(hwndParent, result, null, null); if (result != IntPtr.Zero) { ++ct; } } while (ct < index && result != IntPtr.Zero); return result; } }
5. 定义发送字符串/字符的函数 static void SendChar(IntPtr hControl, char c) { uint WM_CHAR = 0x0102; SendMessage1(hControl, WM_CHAR, c, 0); } static void SendChars(IntPtr hControl, string s) { foreach (char c in s) { SendChar(hControl, c); } }
6. 定义点击鼠标按钮的函数 static void ClickOn(IntPtr hControl) { uint WM_LBUTTONDOWN = 0x0201; uint WM_LBUTTONUP = 0x0202; PostMessage1(hControl, WM_LBUTTONDOWN, 0, 0); PostMessage1(hControl, WM_LBUTTONUP, 0, 0); }
7. 编写测试代码 [STAThread] static void Main(string[] args) { try { Console.WriteLine("\nLaunching application under test"); string path = Directory.GetCurrentDirectory() + "\\AUT.exe"; Process p = Process.Start(path); Thread.Sleep(2000); Console.WriteLine("\nFinding main window handle"); IntPtr mwh = FindMainWindowHandle("Form1", 100, 25); Console.WriteLine("Main window handle = " + mwh); Thread.Sleep(2000); //因为测试程序是使用C#创建的,所以控件的Class名称会比较奇怪,可以使用SPY++工具来查看 IntPtr tb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.EDIT.app.0.378734a", ""); IntPtr cb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.COMBOBOX.app.0.378734a", ""); IntPtr bt = FindWindowEx(mwh, IntPtr.Zero, null, "button1"); IntPtr lb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.LISTBOX.app.0.378734a", ""); if (tb == IntPtr.Zero || cb == IntPtr.Zero || bt == IntPtr.Zero || lb == IntPtr.Zero) { throw new Exception("Unable to find all controls"); } else { Console.WriteLine("All control handles found"); } //设置数据 SendChars(tb, "paper"); SendChars(cb, "rock"); ClickOn(bt); Thread.Sleep(1000); uint LB_FINDSTRING = 0x018F; byte[] bResult = Encoding.ASCII.GetBytes("The TextBox wins"); int result = SendMessage4(lb, LB_FINDSTRING, -1, bResult); //uint WM_GETTEXT = 0x000D; if (result >= 0) { Console.WriteLine("\nTest scenario result = Pass"); } else { Console.WriteLine("\nTest scenario result = Fail"); } Console.WriteLine("\nExiting app in 3 seconds..."); Thread.Sleep(3000); IntPtr hMainMenu = GetMenu(mwh); //IntPtr hMainMenu = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.Window.8.app.0.378734a", null); IntPtr hFile = GetSubMenu(hMainMenu, 0); int iexit = GetMenuItemID(hFile, 0); uint WM_COMMAND = 0x0111; SendMessage2(mwh, WM_COMMAND, iexit, IntPtr.Zero); Console.WriteLine("\nDone"); Console.ReadLine(); } catch (System.Exception ex) { } }
8. 编译测试程序,OK,大功告成- .Net软件UI界面测试自动化--Windows API
- .Net软件UI界面测试自动化--反射技术
- .Net软件UI界面测试自动化--UIAutomation技术
- windows UI自动化测试
- API自动化软件测试之我见
- 从数据库读取UI源数据自动化生成Windows 界面(.net环境中Windows开发的自动化界面系统构架研究 续一)
- QTP软件测试 Windows计算器自动化脚本
- 软件测试_BadBoy自动化测试工具1 界面介绍
- “.Net软件测试自动化之道”
- .NET软件测试自动化之道
- 使用phantomjs进行无界面UI自动化测试
- Robot Framework使用Phantomjs进行无界面UI自动化测试
- net自动化测试之道API测试-确定测试结果
- net自动化测试之道API测试-统计测试结果
- net自动化测试之道API测试-用空串测试
- iOS自动化测试之常用UI Automation API
- iOS自动化测试之常用UI Automation API
- 软件测试中界面UI测试常见BUG汇总
- 攻克“用InstallShield制作卸载快捷方式”
- 暂时离开,csdn啥时候弄好了,啥时候回来
- 创业公司CEO每周应该做的13件事
- 等待队列学习笔记
- 使用JasperReport和iReport制作java报表
- .Net软件UI界面测试自动化--Windows API
- linux下统计代码行数
- 日历控件格式HH/MM/DD
- 第一个android益智类游戏-->数独
- Python的reload及热更新
- 关于Opera浏览器的html文件的关联
- wireshark过滤器规则
- android 反编译(转)
- Linux下PCI设备驱动程序开发