背景
近期的⾃动化测试项⽬中有个关于测试内部IM通信软件的需求,在了解到各个客户端的相应技术栈实现以后,在mac中的应⽤使⽤的是electron 技术,我们也对相应的技术进⾏调研,此⽂记录⼀下在关于electron应⽤的⾃动化测试。
electron 简介
electron利⽤Chromium和Node.js,为使⽤ JavaScript,HTML 和 CSS 构建跨平台的桌⾯应⽤程序,可以实现代码⼀次编译,多端运⾏的效果,可以⽣成mac app, windows exe等,但是它编译出来的⽂件由于包含Chromium,所以体积⼀般会⽐较⼤。
使⽤selenium操作Chrome浏览器
先确定⼀下系统中的chrome浏览器的版本,由于selenium 操作Chrome浏览器需要使⽤到ChromeDriver,不同版本的Chrome对应着不同的ChromeDriver,如果不对应的话可能会失败。
然后到
ChromeDriver - WebDriver for Chrome - Downloads 这⾥下载对应的ChromeDriver,国内的⽤户如果访问不了的话可以使⽤淘宝镜像源
https://npm.taobao.org/mirrors/chromedriver
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome()
# webdriver.Chrome 在初始化的时候也可以指定chromedriver路径,这种对于系统中有多个版本的
chromedriver⾮常有⽤
# driver = webdriver.Chrome(executable_path="/Users/qihoo/Desktop/chromedriver94")
driver.get("https://www.google.com")
assert "Google" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("360")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()
使⽤selenium操作electron应⽤
想要使⽤ selenium 操作electron app, ⾸先要确认的是该app使⽤的是哪个版本的Chromium那么该如何确认electron应⽤的Chromium版本号呢?
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true, contextIsolation: false //加上这个配置才可以在控制台使⽤process对象
}
})
selenium.common.exceptions.SessionNotCreatedException: Message: session not created:
This version of ChromeDriver only supports Chrome version 94
Current browser version is 80.0.3987.86 with binary path /Applications/360家.app/Contents/MacOS/360家
我们使⽤electron来创建⼀个mac 应⽤,代码使⽤官⽅提供的示例,
但是打包我这⾥和官⽅的不太⼀样。
mkdir electroltest
cd electrontest
npm init -y
npm install electron electron-packager electron-installer-dmg --save
{
"name": "electroltest",
"version": "1.0.0",
"description": "",
"main": "main.js", //修改为main.js
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron .", // 添加⼀个启动指令
"build": "electron-packager .", //添加打包指令
"dmg": "electron-installer-dmg ./electroltest-darwin-x64/electroltest.app/
electroltest" // 添加⽣成dmg指令
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^15.1.2",
"electron-installer-dmg": "^3.0.0",
"electron-packager": "^15.4.0"
}
}
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello YYX!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafeinline';"/>
</head>
<body>
<h1>Hello 360 质量效能 !</h1>
<p>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</p>
</body>
</html>
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})
写完代码以后可以使⽤npm run start 看下效果,是否可以正常的显示electron应⽤
如果正常显示则可以进⾏打包操作
- 打包electron应⽤
npm run build #这⾥是由于在package.json中定义了build指令,如果没有定义也可以运⾏ npxelectron-packager
npm run dmg # 同build指令,这⾥也可以使⽤ npx electron-installer-dmg ./electroltestdarwin-x64/electroltest.app/ electroltest
接下来我们来写⼀个简单的测试,就是打开app,查看⼀下html,再跳转到google,输⼊⼀些⽂字,再点击搜素按钮
/Applications/electroltest.app/Contents/MacOS/electroltest
自己****根据安装的位置进行相应的修改
- 安装 selenium
pip install selenium
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
File Name:eletest
Description : electrol⾃动化测试
Author : qihoo
date:2021/10/14
-------------------------------------------------
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
options = webdriver.ChromeOptions()
options.binary_location = "/Applications/electroltest.app/Contents/MacOS/electroltest"
driver = webdriver.Chrome(chrome_options=options)
time.sleep(3)
print(driver.page_source)
driver.get("http://www.google.com")
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("360") # 这⾥也可以输⼊中⽂
elem.send_keys(Keys.RETURN)
driver.close()
driver.quit()
这⾥⽐较重要的是定义 options.binary_location 需要设置为 electron 应⽤的路径
使⽤selenium操作已经打开的electron应⽤
以上⽅式我们其实是重新打开了某个app, 但是更多的时候,我们是期望测试⼀个已经打开的app,试想⼀下如下的场景,某个app需要登录,登录的⽅式⼜⽐较复杂,扫码登录或者短信登录,或者有验证码,但是如果成功登录以后,⼀段时间以后再次打开就不会进⼊到登录界⾯,此时,我们不希望每次运⾏⽤例的时候,都重新登录,这时,我们就需要使⽤ selenium 来测试⼀个打开着的应⽤。
/Applications/electroltest.app/Contents/MacOS/electroltest --remote-debugging-port=9222
options = webdriver.ChromeOptions()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 设置
debuggerAddress
driver = webdriver.Chrome(chrome_options=options)
总结
使⽤ selenium 测试 electron 应⽤的测试有⼏个总结
找到对应的 chromedriver;
通过 binary_location 参数设置app路径;
对于测试打开着的app, 需要在app启动的时候添加远程调试参数 --remote-debugging-port
参考文献
https://selenium-python-zh.readthedocs.io/en/latest/index.html#