借助API实现黑盒自动化测试工具的编写

发表于:2018-7-30 17:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:不如来编码    来源:博客园


  本文摘要:
  1:一个简单的例子
  1.1:EnumChildWindows介绍
  1.2:主要源码
  2:难点:如何获取指定的控件句柄
  2.1:使用SPY++
  2.2:获取控件位置
  2.3:获取控件ID
  1:一个简单的例子
  在日常编码过程中,我们常常会进行自动化测试。这里的自动化测试不是指单元测试,而是模拟人工输入来进行快速的、高并发的测试。可以使用的自动化工具有LOADRUNNER,以及目前在VS2010中的功能很强大的测试工作平台(录制操作步骤,自动生成代码)。但是,这些工具的熟练掌握也有一定的时间成本,并且,最主要的,对于一个程序员来说,那不够灵活。所以,比较高效的一个做法是,调用WINDOWS API,自己动手写编码来实现。
  下面做一个简单的演示。为了简便起见,假设存在这样一个应用程序:
  1:提供一个WINFORM窗体,上面存在一个TextBox,以及一个Button;
  2:点击Button,会弹出提示框,提示框内容为TextBox的值;
  现在,测试要求如下:
  1:在300台机器上运行上面的程序;
  2:到这300台机器上去点击这个Button,看看上文中的功能2有没有实现;
  很显然,实际情况中没有这么简单的程序,实际的情况有可能是点击Button,统一下载一个文件,而测试的要求可能就变为考核服务器的负载。现在,测试部显然也没有300个人坐在客户机上验证测试的结果,这个时候,就需要我们提供一个自动化的测试工具,来完成必要的测试任务。
  测试工具,首先也是一个C#的程序,它的主要目的是:
  1:获取上文应用程序的窗口句柄,继而获取TextBox句柄及Button句柄;
  2:为TextBox随机填入一些字符;
  3:模拟点击Button;
  1.1:EnumChildWindows介绍
  在这里需要介绍下EnumChildWindows,
  EnumChildWindows可是个好东西,可以枚举一个父窗口的所有子窗口:
  BOOL EnumChildWindows(
  HWND hWndParent,         // handle to parent window // 父窗口句柄
  WNDENUMPROC lpEnumFunc,  // callback function // 回调函数的地址
  LPARAM lParam            // application-defined value // 你自已定义的参数
  );
  就这么简单,让我们再定义一个回调函数,像下面这样:
  BOOL CALLBACK EnumChildProc(
  HWND hwnd,      // handle to child window
  LPARAM lParam   // application-defined value
  );
  在调用EnumChildWindows 这个函数时,直到调用到最个一个子窗口被枚举或回调函数返回一个false,否则将一直枚举下去。
  1.2:简单例子的主要源码
  测试工具的主要代码如下:
  private void button1_Click(object sender, EventArgs e)
  {
  //获取测试程序的窗体句柄
  IntPtr mainWnd = FindWindow(null, "FormLogin");
  List<IntPtr> listWnd = new List<IntPtr>();
  //获取窗体上OK按钮的句柄
  IntPtr hwnd_button = FindWindowEx(mainWnd, new IntPtr(0), null, "OK");
  //获取窗体上所有控件的句柄
  EnumChildWindows(mainWnd, new CallBack(delegate(IntPtr hwnd, int lParam)
  {
  listWnd.Add(hwnd);
  return true;
  }), 0);
  foreach (IntPtr item in listWnd)
  {
  if (item != hwnd_button)
  {
  char[] UserChar = "luminji".ToCharArray();
  foreach (char ch in UserChar)
  {
  SendChar(item, ch, 100);
  }
  }
  }
  SendMessage(hwnd_button, WM_CLICK, mainWnd, "0");
  }
  public void SendChar(IntPtr hand, char ch, int SleepTime)
  {
  PostMessage(hand, WM_CHAR, ch, 0);
  System.Threading.Thread.Sleep(SleepTime);
  }
  public static int WM_CHAR = 0x102;
  public static int WM_CLICK = 0x00F5;
  [DllImport("User32.dll", EntryPoint = "SendMessage")]
  public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
  [DllImport("user32.dll")]
  public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
  string lpszClass, string lpszWindow);
  [DllImport("user32.dll", SetLastError = true)]
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  [DllImport("user32.dll")]
  public static extern int AnyPopup();
  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
  [DllImport("user32.dll")]
  public static extern int EnumThreadWindows(IntPtr dwThreadId, CallBack lpfn, int lParam);
  [DllImport("user32.dll")]
  public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
  [DllImport("user32.dll", CharSet = CharSet.Ansi)]
  public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
  [DllImport("user32.dll", CharSet = CharSet.Ansi)]
  public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  public static extern IntPtr SendMessageA(IntPtr hwnd, int wMsg, int wParam, int lParam);
  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
  [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  public static extern int GetWindowTextLength(IntPtr hWnd);
  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
  public static extern IntPtr GetParent(IntPtr hWnd);
  public delegate bool CallBack(IntPtr hwnd, int lParam);

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号