ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

200行Python+Playwright,把15小时手动QA活干成4分钟

200行Python+Playwright,把15小时手动QA活干成4分钟 一、15小时重复点击逼出一个“偷懒”的程序员谁知晓呀? 存有这般一群QA, 日行事务并非深度钻研测试逻辑, 却是机械性地反复同一行为: 开启测试环境, 登录账号, 钻研三层菜单, 填写表单, 点击提交, 等待加载, 查询表格, 循环不止, 枯燥至极仿若灵魂出窍。去年, 有个程序员, 亲眼看到团队陷入这般内耗, 一个回归测试流程, 手动跑一回需3小时, 他们每周发5次版本, 算下来每周有15小时全耗在这种没意义的重复操作上。更让人崩溃的是, 人一无聊就容易出错, 手动测试时漏测、误判的状况屡屡发生, 反倒拖慢版本上线速度了。所有人都认定“这就是QA的工作”, 只有他不愿忍受, 明明是具有确定性的流程, 为啥要让人类去干机器的活儿? 于是他动手写代码, 没料到有200行还多, 直接把长达3小时的手动工作压缩至4分钟, 并且零差错。这看上去好像是一回简简单单的“偷懒”行为, 实际上却把许许多多团队的关键痛点给解决掉了, 然而好多人并不清楚, 自动化测试真的能够去替代手动QA吗, 普通的人能够复制这种高效吗, 在这背后所隐藏着的, 是多数团队都在遭遇的自动化误区。二、对核心进行拆解, 从无到有, 去复制两百行代码, 从而完成QA自动化的整个过程。他没用复杂繁复的测试框架也没搭建规模宏大的网格, 仅凭借与两种工具, 便达成了全流程自动化, 整个进程划分成六个关键步骤, 每一步骤皆存有详尽代码, 普通人依照去做便可上手。第一步选对工具少走80%的弯路他摒弃了平常所采用的, 做出了选择, 关键缘由存在三个, 其中每一个都精准地击中了手动测试以及传统自动化的症结所在。1. 让元素自动等待, 用不着去写完大量的sleep()语句, 防止因页面加载速度慢致使测试失败。2. 有着内置网络, 还有着控制台检查, 调试的时候会更加高效, 并不需要额外去安装插件。3. 选择器更稳定不容易因页面布局变化而失效。微软开源的自动化测试工具, 它完全免费, 星数高达4.5万以上, 支持多种语言, 安装简便, 新手也能够快速上手, 这是关键信息。安装步骤复制就能执行pip install playwright playwright install完成这两句之行程序后, 浏览器二进制格式的文件会自行展开下载操作, 不需要进行额外的配置设定, 马上便能够开启编写脚本的进程。第二步梳理流程先定规则再写代码这乃是最为关键同时也是极易被忽视的一步, 他并未一开始就着手编写代码, 而是率先将QA的手动流程分解为清晰的、能够确定的步骤, 以此防止“即便代码的写法极为流畅, 然而流程处于混乱状态也是徒劳无功”。最终梳理后的核心流程1. 登录测试环境2. 创建一个新的测试账号3. 导航到账单页面提交一笔模拟购买4. 验证发票是否正常生成5. 确认后台任务是否正确处理。他在这一步, 还把两个多余的手动检查步骤删掉了, 让流程变得更简洁, 还为后续代码的简化奠定了基础, 记住, 自动化的前提是“流程确定性”, 手动流程要是混乱, 自动化只会更乱。第三步编写基础脚本实现登录自动化它的API属于异步性质, 能够以高效的方式去处理多个浏览器所产生的事件, 接下来要呈现的是最为基础的登录脚本, 仅仅只有几十行代码, 却能够起到替代几十次手动进行输入以及点击操作的作用:import asyncio from playwright.async_api import async_playwright async def run_test(): # 启动浏览器无头模式不弹出浏览器窗口 async with async_playwright() as p: browser await p.chromium.launch(headlessTrue) page await browser.new_page() # 导航到登录页面 await page.goto(https://staging.example.com/login) # 填写账号密码 await page.fill(#email, test_userexample.com) await page.fill(#password, password123) # 点击提交按钮Playwright会自动等待按钮可点击 await page.click(button[typesubmit]) # 等待仪表盘加载完成确认登录成功 await page.wait_for_selector(#dashboard) print(Login successful) # 关闭浏览器 await browser.close() if __name__ __main__: asyncio.run(run_test())这段代码的核心优势在于, 它无需手动去添加等待时间, 能够自动等待元素加载完毕, 进而避免了在过程中常见的那种“元素未加载就进行点击”所引发的报错情况, 使得稳定性得到了大幅度的提升。第四步避坑关键选对选择器避免脚本频繁失效他的第一版脚本老是崩溃, 并非不好用, 而是选择器选得太随性, 最初他用那种依靠页面布局的选择器“div div:nth-child(3) ”, 只要前端对布局稍作调整, 脚本就会没效果。后来呀, 他对策略做出了调整, 优先去使用语义化的选择器, 最终把脚本脆弱这个问题给彻底解决掉了, 还推荐了两种具备实用性质的选择器。# 1. 按文本选择直观不易失效 await page.click(textCreate Account) # 2. 按data-testid选择最稳定需前端配合添加 await page.locator([data-testidcreate-account]).click()这存在这么一个实用的建议, 要是你的前端团队未曾添加data - 属性, 那就一定要主动提出。此属性是专门投身于自动化测试的, 其不会对页面显示造成影响, 但是却能够规避后续数量众多的脚本修改工作。第五步完善流程实现账号创建与发票验证登录功能稳定下来之后, 他接着去扩展脚本, 达成了测试账号创建的自动化以及发票验证的自动化, 这两步直接将近10分钟的手动操作给替代掉了。# 账号创建函数 async def create_account(page): await page.click(textNew Account) await page.fill(#name, Automation Test) await page.fill(#email, automation_testexample.com) await page.click(button:has-text(Create)) # 等待账号创建成功提示 await page.wait_for_selector(textAccount created) # 发票验证函数核心业务校验不止于UI点击 async def verify_invoice(page): # 导航到发票页面 await page.goto(https://staging.example.com/invoices) # 等待表格加载 await page.wait_for_selector(table) # 查找自动化测试生成的发票 invoice await page.locator(textAutomation Test).first # 断言发票存在验证业务是否正常 assert await invoice.is_visible()第六步解决异步难题处理后台任务延迟最难解决的问题在于: 发票并非在提交购买之后马上生成, 后台任务处理时间不固定, 有时是三秒, 有时是二十秒。若采用固定的等待时间, 要么会造成时间的浪费, 要么会因为等待时间不够而致使测试失败。他用了“轮询超时”的方法完美解决了这个问题代码如下import asyncio import time async def wait_for_invoice(page, timeout30): start time.time() # 循环查询直到超时 while time.time() - start timeout: await page.reload() # 刷新页面 # 统计符合条件的发票数量 invoices await page.locator(textAutomation Test).count() if invoices 0: return True # 找到发票返回成功 await asyncio.sleep(2) # 每2秒查询一次 # 超时未找到抛出异常 raise TimeoutError(Invoice was not generated)这样子的一种方法, 其具备的优势之处在于, 并非是去依赖于固定的时间, 反而是依据系统实际呈现出来的状态来进行判断, 它不但高效, 而且还稳定, 特别适宜于分布式系统的自动化测试。第七步优化脚本实现生产级可用刚一开始的那个脚本虽说是能够使用的, 然而却是比较杂乱无章的, 他借助“页面对象模式”这种方式针对脚本开展重构工作, 把它划分成三个不同层次, 从而大幅度地提升了可维护性。1. tests/存放测试用例如.py2. pages/存放页面操作逻辑如登录页、账单页3. utils/存放通用工具如浏览器启动、关闭。拿登录页当作例子来讲, 经过重构过后的代码变得更为简洁明了, 在后续进行修改选择器时, 仅仅只需要改动这一个文件即可:class LoginPage: def __init__(self, page): self.page page # 传入页面对象 async def login(self, email, password): await self.page.goto(https://staging.example.com/login) await self.page.fill(#email, email) await self.page.fill(#password, password) await self.page.click(button[typesubmit]) await self.page.wait_for_selector(#dashboard)最终, 他将脚本接入, 达成了“每一回提交代码, 便会自动运行测试”, 无需再有人员手动去触发, 完全地解放了QA以及开发的双手。三、辩证分析自动化不是万能的这些坑一定要避开通过200行代码, 完成了原本需15小时才能做完的活, 这样子听上去好似是一种“一本万利”的情况, 然而在实际操作期间, 他也碰到了诸多的坑, 更为关键的是, 他察觉到: 自动化测试并非是用于取代手动QA的, 而是用于让手动QA得以解脱的。首先, 确定价值: 自动化的核心优势在于“高效、稳定、可重复”, 它能够完美地取代重复的机械操作, 防止人类由于疲劳、无聊致使的漏测现象发生, 与此同时, 能将QA从繁杂的重复劳动中解放出去, 促使他们专心致力于更具价值的边缘场景测试以及逻辑漏洞挖掘工作, 从而大幅度地提高团队的版本交付效率。再来谈谈局限和坑点, 其一, 自动化没办法覆盖全部场景, 特别是那些存在非确定性, 以及需要进行主观判断的测试, 像页面美观度、交互流畅度这类, 手动QA仍然是不可被替代的其二, 脚本进行维护是要付出成本的, 要是前端频繁地迭代, 选择器频繁发生变化, 那么维护脚本所用的时间, 也许会把自动化节省下来的时间给抵消掉其三, 初期投入的时间成本是不能被忽视的, 梳理流程、编写脚本、调试并优化, 这些都需要耐心, 并非是“写好代码就可以一劳永逸”的。相较而言更值得去深入思索的是, 存在着许多团队, 他们盲目地跟随着潮流去从事自动化相关工作单纯地认为自动化就等同于高效, 于是投入了数量众多的时间去编写脚本, 然而最终却由于维护所需的成本过于高昂, 以及脚本极其频繁地出现失效状况, 反倒无奈地放弃了自动化, 这般做法实在是得不偿失。而真正意义上的自动化, 应当是仅仅去自动化那些能够节省大量时间的核心流程, 而绝不是不论何种流程都进行自动化。四、现实意义不止于QA普通人也能靠自动化“偷懒”该案例所具备的价值, 并非仅仅局限于对一个团队的QA痛点予以解决, 它实际上给每一位程序员以及职场人敲响了一记警钟, 那便是, 任何重复性的工作, 皆值得借助自动化的手段来处理。对于开发团队而言, 这个案例给出了一个能够复刻的自动化方案, 此方案不依赖复杂框架, 只要 200 行代码便可落地, 它能够解决“ 测试瓶颈”问题, 还能降低漏测风险, 它特别适合中小型团队, 不用投入大量成本就能提高效率。对于 QA 团队来说, 情况也是如此。更关键的是, 它破除了“自动化测试很难”的错误认知, 促使更多人认识到, 自动化并非资深工程师独有, 新手同样可以操作。对于平常在职场打拼的人而言, 就算你并非从事程序员工作, 也能够从中得到启发: 工作里那些带有重复性的、呈现机械性质的操作像是批量去填写表格、反复进行点击、定期开展统计数据的工作, 均能够借助简易的代码或者工具达成自动化, 将节省下来的时间, 运用到具备更高价值的事情上面。更为关键之处在于, 此案例证实了“懒”亦是一种生产力, 真正高效之人, 压根不会将时间耗费于毫无意义的重复之上, 而是借助技术手段, 使机器代自己劳作。在这个讲求效率至上的时代, 是否会“偷懒”, 常常决定了你的竞争力。五、互动话题你工作中有哪些“重复到崩溃”的操作瞅完这个实例, 想必好多人都会产生共鸣, 在我们每日的工作里头, 总会存在一些重复得能把人逼疯的操作, 这操作或许是QA的手动测验, 或许是行政的批量录入, 或许是运营的反复统计, 又或许是程序员的反复调试。对于工作来讲, 困扰你的重复操作是啥? 是否试着借助自动化来处理? 要是有的话, 欢迎于评论区域分享你的办法要是没有此尝试, 你认为哪些运用值得被自动化呢?此外, 要是你同样有着想要凭借那个加上自动化来使自身工作实现自动化的想法, 就在评论区域扣下“自动化”, 一块儿去交流且学习, 从而避开那些已经踩过的坑
返回列表