• Electron自动化测试技术选型调研


    Electron简介

    Electron是一个开源的框架,用于构建跨平台的桌面应用程序。它由GitHub开发并于2013年首次发布。Electron允许开发人员使用Web技术(如HTML、CSS和JavaScript)来构建桌面应用程序,同时可以在Windows、macOS和Linux等操作系统上运行。

    以下是一些关键特点和优势:

    1. 跨平台:Electron可以在多个操作系统上运行,包括Windows、macOS和Linux。这意味着开发人员可以使用相同的代码库构建应用程序,并在不同的平台上进行部署。

    2. 基于Web技术:Electron使用Web技术作为应用程序的构建基础。开发人员可以使用HTML、CSS和JavaScript来构建用户界面和应用逻辑,这使得开发过程更加熟悉和容易上手。

    3. 强大的生态系统:Electron拥有庞大的开发者社区和丰富的第三方库和插件。开发人员可以利用这些资源来加速开发过程、解决问题和扩展应用程序功能。

    4. 自定义能力:Electron提供了丰富的API,可以访问底层操作系统的功能。开发人员可以利用这些API来实现与操作系统交互、访问文件系统、创建系统托盘应用等功能。

    5. 调试和工具支持:Electron集成了开发者工具,包括Chrome开发者工具,可以帮助开发人员进行调试和性能优化。此外,还有许多第三方工具和库可以用于构建、测试和部署Electron应用程序。

    6. 应用程序分发:Electron提供了打包和分发应用程序的工具。开发人员可以将应用程序打包为可执行文件或安装程序,并将其发布到应用商店或通过其他方式分发给用户。

    Electron已经被广泛应用于各种领域,包括代码编辑器、聊天应用程序、桌面客户端等。许多知名的应用程序,如Visual Studio Code、Slack和GitHub Desktop,都是使用Electron构建的。

    总之,Electron提供了一种简化和加速桌面应用程序开发的方式,使开发人员能够利用熟悉的Web技术构建跨平台的应用程序。

    是当前酷家乐桌面客户端的底层技术

    框架简介

    在官方文档中介绍了3种(使用 WebDriver 接口,使用 Playwright,使用自定义测试驱动)进行自动化测试的方式:

    https://www.electronjs.org/zh/docs/latest/tutorial/automated-testing

    根据实际操作后发现,官网的操作的省略了很多关键步骤,而且无法直接跑通我们自己项目,需要一定的调研

    查阅puppeteer-electron相关仓库:

    https://github.com/peterdanis/electron-puppeteer-demo

    https://github.com/nondanee/puppeteer-electron

    方式框架star数量GPT给出的优点GPT给出的缺点
    使用 WebDriver 接口WebdriverIO8.2kWebdriverIO是一个成熟的Web自动化测试框架,支持多种浏览器和平台。它提供了丰富的API和插件,使得测试编写更加方便和灵活。具有强大的等待机制,可确保元素可见性和页面加载完成。支持并行测试执行,提高测试效率。社区活跃,文档丰富,易于学习和使用。由于WebdriverIO是基于WebDriver协议的,因此执行速度可能相对较慢。在处理某些特殊情况下,如处理模态对话框和桌面应用程序时,可能会遇到一些困难。
    Selenium/
    27.2kSelenium是最广泛使用的Web自动化测试框架,支持多种编程语言和浏览器。具有强大的定位元素的能力,能够灵活地与页面交互。支持并行执行测试,提高了测试效率。社区庞大,可以获得广泛的支持和资源。Selenium不是为桌面应用程序设计的,因此在测试Electron应用程序时可能会遇到一些限制和问题。对于某些高级功能,如处理模态对话框和文件上传,可能需要编写自定义逻辑。
    使用 Playwrightplaywright53.6kPlaywright是一个新兴的跨浏览器自动化测试框架,支持多个浏览器和平台。它提供了一个简洁的API,可以轻松地与页面交互和操作元素。具有强大的等待机制,可以等待元素出现和页面加载完成。支持截图、录屏等高级功能。相对于Selenium和WebdriverIO,Playwright的社区规模较小,可能会找到较少的资源和支持。在某些特殊情况下,如处理桌面应用程序和模态对话框时,可能会遇到一些限制。
    使用自定义测试驱动node96.9k//
    远程debugPuppeteer84.1k强大的浏览器自动化:Puppeteer提供了一套简洁而强大的API,可以用于模拟用户在浏览器中进行各种操作,如点击、填写表单、截图等。完全控制浏览器环境:Puppeteer可以控制底层的Chromium浏览器实例,从而能够修改和监控浏览器的各个方面,例如网络请求、用户代理、存储等,使得测试更加灵活和可靠。支持调试和错误排查:Puppeteer具有调试工具,可以帮助开发人员定位和修复测试中的问题,包括视觉回归问题、性能问题等。多平台支持:Puppeteer可以运行在多个平台上,包括Windows、Mac和Linux,适用于跨平台的Electron应用程序的自动化测试。学习曲线陡峭:Puppeteer的API相对复杂,需要一定的学习成本,特别是对于没有过多浏览器自动化经验的人来说。执行速度相对较慢:由于需要通过启动浏览器、模拟用户交互等步骤,使用Puppeteer进行自动化测试可能会比其他测试框架的执行速度慢一些。测试环境配置:使用Puppeteer进行Electron自动化测试需要配置好相关环境,包括安装正确版本的Chromium浏览器和Puppeteer库,这可能会带来一些麻烦。

    前置准备

    使用navigator.appVersion查看当前客户端使用的chromedriver版本

    1. > navigator.appVersion
    2. < '104.0.5112.124 qunheclient/1.0.0 kujialesoft/12.3.9 kujialeclient/12.3.9 utm_industry=kujiale/12.3.9 utm_campaign=autoUpdate'

    使用process.versions.electron查看当前客户端electron版本

    1. > process.versions.electron
    2. < '20.3.8'

    设置国内ELECTRON源

    npm config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/

    框架试用Demo

    WebdriverIO

    相关文档:https://webdriver.io/docs/desktop-testing/electron/

    需要node版本为16+

    使用脚手架安装:

    yarn create wdio .

    选择:


    98e24c19c5be852d460d03a82050acfe.png

    1. zhongxin@zhongxindeMacBook-Pro demo2 % yarn create wdio .
    2. yarn create v1.22.19
    3. [1/4] Resolving packages...
    4. [2/4] Fetching packages...
    5. [3/4] Linking dependencies...
    6. [4/4] Building fresh packages...
    7. success Installed "create-wdio@8.2.5" with binaries:
    8. - create-wdio
    9. [#####################################################] 53/53
    10. -:...........................-:.
    11. + +
    12. `` + `...` `...` + `
    13. ./+/ + .:://:::` `::///::` ` + ++/.
    14. .+oo+ + /:+ooo+-/ /-+ooo+-/ ./ + +oo+.
    15. -ooo+ + /-+ooo+-/ /-+ooo+-/ .: + +ooo.
    16. -+o+ + `::///:-` `::///::` + +o+-
    17. ``. /. ````` ````` .: .``
    18. .----------------------------.
    19. `-::::::::::::::::::::::::::::::::::::::::-`
    20. .+oooo/:------------------------------:/oooo+.
    21. `.--/oooo- :oooo/--.` .::-``:oooo` .oooo-``-::.
    22. ./-` -oooo`--.: :.-- .oooo- `-/.
    23. -/` `-/oooooooo/.` `/-
    24. `+` `/+oooooooooooooooooooooooooooooooooooooooooooooooo+:` .+`
    25. -/ +o/.:oooooooooooooooooooooooooooooooooooooooooooo:-/o/ +.
    26. -/ .o+ -oooosoooososssssooooo------------------:oooo- `oo` +.
    27. -/ .o+ -oooodooohyyssosshoooo` .oooo- oo. +.
    28. -/ .o+ -oooodooysdooooooyyooo` `.--.`` .:::-oooo- oo. +.
    29. -/ .o+ -oooodoyyodsoooooyyooo.//-..-:/:.`.//.`./oooo- oo. +.
    30. -/ .o+ -oooohsyoooyysssysoooo+-` `-:::. .oooo- oo. +.
    31. -/ .o+ -ooooosooooooosooooooo+//oooo- oo. +.
    32. -/ .o+ -oooooooooooooooooooooooooooooooooooooooooooo- oo. +.
    33. -/ .o+ -oooooooooooooooooooooooooooooooooooooooooooo- oo. +.
    34. -+o+` -oooo---:///:----://::------------------:oooo- `oo+-
    35. +ooooooo/`-oooo``:-```.:`.:.`.+/- .::::::::::` .oooo-`+ooooooo+ oooooooo+`-oooo`-- `/` .:+ -/-`/` .:::::::::: .oooo-.+oooooooo
    36. +-/+://-/ -oooo-`:`.o-`:.:-````.: .///:`````` -oooo-`/-//:+:-+
    37. : :..--:-:.+ooo+/://o+/-.-::-....-::::-....--/+ooo+.:.:--.-- /
    38. - /./`-:-` .:///+/ooooo/+///+++ooooo/+///:. .-:.`+./ :
    39. :-:/. :`ooooo`/` .:.ooooo : ./---
    40. :`ooooo`/` .:.ooooo :
    41. :`ooooo./` .:-ooooo :
    42. :`ooooo./` .:-ooooo :
    43. `...:-+++++:/. ./:+++++-:...`
    44. :-.````````/../ /.-:````````.:-
    45. -/::::::::://:/+ `+/:+::::::::::+.
    46. :oooooooooooo++/ +++oooooooooooo- Webdriver.IO
    47. Next-gen browser and mobile automation
    48. test framework for Node.js
    49. Installing @wdio/cli to initialize project...
    50. ✔ Success!
    51. =============================== WDIO Configuration Wizard
    52. ===============================
    53. ? What type of testing would you like to do? Desktop Testing - of Electron Applications
    54. > https://webdriver.io/docs/desktop-testing/electron
    55. ? What is the path to your compiled Electron app? ./dist
    56. ? Which framework do you want to use? Jasmine (https://jasmine.github.io/)
    57. ? Do you want to use a compiler? No!
    58. ? Do you want WebdriverIO to autogenerate some test files? Yes
    59. ? Where should these files be located? /Users/zhongxin/gitproject/desktopui/demo2/test/specs/**/*.js
    60. ? Which reporter do you want to use? spec, allure
    61. ? Do you want to add a plugin to your test setup?
    62. ? Do you want to add a service to your test setup? electron
    63. ? Do you want me to run `npm install` Yes
    64. Installing wdio packages:
    65. - @wdio/local-runner@latest
    66. - @wdio/jasmine-framework@latest
    67. - @wdio/spec-reporter@latest
    68. - @wdio/allure-reporter@latest
    69. - wdio-electron-service
    70. added 78 packages, and changed 1 package in 11s
    71. 97 packages are looking for funding
    72. run `npm fund` for details
    73. ✔ Success! Creating a WebdriverIO config file...
    74. ✔ Success! Autogenerating test files...
    75. ✔ Success! Adding "wdio" script to package.json.
    76. ✔ Success! Successfully setup project at /Users/zhongxin/gitproject/desktopui/demo2
    77. Join our Discord Community Server and instantly find answers to your issues or queries. Or just join and say hi ! https://discord.webdriver.io
    78. Visit the project on GitHub to report bugs or raise feature requests : https://github.com/webdriverio/webdriverio
    79. To run your tests, execute:
    80. $ cd /Users/zhongxin/gitproject/desktopui/demo2
    81. $ npm run wdio
    82. Done in 72.80s.

    安装chromedriver

    npm i -D chromedriver@104

    修改wdio.conf.js文件

    1. capabilities: [{
    2. browserName: 'chrome', 'goog:chromeOptions': {
    3. binary: 'chromedriver/bin/chromedriver', // Electron 二进制文件的路径
    4. args: [/* 命令行参数 */] // 可选, 比如 'app=' + /path/to/your/app/
    5. }
    6. }],
    7. services: [[ 'electron',
    8. {
    9. appPath: '/Users/zhongxin/Downloads',
    10. appName: "酷家乐",
    11. appArgs: ['foo', 'bar=baz'],
    12. chromedriver: {
    13. port: 9519,
    14. logFileName: 'wdio-chromedriver.log',
    15. chromedriverCustomPath: 'chromedriver/bin/chromedriver' // resolves to chromedriver binary
    16. },
    17. electronVersion: '20.3.8',
    18. }
    19. ]],

    以mac m1电脑为例,从官网下载客户端后,打开dmg文件,将酷家乐.app放到/Users/zhongxin/Downloads/mac-arm64/酷家乐.app位置

    修改一下测试脚本test.e2e.js,完成登录

    1. import { browser } from '@wdio/globals'describe('Electron Testing', () => {
    2. it('should print application metadata', async () => { console.log('听白测试')
    3. await browser.$('//*[text()="账号登录"]').click()
    4. await browser.$('//input[@placeholder="输入手机号/邮箱"]').setValue("xxxx@xxxx.com")
    5. await browser.$('//input[@placeholder="输入密码"]').setValue("xxxx")
    6. await browser.$('//button[text()="登录"]').click()
    7. await browser.pause(5000)
    8. await browser.saveScreenshot('./test.png')
    9. })
    10. })

    运行测试wdio run ./wdio.conf.js后会唤起客户端并完成登录操作,然后进行截图

    Selenium

    新建一个空文件夹,使用npm进行初始化

    npm init
    1. zhongxin@zhongxindeMacBook-Pro demo2 % npm init
    2. This utility will walk you through creating a package.json file.
    3. It only covers the most common items, and tries to guess sensible defaults.
    4. See `npm help init` for definitive documentation on these fields
    5. and exactly what they do.
    6. Use `npm install ` afterwards to install a package and
    7. save it as a dependency in the package.json file.
    8. Press ^C at any time to quit.
    9. package name: (demo2)version: (1.0.0)description:entry point: (index.js)test command:git repository:keywords:author:license: (ISC)About to write to /Users/zhongxin/gitproject/desktopui/demo2/package.json:
    10. {
    11. "name": "demo2",
    12. "version": "1.0.0",
    13. "description": "",
    14. "main": "index.js",
    15. "scripts": {
    16. "test": "echo \"Error: no test specified\" && exit 1"
    17. },
    18. "author": "",
    19. "license": "ISC"
    20. }Is this OK? (yes)

    安装&运行chromedriver

    npm install --save-dev electron-chromedriver@20.0.0./node_modules/.bin/chromedriver

    安装selenium

    npm install --save-dev selenium-webdriver

    编写测试脚本

    1. const webdriver = require('selenium-webdriver')const { Builder } = require('selenium-webdriver');
    2. (async function myTest() { let driver = await new Builder()
    3. .usingServer('http://localhost:9515')
    4. .withCapabilities({ 'goog:chromeOptions': {
    5. binary: '/Users/zhongxin/Downloads/mac-arm64/酷家乐.app/Contents/MacOS/酷家乐'
    6. }
    7. })
    8. .forBrowser('chrome') // 注意: 使用 .forBrowser('electron') for selenium-webdriver <= 3.6.0
    9. .build() console.log('听白测试')
    10. await driver.sleep(5000)
    11. await driver.findElement(webdriver.By.xpath('//*[text()="账号登录"]')).click()
    12. await driver.findElement(webdriver.By.xpath('//input[@placeholder="输入手机号/邮箱"]')).sendKeys("xxxx@xxxx.com")
    13. await driver.findElement(webdriver.By.xpath('//input[@placeholder="输入密码"]')).sendKeys("xxxx")
    14. await driver.findElement(webdriver.By.xpath('//button[text()="登录"]')).click()
    15. await driver.sleep(5000)
    16. await driver.takeScreenshot().then( function (image, err) { require('fs').writeFile('test.png', image, 'base64', function (err) { console.log(err)
    17. })
    18. })
    19. await driver.quit()
    20. })();

    playwright

    官方文档:https://playwright.dev/docs/api/class-electron

    安装

    npm init playwright@latest

    a856675f0a9706f5f49a608d169a4f16.png

    1. zhongxin@zhongxindeMacBook-Pro demo3 % npm init playwright@latest
    2. Need to install the following packages:
    3. create-playwright@1.17.128Ok to proceed? (y)
    4. Getting started with writing end-to-end tests with Playwright:
    5. Initializing project in '.'
    6. ✔ Do you want to use TypeScript or JavaScript? · JavaScript
    7. ✔ Where to put your end-to-end tests? · tests
    8. ✔ Add a GitHub Actions workflow? (y/N) · false
    9. ✔ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true
    10. Initializing NPM project (npm init -y)…
    11. Wrote to /Users/zhongxin/gitproject/desktopui/demo3/package.json:
    12. {
    13. "name": "demo3",
    14. "version": "1.0.0",
    15. "description": "",
    16. "main": "index.js",
    17. "scripts": {
    18. "test": "echo \"Error: no test specified\" && exit 1"
    19. },
    20. "keywords": [],
    21. "author": "",
    22. "license": "ISC"
    23. }
    24. Installing Playwright Test (npm install --save-dev @playwright/test)…
    25. added 3 packages in 5s
    26. Downloading browsers (npx playwright install)…
    27. Writing playwright.config.js.
    28. Writing tests/example.spec.js.
    29. Writing tests-examples/demo-todo-app.spec.js.
    30. Writing package.json.
    31. ✔ Success! Created a Playwright Test project at /Users/zhongxin/gitproject/desktopui/demo3
    32. Inside that directory, you can run several commands:
    33. npx playwright test
    34. Runs the end-to-end tests.
    35. npx playwright test --ui
    36. Starts the interactive UI mode.
    37. npx playwright test --project=chromium
    38. Runs the tests only on Desktop Chrome.
    39. npx playwright test example
    40. Runs the tests in a specific file.
    41. npx playwright test --debug
    42. Runs the tests in debug mode.
    43. npx playwright codegen
    44. Auto generate tests with Codegen.
    45. We suggest that you begin by typing:
    46. npx playwright test
    47. And check out the following files:
    48. - ./tests/example.spec.js - Example end-to-end test
    49. - ./tests-examples/demo-todo-app.spec.js - Demo Todo App end-to-end tests
    50. - ./playwright.config.js - Playwright Test configuration
    51. Visit https://playwright.dev/docs/intro for more information. ✨
    52. Happy hacking!

    安装electron

    npm i electron@20.3.8

    运行开发项目:

    https://gitlab.qunhequnhe.com/fe/up/desktop

    https://gitlab.qunhequnhe.com/desktop/base/main

    生成入口文件:/Users/zhongxin/gitproject/main/app/dist/main.js

    测试脚本:

    1. const {_electron: electron} = require('@playwright/test');
    2. (async () => { const electronApp = await electron.launch({
    3. cwd: '/Users/zhongxin/gitproject/main/app/dist',
    4. args: ['main.js']
    5. }); console.log('开始测试') const window = await electronApp.firstWindow();
    6. await window.waitForTimeout(3000) window.on('console', console.log); console.log(await window.title());
    7. await window.screenshot({path: 'intro.png'});
    8. await window.click('text=账号登录');
    9. await window.fill('input[placeholder="输入手机号/邮箱"]', 'xxxx@xxxx.com')
    10. await window.fill('input[placeholder="输入密码"]', 'xxxx')
    11. await window.click('button[title="账密登录"]');
    12. await window.waitForTimeout(3000)
    13. await window.locator('text=登录').last().click();
    14. await window.waitForTimeout(3000)
    15. await window.screenshot({path: 'test.png'});
    16. await electronApp.close();
    17. })();

    这种方式非常的麻烦,比较适合在开发阶段进行测试

    Puppeteer

    新建一个空文件夹,使用npm进行初始化

    npm init

    安装相关包

    npm i electron@20.3.8 puppeteer-core

    运行本地electron并开启调试

    1. const {spawn} = require("child_process");const port = 9200;
    2. spawn( "/Users/zhongxin/Downloads/mac-arm64/酷家乐.app/Contents/MacOS/酷家乐",
    3. [`--remote-debugging-port=${port}`],
    4. {shell: true}
    5. );

    编写测试脚本

    1. const puppeteer = require("puppeteer-core");const port = 9200;
    2. (async () => { let app = await puppeteer.connect({
    3. browserURL: `http://localhost:${port}`,
    4. }); const pages = await app.pages(); const [page] = pages;
    5. await (await page.$x('//button[text()="账号登录"]'))[0].click();
    6. await (await page.$x('//input[@placeholder="输入手机号/邮箱"]'))[0].type('xxxx@xxxx.com')
    7. await (await page.$x('//input[@placeholder="输入密码"]'))[0].type('xxxx');
    8. await (await page.$x('//button[text()="登录"]'))[0].click();
    9. await page.screenshot({path: 'test.png'});
    10. setTimeout(async () => await app.close(), 5000)
    11. })()

    总结

    框架环境准备支持情况
    WebdriverIO简单:将下载到的安装包放到指定路径下即可支持较好
    Selenium中等:将下载到的安装包放到指定路径+启动chromedriver支持一般
    playwright困难:部署&运行代码实验性质
    Puppeteer中等:将下载到的安装包放到指定路径+启动应用支持一般

    由于Hades采用的是Puppeteer,优先考虑使用Puppeteer

    后续封装一个启动electron的操作,将它加在beforeAll里,就可以复用之前旧的UI自动化测试代码了

  • 相关阅读:
    Notion 开源替代品 AFFINE 部署和使用教程
    Spring Boot 整合 RestTemplate:详解与实战
    Hive环境搭建_远程部署
    Spring如何解决循环依赖问题
    手把手带你实现基于 Vite+Vue3 的在线Excel表格系统
    springboot3:web开发
    纯干货无广告,毕业大论文,如何优雅地拼拼凑凑,降重和润色
    Keycloak服务开发-认证服务SPI
    爬虫工作流程、请求与响应原理、requests库讲解
    JavaWeb简单实例——Ajax请求
  • 原文地址:https://blog.csdn.net/weixin_37786060/article/details/133153348