本例是参考Youtube NodeJS Appium教程自己写的框架,没有直接用作者给的框架,但是Android测试的方方面面都已经支持,而且简单好用。
Android的环境搭建方面,可以参考如下视频,只需要管SDK就可以, AndroidStudio部分处理完之后可以删掉。另外需要注意的一个点是uiautomatorviewer这个组件已经过期,不可用了。不用刻意去找tools目录了。直接用appium_inspector去inspect元素即可
https://www.acfun.cn/v/ac43667234
工程的整体代码在如下repo,
https://gitlab.com/zhuge20100104/cpp_practice/-/tree/master/automation/appiums/6_page_objects?ref_type=heads
包括并发执行,截图等等。
测试框架基于Mocha Test FrameWork + Appium + WebDriverIO。
相关组件版本
nodejs: v18.19.0
appium server: 1.22.3
appium_inspector: 在这里下载Latest Release就可以了
各种包,
"dependencies": {
"mochawesome": "^7.1.3",
"webdriverio": "^6.4.6",
"chai": "^4.4.1"
},
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/register": "^7.11.5"
}
程序代码如下,
package.json
{
"name": "6_page_objects",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"extension": "js",
"scripts": {
"test": "mocha --file ./src/test_scripts/account/TC_001_Login.js --no-timeouts --reporter mochawesome && cp -rf ./screenshot ./mochawesome-report"
},
"author": "",
"license": "ISC",
"dependencies": {
"mochawesome": "^7.1.3",
"webdriverio": "^6.4.6",
"chai": "^4.4.1"
},
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/register": "^7.11.5"
}
}
utils/Consts.js
const capabilities = {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:udid": "R28M32MWVBH",
"appium:appPackage": "com.wdiodemoapp",
"appium:appActivity": ".MainActivity",
"appium:noReset": true
}
const wdOpts = {
hostname: process.env.APPIUM_HOST || 'localhost',
path: "/wd/hub",
port: parseInt(process.env.APPIUM_PORT, 10) || 4723,
logLevel: 'info',
capabilities,
waitforTimeout: 6000
};
export {capabilities, wdOpts}
utils/Funcs.js
import { wdOpts } from './Consts.js';
import {remote} from 'webdriverio';
import pkg from 'mochawesome/addContext.js'
const addContext = pkg;
let getDriver = async (wd_opts) => {
return await remote(wd_opts)
}
global.driver = await getDriver(wdOpts)
global.$ = (selector) => driver.$(selector)
global.$$ = (selector) => driver.$$(selector)
let releaseResource = async (driver_) => {
console.log("releaseResource")
await driver_.pause(1000)
await driver_.deleteSession()
}
let screenShot = async function(ctx, driver_, path_) {
addContext(ctx, path_)
await driver_.saveScreenshot(path_)
}
let releaseEach = async function(ctx, driver_, path_) {
if(ctx.currentTest.state !== 'passed') {
screenShot(ctx, driver_, path_)
}
}
export {releaseResource, addContext, screenShot, releaseEach }
page_objects/account/Login.js
import { expect } from "chai";
const LOGIN_ICON_HOME_SCREEN = '~Login'
const EMAIL_TEXT_FIELD = '~input-email'
const PASSWORD_TEXT_FIELD = '~input-password'
const LOGIN_BTN = '~button-LOGIN'
const SUCCESS_MSG = '//android.widget.TextView[@resource-id="android:id/message"]'
class Login {
async is_on_home_page() {
await $(LOGIN_ICON_HOME_SCREEN).then(async ele => await ele.waitForDisplayed())
return await $(LOGIN_ICON_HOME_SCREEN).then(async ele => await ele.isDisplayed())
}
async go_to_login_page() {
await $(LOGIN_ICON_HOME_SCREEN).then(async ele => await ele.click())
await $(LOGIN_BTN).then(async ele => await ele.waitForDisplayed())
return await $(LOGIN_BTN).then(async ele => await ele.isDisplayed())
}
async login() {
await $(EMAIL_TEXT_FIELD).then(async ele => await ele.setValue('a@a.com'))
await $(PASSWORD_TEXT_FIELD).then(async ele => await ele.setValue('12345678'))
await $(LOGIN_BTN).then(async ele => await ele.click())
}
async is_login_successful() {
await $(SUCCESS_MSG).then(async ele => await ele.waitForDisplayed())
let text = await $(SUCCESS_MSG).then(async ele => await ele.getText())
console.log("Text is: " + text)
expect(text).to.equal("You are logged in!!")
return true
}
}
export {Login}
test_scripts/account/TC_001_Login.js
import { releaseResource, addContext, releaseEach } from '../../utils/Func.js';
import { Login } from '../../page_objects/account/Login.js';
describe('Learning WebdriverIO API', () => {
after(async function() {
releaseResource(driver)
})
afterEach(async function() {
releaseEach(this, driver, './screenshot/login.png')
})
it('should click on Login Icon successfully', async function () {
let login = new Login()
await login.is_on_home_page()
addContext(this, 'Go to home page successfully')
await login.go_to_login_page()
addContext(this, 'Go to login page successfully')
await login.login()
addContext(this, 'Login')
await login.is_login_successful()
addContext(this, 'Login successfully')
});
});
本例故意用了一个错误的chai assert,好让大家看一下错误以后截图的效果
Report
image.png image.png image.png
网友评论