自动化测试 之连连看外挂项目实战
GUI自动化测试和做外挂的原理很相似,都是模拟用户的鼠标和键盘操作, 给自己的程序写自动化就是做测试,给别人的程序写自动化就是外挂了。
本文使用的技术也同样适用制作“对对碰”,"找茬" 之类游戏的外挂。
QQ连连看外挂实现原理
1. 先调用Win32 API获取"连连看"游戏窗口的句柄,
2. 根据游戏窗口的句柄,然后获取游戏方块中的像素。
3. 用一个二维数组来保存每个方块的像素
4. 用算法判定两个一样的方块能否"消", 如果能"消"的话,就模拟鼠标去点击这两个方块。 继续"消" 下一组方块。
GUI自动化测试的原理
当你点击窗体中的一个button, button会响应然后执行一些操作。 这个过程的本质是: 你在屏幕上点击一个Button, Windows系统根据你点击的位置,知道你要点击哪个Button,然后给这个Button发送鼠标点击的消息。
自动化的原理是: 找到控件的句柄,通过句柄给这个控件发送消息,比如“键盘输入”消息或者“鼠标点击”消息。
什么是句柄
所有的Windows控件本质上都是一个窗体(Window). 每个控件/窗体都有一个与之关联的句柄(handle), 可以通过这个句柄来访问,操纵和检测这个控件/窗体
窗体句柄是由系统产生的一个值,你可以把它想象成与窗体关联的一个ID,通过这个ID可以访问相应的窗体。
在.NET中, 句柄的类型是System.IntPtr, 有点类似Int型。
P/Invoke机制
P/invoke机制叫做"平台调用"机制, 因为Win32API 函数是Windows操作系统的一部分,所以它是用传统的C++程序写的,而不是用C#托管代码写的。 所以我们需要一种机制,让C#中可以调用Win32 API函数.
具体的解决方案是: 先为想要使用的Win32函数创建一个C#外覆函数,或者叫别名函数, 然后调用这个别名函数
实例:
在Win32 API中获取窗体的句柄的函数是 FindWindow(), 它的函数签名用C++描述是这样的
HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
在C#中,给这个Win32 函数创建别名函数
需要先引用命名空间: using System.Runtime.InteropServices;
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
DllImport: 指定要使用的函数所在的DLL文件。
EntryPoint: Win32 API函数的名称.
CharSet.Auto: 让.NET框架来决定如何进行字符类型转换
当为一个Win32函数编写相应的C#方法别名的时候, 几乎总要使用static 和extern, 因为大多数Win32函数都是静态函数,而非实例函数。
注意:别名函数和Win32函数的名称并不要求一致。 但是名称一致可以保证代码的可读性.
获取游戏窗体的句柄
我们用Win32 API 函数来获取“连连看"游戏窗体的句柄
我们现在调用上节介绍的C#中的别名函数FindWindow(),就相当于调用了Win32 API 的FindWindow()函数
FindWindow函数接收2个参数,className 或者WindowName 然后返回句柄.
Spy++是.NET中自带工具,我们可以使用它来获取窗体的名字。
具体用法是,启动spy++, 点击"Findow Window"图标,弹出Findow Window 程序后, 用鼠标拖动“靶心”到你要测试的窗体上。
如下图。 可以得到游戏窗体的名字叫"QQ游戏 - 连连看角色版"
这样我们就能轻松获取 游戏窗体的句柄
IntPtr wndPane = Win32API.FindWindow(null, "QQ游戏 - 连连看角色版");
分析游戏窗口
通过屏幕标尺工具, 我们去测量游戏窗口。 (这个比较繁琐,需要你多次去测量,多次调整后才能得到准确的数据).
可以发现 "游戏区域" 距离游戏窗口 水平方向:15像素, 垂直方向:182像素
游戏中垂直方向有11个方块, 水平方向有19个方块
每个方块 长:31像素, 宽:35像素 如下图
对游戏窗口中的所有方块进行截图
一个方块有31*35=1085个像素, 事实上我们不需要获取方块中所有的像素点。 为了节省性能,我只需要获取一个方块中的几个像素就可以了。
我们需要用到2个函数来实现获取方块的像素。
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);[DllImport("Gdi32.dll")]
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
GetDC函数的作用是指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄, 它的输入参数是窗口的句柄, (上节中我们介绍过可以使用FindWindow函数来获取窗口的句柄). 返回的是DC句柄。 (注意这两个句柄是不同的)
GetPixel根据GetDC获取的DC句柄和X坐标,Y坐标来获取像素点。
实例: 我们获取游戏中 "第三排第四列" 的方块的像素, 代码如下:
IntPtr wndPane = Win32API.FindWindow(null, "QQ游戏 - 连连看角色版");
IntPtr hdc = Win32API.GetDC(wndPane);
// X轴方向的像素要这么算15+31*3
// 因为游戏区域距离游戏窗口左边15像素,每个方块宽31像素,
// Y轴方向的像素要这么算 182+35*4
// 因为游戏区域距离游戏窗口上方182,每个方块高35像素
uint color = Win32API.GetPixel(hdc, 15+31*3 + offX, 182+35*4 + offY);
根据游戏规则来写算法
我们用一个二维数组来保存游戏中的所有方块
private Block[,] blocks = new Block[11, 19];
Block对象代表一个方块,如果方块为空,那么Block包含的是背景色。 如果有方块,那么Block对象中保存该方块的9个像素点。
详细请参考代码中的Block对象。
然后分析游戏规则来写算法来遍历二维数组。
垂直方向,如果两个一样的方块,处于同样的Y轴上,中间没有任何方块可以消, 如图
水平方向,如果两个一样的方块,处于同样的X轴上,中间没有任何方块, 可以消, 如图
拐1个弯, 如果两个一样的方块, 其中一个的X轴和另一个Y成90度,并且中间没有任何方块, 可以消, 如图
拐2个弯, 如图
根据上面这些游戏规则,来设计算法, 具体算法请参考源代码
模拟鼠标点击
模拟鼠标点击的的方法有很多,
其中的一个win32 API 方法为
[DllImport("user32.dll")]public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);const int MOUSEEVENTF_MOVE = 0x0001; //移动鼠标public const int MOUSEEVENTF_LEFTDOWN = 0x0002; //模拟鼠标左键按下public const int MOUSEEVENTF_LEFTUP = 0x0004; //模拟鼠标左键抬起const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //模拟鼠标右键按下const int MOUSEEVENTF_RIGHTUP = 0x0010; //模拟鼠标右键抬起const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; //模拟鼠标中键按下const int MOUSEEVENTF_MIDDLEUP = 0x0040; //模拟鼠标中键抬起const int MOUSEEVENTF_ABSOLUTE = 0x8000; //标示是否采用绝对坐标
我这里给你们分享一下我所积累和真理的文档和学习资料有需要是领取就可以了
1、学习思路和方法
这个大纲涵盖了目前市面上企业百分之99的技术,这个大纲很详细的写了你该学习什么内容,企业会用到什么内容。总共十个专题足够你学习
2、想学习却无从下手,该如何学习?
这里我准备了对应上面的每个知识点的学习资料、可以自学神器,已经项目练手。
3、软件测试/自动化测试【全家桶装】学习中的工具、安装包、插件....
4、有了安装包和学习资料,没有项目实战怎么办,我这里都已经准备好了往下看
最后送上一句话:
世界的模样取决于你凝视它的目光,自己的价值取决于你的追求和心态,一切美好的愿望,不在等待中拥有,而是在奋斗中争取。
如果我的博客对你有帮助、如果你喜欢我的文章内容,请 “点赞” “评论” “收藏” 一键三连哦!
自动化测试 之连连看外挂项目实战相关推荐
- pytest测试实战 电子书_电子书丨Selenium 3+Python 3自动化测试项目实战:从菜鸟到高手...
▊<Selenium 3+Python 3自动化测试项目实战:从菜鸟到高手> 田春成 著 电子书售价:39.5元 2019年9月出版 Selenium是目前非常流行的一种自动化测试工具.本 ...
- Python核心场景自动化测试项目实战(二)
往期关联文章回顾: Pytest+Allure+Jenkins接口自动化项目实战(一) [Python篇]核心场景接口自动化方案(一) 以前我们用python+unittest+HTMLTestRun ...
- Python+Selenium自动化测试项目实战
第 1 章 自动化测试 1.1.自动化测试介绍 自动化测试就是通过自动化测试工具帮我们打开浏览器,输入网址,输入账号密码登录,及登录后的操作,总的说来自动化测试就是通过自动化测试脚本来帮我们从繁琐重复 ...
- 一文8个步骤从0到1实现Python+Selenium自动化测试项目实战【建议收藏】
目录 第 1 章.自动化测试 第 2 章.Python基础 第 3 章.元素定位方式 第 4 章.元素 | 浏览器操作方法 第 5 章.元素等待 第 6 章.鼠标和键盘操作 第 7 章.UnitTes ...
- python3自动化测试书籍推荐_免费送书 | 《Selenium 3+Python 3自动化测试项目实战:从菜鸟到高手》...
点击上方蓝色字体,关注我们 免费送书 2019年就剩「2个月」了,你的读书计划进行得如何? 莫踌躇,光荣之路马上送你本书! 读完它,请为你的2019年画上个美丽的圈圈! <Selenium 3+ ...
- Python+Selenium自动化测试项目实战【建议收藏】
第 1 章 自动化测试 1.1.自动化测试介绍 自动化测试就是通过自动化测试工具帮我们打开浏览器,输入网址,输入账号密码登录,及登录后的操作,总的说来自动化测试就是通过自动化测试脚本来帮我们从繁琐重复 ...
- 连连看项目实战之三(解析配置表)
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 这是一款连连看,如果只能连连,那估计大家看看就没兴趣了.如果在里面加上一些场景式对话,那么可能就会有意思许多. 今天就带大家学习Uni ...
- WindowsGUI自动化测试项目实战+辛酸过程+经验分享
WindowsGUI自动化测试项目实战+辛酸过程+经验分享 一.前言 ⚜ 起因 ⚜ 项目要求 ⚜ 预研过程 ⚜⚜ 框架选型 ⚜⚜ 关于UIaotumation框架 ⚜ 预研成果 二.项目介绍
- 基于Selenium+Python的web自动化测试框架(附框架源码+项目实战)
目录 一.什么是Selenium? 二.自动化测试框架 三.自动化框架的设计和实现 四.需要改进的模块 五.总结 总结感谢每一个认真阅读我文章的人!!! 重点:配套学习资料和视频教学 一.什么是Sel ...
- Android性能优化——腾讯、字节、阿里、百度、网易等互联网公司项目实战+案例分析(附PDF)
前言 当我们还在用按键.滑盖.翻盖手机的时候,全触屏手机来了; 当我们觉得二维码这项发明没有意义的时候,支付宝和微信等狠狠地给了我们响亮的耳光; 当我们以为扫码支付只有支付宝的时候,微信支付来了; 当 ...
最新文章
- 通过url,获取html内容,并解析
- BZOJ 4244 邮戳拉力赛 (DP)
- 姗姗来迟的Ubuntu版MX4,已经没了当年的初衷
- UIImageview 遮罩效果
- Hive中排序和聚集
- Codeforces Global Round 14 F. Phoenix and Earthquake 思维 + 并查集
- 实战_06_SpringBoot整合redis-cluster集群版本
- 设计模式之观察者模式(Java)
- 高效排错系列--摘要
- php 去掉无关数据,php 读取 mysql 表中的double数据,去掉多余的0
- Vue 学习笔记(4)Vue-cli4 项目搭建 + 目录结构 + 项目打包、部署
- java redis源码分析,慢谈 Redis 实现分布式锁 以及 Redisson 源码解析
- Golang学习:生成GIF动画
- gisdk学习心得(一)-简介
- 天轰穿Visual Studio2005入门.Net2.0系列视频教程
- 2019 谷歌dat.GUI组件对中文的支持
- python爬虫--爬取网易云音乐评论
- RL gym 环境(2)—— 自定义环境
- goinception审核规则
- [附源码]计算机毕业设计JAVA校园超市进销存管理系统
热门文章
- Pearson 相关分析 理论与应用
- 绕过tp路由器管理密码_TP-Link路由器登录密码怎么重置【详细介绍】
- nebulagraph exchange3.0.x
- Windows10清理C盘的恶意软件
- 计算机计算累计公式,““请问Excel表格求的合计数为什么和用计算器累加出的合计数不一致...
- 英语语法最终珍藏版笔记-8虚拟语气
- Spring的refresh()方法相关异常
- pdf文件如何生成目录 wps_怎样快速为WPS文档增加目录
- packet和frame区别
- 用QQ聊天记录生成一个词云