原理
通过Puppeteer模拟用户操作
Puppeteer介绍
你可以在浏览器中手动完成的大部分事情都可以使用 Puppeteer 完成!你可以从以下几个示例开始:
- 生成页面的截图和PDF。
- 抓取SPA并生成预先呈现的内容(即“SSR”)。
- 从网站抓取你需要的内容。
- 自动表单提交,UI测试,键盘输入等
- 创建一个最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试。
- 捕获您的网站的时间线跟踪,以帮助诊断性能问题。
还有一些可用于工程化相关的建设:
- 自动化工具 如自动提交表单,自动下载
- 自动化 UI 测试 如记录下正确 DOM 结构或截图,然后自动执行指定操作后,检查 DOM 结构或截图是否匹配(UI 断言)
- 定时监控工具 如定时截图发周报,或定时巡查重要业务路径下的页面是否处于可用状态,配合邮件告警
Puppeteer文档
个人感觉,这个文档比较适合我。里面api比较详细,还有写小demo。
为什么要进行UI自动化测试
业务的更新迭代频繁,传统测试大部分都还是手工、肉眼的模式来进行,无法满足产品敏捷开发、快速迭代的需求。而UI自动化能让全功能的回归变得简单,释放纯手工测试的人力资源,并且回归测试能够覆盖到所有的逻辑场景,这对测试的效率,以及整个开发流程的效率都是很大的提升,并且能够规避很多人的主观和客观因素导致的漏测或者疏忽。
其他测试方式的局限性:
单元测试(Unit Testing)
事实上,单元测试确实能够帮助我们发现大部分的问题,但是在复杂的前端交互中,单纯的单元测试并不能真实地反映用户操作的路径,而单元测试一般的场景是测试一系列的功能集合。
快照测试(Snapshot Testing)
DOM结构并不能完全反映页面的视觉效果,DOM结构不变并不完全等于样式不变。此外,大多数工具都是React专用,非React应用基本不支持。
很多人认为,UI总是频繁的变动,导致测试用例维护成本高,性价比低,因此UI自动化测试比较适合场景稳定的业务。其实不是,这里的UI不仅仅指的是视觉,更多的是业务逻辑。UI可以多变,但业务逻辑一定是趋于稳定的,尤其是核心业务,想一想用户得多辛苦才能适应这种业务逻辑频繁变更的产品啊。
实战
第1步:确定功能测试方案
我们将在以下情况下逐步展示执行Puppeteer自动化的方法–
·启动Web浏览器。
·调用Amazon Web应用程序。
- 搜索书籍“ Testing Book”。
- 从结果中将书添加到购物车中。
- 打开购物车,然后检查购物车中是否有书籍。
- 捕获屏幕并关闭浏览器。
Step2#安装Puppeteer并创建测试用例
在特定文件夹中创建一个空的javascript文件作为“ sample_script.js”。 在这里,我们将根文件夹视为SampleProject。 要安装Puppeteer,我们将使用命令–“ npm install puppeteer”。 根据网络速度,安装过程会花费一些时间。 它将下载大约350MB的数据。 安装后,将在示例Puppeteer项目根文件夹中创建包含不同的puppeteer组件和package-lock.json文件的node_modules文件夹。
Step3#捕获测试对象的标识属性
我们可以使用Chrome网络浏览器的开发者工具捕获标识属性。 分析不同的属性,例如id,name,XPath等,我们将选择可以在脚本执行任何操作中使用的正确属性。 在本“ Puppeteer自动化测试”教程中,我们将在脚本中使用XPath。 按照以下步骤获取XPATH或任何其他属性,
打开“菜单->更多工具”下可用的开发人员工具,然后转到“元素”选项卡。
使用 Finder 工具(单击 Elements 选项卡左上角可用的箭头图标),突出显示应用程序中的测试对象。 在这里,我们将检查搜索框。
分析突出显示的源代码以识别期望的属性。 要获取测试对象的XPATH属性,请右键单击突出显示的部分,然后单击“复制->复制Xpath”以将XPATH属性复制到剪贴板中。
现在,将Xpath粘贴到查找器文本框中,然后按Enter键以检查Xpath是否在唯一地标识对象。
同样,我们还需要捕获另一个测试对象的标识属性。
Step4#Puppeteer自动化开发步骤
现在,我们已经了解了使功能场景自动化的基本技术步骤。 基于这些知识,我们可以通过下面的Puppeteer Automation测试案例。 最常用的类和方法的详细概述将在后续文章中进行解释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| /** * @name Amazon search */ const puppeteer = require('puppeteer'); const reportPath = 'C:\\LambdaGeeks\\puppteer_proj_sample\\output\\'; const screenshot = 'screen1.png'; // Used to export the file into a .docx file try { (async () => { const browser = await puppeteer.launch({ headless: false }); const pageNew = await browser.newPage() await pageNew.setViewport({ width: 1280, height: 800 }); await pageNew.goto('https://www.amazon.in/'); //Enter Search criteria let searchBox = await page.waitForXPath("//*[@id='twotabsearchtextbox']",{ visible: true }); if (searchBox === null) { console.log('Amazon screen is not displayed'); } else{ await searchBox.type("Testing Book"); console.log('Search criteria has been entered'); } //Clicked on search button let btnSearch = await pageNew.waitForXPath("//*/input[@id='nav-search-submit-button']",{ visible: true }); if (btnSearch === null) { console.log('Search button is not showing'); } else{ await btnSearch.click(); console.log('Clicked on search button'); } //Click on specific search result let myBook = await pageNew.waitForXPath("//*[contains(text(),'Selenium Testing Tools Cookbook Second Edition')]",{ visible: true }) if (myBook === null) { console.log('Book is not available'); } else{ await myBook.click(); console.log('Click on specific book to order'); } // Identify if the new tab has opened const pageTarget = pageNew.target(); const newTarget = await browser.waitForTarget(target => target.opener() === pageTarget); //get the new page object: const page2 = await newTarget.pageNew(); await page2.setViewport({ width: 1280, height: 800 }); //Add to cart let addToCart = await page2.waitForXPath("//*/input[@id='add-to-cart-button']",{ visible: true }); if (addToCart === null) { console.log('Add to cart button is not available'); } else{ console.log('Click on add to Cart button'); await addToCart.click(); } //Verify add to cart process let successMessage = await page2.waitForXPath("//*[contains(text(),'Added to Cart')]",{ visible: true }); if (successMessage === null) { console.log('Item is not added to cart'); } else{ console.log('Item is added to cart successfully'); } // Capture no of cart let cartCount = await page2.waitForXPath("//*/span[@id='nav-cart-count']",{ visible: true}); let value = await page2.evaluate(el => el.textContent, cartCount) console.log('Cart count: ' + value); cartCount.focus(); await page2.screenshot({ path: screenshot }); await pageNew.waitForTimeout(2000); await page2.close(); await pageNew.close(); await browser.close(); })() } catch (err) { console.error(err) }
|
Step5#木偶自动化测试执行
我们可以使用以下命令启动执行 节点sample_script.js 通过命令提示符。 在执行过程中,将打开Chromium浏览器并自动执行功能步骤,并存储最后一页的屏幕截图。 屏幕截图和控制台输出如下所示。