BDD 快速入门手机自动化测试

imzack · 2018年04月20日 · 最后由 Jason Jing 回复于 2018年04月21日 · 3820 次阅读

代码前的准备

前提条件

无线连接具体操作步骤

1.打开命令行,将手机通过 usb 连接到电脑,执行命令 adb devices 查看设备链接情况,连接接成功后会有如下设备信息显示

$ adb devices
List of devices attached
U10AFH235V8   device

2.命令行运行 adb tcpip 5555 开启手机的 5555 端口

$ adb tcpip 5555
restarting in TCP mode port: 5555

3.手机从电脑上拔下来,查看手机 ip 地址。打开手机 -- 设置--WiFi--ip。以下以魅蓝手机为例,其它手机品牌请自行查找。发现我的 ip 为 192.168.1.5

4.在 PC 端命令行执行 adb connect 192.168.1.5:5555

$ adb connect 192.168.1.5:5555
connected to 192.168.1.5:5555

5.现在再执行 adb devices 可以看到通过 WiFi 连接的设备

$ adb devices
List of devices attached
192.168.1.5:5555        device

6.现在就可以通过 WiFi 来远程操作我们的手机了。

开始编码

编写测试用例

打开 CukeTest,创建一个空的项目。 文件—新建项目—项目类型选择 Basic。

创建成功之后,在 feature 文件中编辑测试用例
例如我们要编写一个简单操作场景

我们也可以将 CukeTest 切换到文本界面,直接将如下代码 复制进去。

# language: zh-CN
功能: 测试手机客户端用例
这是一个使用CukeTest以BDD的方式来做手机端的自动化测试样例。

  场景: API Demo自动化
    假如点击App跳转到App页面
    当在App页面中点击Action Bar
    那么页面应该跳转到Action Bar页面,页面中应该包含"Action Bar Mechanics"

安装项目依赖

正如我们使用其它语言来写手机自动化代码的时候我们需要用到一些第三方的依赖库。同样我们在项目中也需要使用到第三方的库文件。
此次我们用的库如下:

  • Webdriverio: 封装的 web 和手机端的自动化操作控件库
  • @types/webdriverio:帮助我们在 CukeTest 中写代码时能够智能提示的库

在 CukeTest 中安装这些库非常简单:
点击更新包依赖配置—选择添加/删除
输入框中分别输入 “webdriverio” 和 “@types/webdriverio”,CukeTest 会自动帮我们搜索出对应的结果,选择即可。

完成之后直接点击保存,CukeTest 会自动帮我们保存到 package.json 文件中并提示自动下载。

但是因为网络问题,有时可能下载不成功。可以在项目目录下执行 npm install下载依赖包。

生成自动化代码样例

打开 step_definitions/definitions.js 文件
点击我们 feature 文件中操作步骤后面的灰色按钮,CukeTest 会自动为我们生成自动化样例代码到 definitions.js 文件中

配置 appium
打开 appium 桌面版,点击 start server 开启 server

File – New Session Window 打开新的窗口

配置手机客户端

{
  "platformName": "Android",
  "deviceName": "192.168.1.5:5555",
  "appPackage": "io.appium.android.apis",
  "appActivity": "io.appium.android.apis.ApiDemos",
  "resetKeyboard": false,
  "noReset": true
}

  • deviceName: 我们在准备阶段设置好的手机户端地址(请输入自己在命令行输入的值)
  • appPackage: 被测应用的包名
  • appActivity: 被测应用的入口
  • resetKeyboard: 是否重置手机键盘
  • noReset: 不要重新安装手机 app

点击 Start Session 启动 appium 连接手机(注意:手机不要设置锁屏,请最好将手机置于屏幕常亮状态)
此时 appium 应该显示手机客户端打开的界面。

使用 appium 录制脚本

点击 appium 录制按钮
开始录制
选中 App – 点击 tap,appium 会自动远程点击手机姐界面中的 App。

