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

2023-09-21 11:54:47

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版本

> navigator.appVersion
< '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版本

> process.versions.electron
< '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 .

选择:


1a56a9b47c1e1fde76fd0c830dbf3735.png

zhongxin@zhongxindeMacBook-Pro demo2 % yarn create wdio .
 yarn create v1.22.19
 [1/4]   Resolving packages...
 [2/4]   Fetching packages...
 [3/4]   Linking dependencies...
 [4/4]   Building fresh packages...

 success Installed "create-wdio@8.2.5" with binaries:
       - create-wdio
 [#####################################################] 53/53
                  -:...........................-:.
                  +                              +
               `` +      `...`        `...`      + `
             ./+/ +    .:://:::`    `::///::`  ` + ++/.
            .+oo+ +    /:+ooo+-/    /-+ooo+-/ ./ + +oo+.
            -ooo+ +    /-+ooo+-/    /-+ooo+-/ .: + +ooo.
             -+o+ +    `::///:-`    `::///::`    + +o+-
              ``. /.     `````        `````     .: .``
                   .----------------------------.
            `-::::::::::::::::::::::::::::::::::::::::-`
           .+oooo/:------------------------------:/oooo+.
       `.--/oooo-                                  :oooo/--.`     .::-``:oooo`                                  .oooo-``-::.
   ./-`    -oooo`--.: :.--                         .oooo-    `-/.
  -/`    `-/oooooooo/.`    `/-
 `+`   `/+oooooooooooooooooooooooooooooooooooooooooooooooo+:`   .+`
 -/    +o/.:oooooooooooooooooooooooooooooooooooooooooooo:-/o/    +.
 -/   .o+  -oooosoooososssssooooo------------------:oooo- `oo`   +.
 -/   .o+  -oooodooohyyssosshoooo`                 .oooo-  oo.   +.
 -/   .o+  -oooodooysdooooooyyooo` `.--.``     .:::-oooo-  oo.   +.
 -/   .o+  -oooodoyyodsoooooyyooo.//-..-:/:.`.//.`./oooo-  oo.   +.
 -/   .o+  -oooohsyoooyysssysoooo+-`     `-:::.    .oooo-  oo.   +.
 -/   .o+  -ooooosooooooosooooooo+//oooo-  oo.   +.
 -/   .o+  -oooooooooooooooooooooooooooooooooooooooooooo-  oo.   +.
 -/   .o+  -oooooooooooooooooooooooooooooooooooooooooooo-  oo.   +.
 -+o+` -oooo---:///:----://::------------------:oooo- `oo+-
 +ooooooo/`-oooo``:-```.:`.:.`.+/-    .::::::::::` .oooo-`+ooooooo+ oooooooo+`-oooo`-- `/` .:+  -/-`/`   .::::::::::  .oooo-.+oooooooo
 +-/+://-/ -oooo-`:`.o-`:.:-````.:    .///:``````  -oooo-`/-//:+:-+
 : :..--:-:.+ooo+/://o+/-.-::-....-::::-....--/+ooo+.:.:--.-- /
 - /./`-:-` .:///+/ooooo/+///+++ooooo/+///:. .-:.`+./ :
 :-:/.           :`ooooo`/`              .:.ooooo :           ./---
                 :`ooooo`/`              .:.ooooo :
                 :`ooooo./`              .:-ooooo :
                 :`ooooo./`              .:-ooooo :
             `...:-+++++:/.              ./:+++++-:...`
            :-.````````/../              /.-:````````.:-
           -/::::::::://:/+             `+/:+::::::::::+.
           :oooooooooooo++/              +++oooooooooooo-                            Webdriver.IO
               Next-gen browser and mobile automation
                     test framework for Node.js


 Installing @wdio/cli to initialize project...
 ✔ Success!

 ===============================  WDIO Configuration Wizard
 ===============================

 ? What type of testing would you like to do? Desktop Testing - of Electron Applications
     > https://webdriver.io/docs/desktop-testing/electron
 ? What is the path to your compiled Electron app? ./dist
 ? Which framework do you want to use? Jasmine (https://jasmine.github.io/)
 ? Do you want to use a compiler? No!
 ? Do you want WebdriverIO to autogenerate some test files? Yes
 ? Where should these files be located? /Users/zhongxin/gitproject/desktopui/demo2/test/specs/**/*.js
 ? Which reporter do you want to use? spec, allure
 ? Do you want to add a plugin to your test setup?
 ? Do you want to add a service to your test setup? electron
 ? Do you want me to run `npm install` Yes


 Installing wdio packages:
 - @wdio/local-runner@latest
 - @wdio/jasmine-framework@latest
 - @wdio/spec-reporter@latest
 - @wdio/allure-reporter@latest
 - wdio-electron-service

 added 78 packages, and changed 1 package in 11s

 97 packages are looking for funding
   run `npm fund` for details
 ✔ Success! Creating a WebdriverIO config file...
 ✔ Success! Autogenerating test files...
 ✔ Success! Adding "wdio" script to package.json.
 ✔ Success! Successfully setup project at /Users/zhongxin/gitproject/desktopui/demo2

 Join our Discord Community Server and instantly find answers to your issues or queries. Or just join and say hi !    https://discord.webdriver.io

 Visit the project on GitHub to report bugs  or raise feature requests :    https://github.com/webdriverio/webdriverio

 To run your tests, execute:
 $ cd /Users/zhongxin/gitproject/desktopui/demo2
 $ npm run wdio

   Done in 72.80s.

安装chromedriver

npm i -D chromedriver@104

修改wdio.conf.js文件

capabilities: [{
        browserName: 'chrome',        'goog:chromeOptions': {
            binary: 'chromedriver/bin/chromedriver', // Electron 二进制文件的路径
            args: [/* 命令行参数 */] // 可选, 比如 'app=' + /path/to/your/app/
        }
    }],

services: [[        'electron',
        {
            appPath: '/Users/zhongxin/Downloads',
            appName: "酷家乐",
            appArgs: ['foo', 'bar=baz'],
            chromedriver: {
                port: 9519,
                logFileName: 'wdio-chromedriver.log',
                chromedriverCustomPath: 'chromedriver/bin/chromedriver' // resolves to chromedriver binary
            },
            electronVersion: '20.3.8',
        }
    ]],

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

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

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

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

Selenium

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

npm init
zhongxin@zhongxindeMacBook-Pro demo2 % npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
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:

{
  "name": "demo2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}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

编写测试脚本

const webdriver = require('selenium-webdriver')const { Builder } = require('selenium-webdriver');

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

playwright

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

安装

npm init playwright@latest

b778d36241035b6db0f079c7e4a26876.png

zhongxin@zhongxindeMacBook-Pro demo3 % npm init playwright@latest
Need to install the following packages:
  create-playwright@1.17.128Ok to proceed? (y)
Getting started with writing end-to-end tests with Playwright:
Initializing project in '.'
✔ Do you want to use TypeScript or JavaScript? · JavaScript
✔ Where to put your end-to-end tests? · tests
✔ Add a GitHub Actions workflow? (y/N) · false
✔ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true
Initializing NPM project (npm init -y)…
Wrote to /Users/zhongxin/gitproject/desktopui/demo3/package.json:

{
  "name": "demo3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


Installing Playwright Test (npm install --save-dev @playwright/test)…

added 3 packages in 5s
Downloading browsers (npx playwright install)…
Writing playwright.config.js.
Writing tests/example.spec.js.
Writing tests-examples/demo-todo-app.spec.js.
Writing package.json.
✔ Success! Created a Playwright Test project at /Users/zhongxin/gitproject/desktopui/demo3

Inside that directory, you can run several commands:

  npx playwright test
    Runs the end-to-end tests.

  npx playwright test --ui
    Starts the interactive UI mode.

  npx playwright test --project=chromium
    Runs the tests only on Desktop Chrome.

  npx playwright test example
    Runs the tests in a specific file.

  npx playwright test --debug
    Runs the tests in debug mode.

  npx playwright codegen
    Auto generate tests with Codegen.

We suggest that you begin by typing:

    npx playwright test

And check out the following files:
  - ./tests/example.spec.js - Example end-to-end test
  - ./tests-examples/demo-todo-app.spec.js - Demo Todo App end-to-end tests
  - ./playwright.config.js - Playwright Test configuration

Visit https://playwright.dev/docs/intro for more information. ✨

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

测试脚本:

const {_electron: electron} = require('@playwright/test');

(async () => {    const electronApp = await electron.launch({
        cwd: '/Users/zhongxin/gitproject/main/app/dist',
        args: ['main.js']
    });    console.log('开始测试')    const window = await electronApp.firstWindow();
    await window.waitForTimeout(3000)    window.on('console', console.log);    console.log(await window.title());
    await window.screenshot({path: 'intro.png'});
    await window.click('text=账号登录');
    await window.fill('input[placeholder="输入手机号/邮箱"]', 'xxxx@xxxx.com')
    await window.fill('input[placeholder="输入密码"]', 'xxxx')
    await window.click('button[title="账密登录"]');
    await window.waitForTimeout(3000)
    await window.locator('text=登录').last().click();
    await window.waitForTimeout(3000)
    await window.screenshot({path: 'test.png'});
    await electronApp.close();
})();

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

Puppeteer

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

npm init

安装相关包

npm i electron@20.3.8 puppeteer-core

运行本地electron并开启调试

const {spawn} = require("child_process");const port = 9200;

spawn(    "/Users/zhongxin/Downloads/mac-arm64/酷家乐.app/Contents/MacOS/酷家乐",
    [`--remote-debugging-port=${port}`],
    {shell: true}
);

编写测试脚本

const puppeteer = require("puppeteer-core");const port = 9200;

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

总结

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

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

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

更多推荐

驱动开发 linux内核GPIO子系统、及其新版API的概念和使用,linux内核定时器

1、GPIO子系统概述:每一个芯片厂商生产出芯片后会给linux提供一个当前芯片中gpio外设的驱动,我们只需要调用对应的厂商驱动就可以完成硬件的控制。而linux内核源码中的gpio厂商驱动有很多,linux内核个会对厂商驱动做一些封装,会提供一系列的API,我们在自己编写设备驱动中只需要调用这些API即可访问对应厂

【微服务】六. Nacos配置管理

6.1Nacos实现配置管理配置更改热更新在nacos左侧新建配置管理DataID:就是配置文件名称一般命名规则:服务名称-环境名称.yaml配置内容填写:需要热更新需求的配置配置文件的id:[服务名称]-[profile].[后缀名]分组,默认即可格式,目前支持yaml和properties6.2微服务配置拉取配置获

iOS应用闪退或崩溃的解决方法

iOS应用的闪退(Crash)通常是应用在运行过程中发生了异常或错误,导致应用崩溃的情况。解决iOS应用的闪退问题需要一些工具和方法,以下是一些建议,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。1.使用Xcode进行调试:Xcode是苹果官方的开发工具,提供了强大的调试功能。你可

专访西藏药业CEO郭远东:数字化转型核心是驱动业务战略实现丨爱分析访谈

[图片]近日,爱分析联合创始人、首席分析师张扬与西藏药业CEO郭远东进行了一次深度对话,就西藏药业整体数字化规划布局、数字化转型过程中面临的痛点及落地实践展开交流。爱分析将通过对各家医药企业数字化转型的探讨和洞悉,为行业提供更多的借鉴。创始于1999年的西藏药业,已成长为产品涵盖生物制药、现代藏药、中药和化学药领域,业

Jetpack:在数据变化时如何优雅更新Views数据

本文讲的是关于Jetpack的架构组件LiveData,LiveData是Lifecycle-aware组件的一个应用,这意味着LiveData遵守Activity、Fragment和Service等组件的生命周期,在它们生命周期处于活跃状态(CREATED和RESUMED)才进行更新Views。使用LiveData步

Smart UI Web 16.0.1 WebComponents htmlelements Crack

JavascriptWeb组件库SmartUIWeb组件库是您构建令人惊叹的Web应用程序所需的唯一套件。它包含70多个快速且专业设计的UI组件,可在单个包中实现美观且始终现代的Web应用程序。具有高级功能的即用型Javascript组件。只需几行代码即可使用数据网格、甘特图、调度程序等复杂组件。Smart是一个基于J

Paper Reading: RSPrompter,基于视觉基础模型的遥感实例分割提示学习

目录简介目标工作重点方法实验总结简介题目:《RSPrompter:LearningtoPromptforRemoteSensingInstanceSegmentationbasedonVisualFoundationModel》,基于视觉基础模型的遥感实例分割提示学习日期:2023.6.28单位:北航、北京数字媒体重点

【结构体类型——详细讲解】

结构体1.结构体类型声明1.1结构体的概念结构体是⼀些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。1.2结构的声明structtag{member-list;}variable-list;例如描述⼀个学⽣:structStu{charname[20];//名字intage;//年龄charsex

【数据结构-树】AVL树

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。推荐:kuan的首页,持续学习,不断总结,共同进步,活到老学到老导航檀越剑指大厂系列:全面总结java核心技术点,如集合,jvm,并发编程redis,kaf

Linux--信号量

一、信号量信号量(semaphore)与已经介绍过的IPC结构不同,他是一个计数器。用于实现进程间的互斥与同步,而不是用于存储进程间的通信数据。可以与共享内存配合使用。临界资源:多道程序系统种存在许多进程,他们共享各种资源,然而有很多资源一次智能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。许多物理设备都属

决策树案例分析

决策树(DecisionTree)常用于研究类别归属和预测关系的模型,比如是否抽烟、是否喝酒、年龄、体重等4项个人特征可能会影响到‘是否患癌症’,上述4项个人特征称作‘特征’,也即自变量(影响因素X),‘是否患癌症’称为‘标签’,也即因变量(被影响项Y)。决策树模型时,其可首先对年龄进行划分,比如以70岁为界,年龄大于

热文推荐