美文网首页
使用NodeJS+Appium搭建Android自动化测试框架

使用NodeJS+Appium搭建Android自动化测试框架

作者: FredricZhu | 来源:发表于2024-02-06 10:33 被阅读0次

    本例是参考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

    相关文章

      网友评论

          本文标题:使用NodeJS+Appium搭建Android自动化测试框架

          本文链接:https://www.haomeiwen.com/subject/xjscadtx.html