同样的在新的页面中点击 Action Bar 进入到 Action Bar 页面。

操作完成后,点击 Pause Recording 按钮,代码格式选择 Webdriver.io

编写代码
根据 appium 协助生成的代码,完善 definitions1.js 文件

const { Given, When, Then } = require('cucumber');

//// 你的步骤定义 /////


Given(/^点击App跳转到App页面$/, async function () {
    await driver.element("~App").click()

});

When(/^在App页面中点击Action Bar$/, async function () {

    await driver.element("~Action Bar").click()
});

Then(/^页面应该跳转到Action Bar页面,页面中应该包含"([^"]*)"$/, async function (excpetval) {

    return 'pending';
});

但是此时还不能运行,
我们需要使用 webdriverio 库的相关方法创建 driver,在 support 目录下创建 get_driver.js 文件,编写如下代码:

var webdriverio = require('webdriverio');

let options = {
    desiredCapabilities: {
        platformName: "Android",
        // deviceName: "U10AFCPH235V8",
        deviceName:"192.168.1.5:5555",
        platformVersion: "6.0",
        appPackage: "io.appium.android.apis",
        appActivity: "io.appium.android.apis.ApiDemos",
        resetKeyboard: false,
        noReset: true,
    },
    host: "localhost",
    port: 4723
}
//根据您的浏览器配置创建WebDriver实例;
function createDriver() {
    const client = webdriverio.remote(options);
    return client;
}

exports.driver = createDriver();

我们自动化测试需要每个场景运行之后做截屏操作。可以在 support 目录下创建 hooks.js
编写如下代码:

const { After, BeforeAll, Before, AfterAll, setDefaultTimeout } = require('cucumber');
const { driver } = require('./get_driver');

// 设置默认的超时时间
setDefaultTimeout(60 * 1000);

BeforeAll(function(){
    return driver.init();
})

Before(function () {
    //定义场景运行之前
})

After(async function () {
    //定义场景运行之后
    let screenshot = await driver.saveScreenshot();   
    this.attach(screenshot, 'image/png');

});

AfterAll( function () {
    //perform some shared teardown
    return driver.end();
})

在 definitions1.js 文件引入 driver

const { driver } = require('../support/get_driver')

现在点击运行场景,程序应该可以正常运行。你可以看到你的手机自动去按我们操作步骤中定义的那样去运行。
为代码添加断言
引入 assert 库

const assert = require('assert')

完善代码 最终 definitions.js 文件代码

const { Given, When, Then } = require('cucumber');
const assert = require('assert')
const { driver } = require('../support/get_driver')

Given(/^点击App跳转到App页面$/, async function () {

    await driver.element("~App").click();
    let text = await driver.element('~Action Bar').getText();
    return assert.equal(text,'Action Bar')

});

When(/^在App页面中点击Action Bar$/, async function () {

    await driver.element("~Action Bar").click();
});

Then(/^页面应该跳转到Action Bar页面,页面中应该包含"([^"]*)"$/, async function (excpetval) {

    let text = await driver.element('~Action Bar Mechanics').getText();
    return assert.equal(text,excpetval)
});

运行

点击运行项目按钮,
自动运行项目。
运行完成后,自动生成测试报告。在测试报告中可以看到截图的生成以及每一操作步骤的运行情况。

共收到 5 条回复 时间 点赞

为啥不直接用 appium
封装这么一层,有啥好处吗,效率提升了多少

不需要 root

mling 回复

直接用 appium 也可以,我这样做的话,主要把测试用例与自动化代码结合起来,对于刚入门的小伙伴,可以快速上手,另外,不用去定义大量的基础代码。也可以直接用到公司项目中,后期维护起来也很方便。

mling 回复

Appium 是服务器端框架,客户端还是用 WebDriver 等自动化库。自动化库不是测试框架。Cucumber 是一个测试框架,解决的是测试用例管理的问题,也提高了测试脚本的可读性(特别是对整个团队而言)

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册