Android(安卓)IOS UI自动化测试:Appium
移动APP自动化测试框架对比【 腾讯移动品质中心TMQ】
客户端自动化测试研究【美团技术团队】
Appium【github】
Cucumber【github】
环境搭建
【Win下Android环境搭建】
1. Node.js
官网下载安装包并安装
验证:打开cmd,输入npm
2. Java环境
3. Android环境
4. 安装Appium
github 下载Appium,安装(可能会提示缺少.net framework,建议在微软官网上安装对应的)
安装后,直接【Start Server】启动服务。
5.验证Appium环境
npm install -g appium-doctorappium-doctor --android
【Mac下IOS环境搭建】
基本上类似
1.Node.js
官网下载并安装
在mac下的安装目录如下
Node.js v8.11.1 to /usr/local/bin/node
npm v5.6.0 to /usr/local/bin/npm
Make sure that /usr/local/bin is in your $PATH.
安装完之后,可使用node -v查看node版本,npm -v查看npm版本
2.安装carthage
Carthage 是一款iOS项目依赖管理工具,与 Cocoapods 有着相似的功能
brew install carthage
3.安装Appium
github下载Appium并安装,安装后直接【Start Server】启动服务
5.验证Appium环境
npm install -g appium-doctorappium-doctor --ios
脚本环境【Ruby + cucumber】
以一个求和的应用为例,app效果展示如下
1.启动Appium服务,【Start Server】
2.安装Ruby
利用rubyinstaller安装Ruby
3.安装appium_lib,一个支持Appium服务端的ruby客户端
gem update –system
gem update bundler
gem uninstall -aIx appium_lib
gem install –no-rdoc –no-ri appium_lib
4.新建一个test文件夹,新建文件,命名为Gemfile文件【没有后缀】,用编辑器打开,写入以下代码
source 'https://www.rubygems.org'gem 'appium_lib', '~> 9.7.4'gem 'rest-client', '~> 2.0.2'gem 'rspec', '~> 3.6.0'gem 'cucumber', '~> 2.4.0'gem 'rspec-expectations', '~> 3.6.0'gem 'spec', '~> 5.3.4'gem 'sauce_whisk', '~> 0.0.13'gem 'test-unit', '~> 2.5.5' # required for bundle exec ruby xunit_android.rb
保存退出
用Ruby在目录下执行以下命令,安装Ruby依赖(包括cucumber),并初始化cucumber
bundle updatebundle installcucumber --init
生成目录如下
features # 存放feature的目录
├── step_definitions # 存放steps的目录
└── support # 环境配置
└── env.rb
现在对support目录下的env.rb进行修改,改成匹配android和ios两种移动端环境
修改后目录如下
features # 存放feature的目录
├── step_definitions # 存放steps的目录
└── support # 环境配置
├── android
└── appium.txt
├── ios
└── appium.txt
├── env.rb
env.rb修改后变成如下
# This file provides setup and common functionality across all features. It's# included first before every test run, and the methods provided here can be# used in any of the step definitions used in a test. This is a great place to# put shared data like the location of your app, the capabilities you want to# test with, and the setup of selenium.require 'rspec/expectations'require 'appium_lib'require 'cucumber/ast'# Create a custom World class so we don't pollute `Object` with Appium methodsclass AppiumWorldend# Load the desired configuration from appium.txt, create a driver then# Add the methods to the worldcase ENV['PLATFORM']when 'android' caps = Appium.load_appium_txt file: File.expand_path('./android/appium.txt', __FILE__), verbose: truewhen 'ios' caps = Appium.load_appium_txt file: File.expand_path('./ios/appium.txt', __FILE__), verbose: trueendAppium::Driver.new(caps, true)Appium.promote_appium_methods AppiumWorldWorld do AppiumWorld.newendBefore { $driver.start_driver }After { $driver.driver_quit }
android目录下的appium.txt
[caps]platformName = "Android"deviceName = "ca0edc6b"platformVersion = "7.1.1"app = "E:\\test\\app-fast-develop.apk" #apk路径appActivity = "com.android.commonlib.appiumtest.MainActivity"appPackage = "com.android.commonlib.appiumtest"autoGrantPermissions = true # 处理安卓系统弹窗,自动管理授权automationName = "UiAutomator2"
ios目录下的appium.txt
[caps]platformName = "ios"deviceName = "iPhone 8"platformVersion = "11.1"app = "E:\\test\\app-fast-develop.app"automationName = 'XCUITest'autoAcceptAlerts = truewaitForAppScript = "$.delay(5000); $.acceptAlert();" # 授权系统弹窗,真机测试的时候很有用
然后回到features目录,开始编写测试用例,新建sum.feature文件
#language: zh-CN功能: 求和 场景: 验证1+1=2 当 在第一个输入框输入 1 并且 在第二个输入框输入 1 并且 点击计算按钮 那么 结果应该为 2
运行Android测试 bundle exec cucumber PLATFORM=Android,之后报错,把错误信息(主要是要这个流程跟格式,防止自己写写错)拷贝下
step_definitions中新建一个steps.rb
并把刚刚复制的错误信息填写过来,然后进行修改成正真的测试用例,拷贝如下
当(/^在第一个输入框输入 (\d+)$/) do |arg1| pending # Write code here that turns the phrase above into concrete actionsend当(/^在第二个输入框输入 (\d+)$/) do |arg1| pending # Write code here that turns the phrase above into concrete actionsend当(/^点击计算按钮$/) do pending # Write code here that turns the phrase above into concrete actionsend那么(/^结果应该为 (\d+)$/) do |arg1| pending # Write code here that turns the phrase above into concrete actionsend
修改后
当(/^在第一个输入框输入 (\d+)$/) do |arg1| id("a").type arg1end并且(/^在第二个输入框输入 (\d+)$/) do |arg1| id("b").type arg1end并且(/^点击计算按钮$/) do id('submit').clickend那么(/^结果应该为 (\d+)$/) do |arg1| r = id('c').text expect(arg1).to eq(r)end
再次运行 bundle exec cucumber PLATFORM=Android,搞定
脚本环境【Python3 + behave】
1.安装python3
brew install python3
2.安装Appium-Python-Client
除了官方提供的Appium-Python-Client框架,还有一个非官方由网易开源的python客户端facebook-wda;有兴趣可自行了解
pip3 install Appium-Python-Client
3.安装Behave
pip3 install behave
4.查看Behave支持的语言
behave --lang-list
Languages available:ar: العربية / Arabicbg: български / Bulgarianca: català / Catalancs: Česky / Czechcy-GB: Cymraeg / Welshda: dansk / Danishde: Deutsch / Germanen: English / Englishen-Scouse: Scouse / Scouseen-au: Australian / Australianen-lol: LOLCAT / LOLCATen-pirate: Pirate / Pirateen-tx: Texan / Texaneo: Esperanto / Esperantoes: español / Spanishet: eesti keel / Estonianfi: suomi / Finnishfr: français / Frenchgl: galego / Galicianhe: עברית / Hebrewhr: hrvatski / Croatianhu: magyar / Hungarianid: Bahasa Indonesia / Indonesianis: Íslenska / Icelandicit: italiano / Italianja: 日本語 / Japaneseko: 한국어 / Koreanlt: lietuvių kalba / Lithuanianlu: Lëtzebuergesch / Luxemburgishlv: latviešu / Latviannl: Nederlands / Dutchno: norsk / Norwegianpl: polski / Polishpt: português / Portuguesero: română / Romanianru: русский / Russiansk: Slovensky / Slovaksr-Cyrl: Српски / Serbiansr-Latn: Srpski (Latinica) / Serbian (Latin)sv: Svenska / Swedishtr: Türkçe / Turkishuk: Українська / Ukrainianuz: Узбекча / Uzbekvi: Tiếng Việt / Vietnamesezh-CN: 简体中文 / Chinese simplifiedzh-TW: 繁體中文 / Chinese traditional
5.查看对应语言的关键字
behave --lang-help zh-CN
Translations for Chinese simplified / 简体中文 And: 而且< Background: 背景 But: 但是< Examples: 例子 Feature: 功能 Given: 假如< Scenario: 场景Scenario Outline: 场景大纲 Then: 那么< When: 当<
到这里,环境就搭建好了
6.编写测试代码
创建目录如下
├── test# 待测app│ └── app-fast-develop.app└── features ├── calculate.feature # behave待测功能定义 ├── environment.py # 环境配置 └── steps └── step.py # 测试steps
然后编写environment.py环境配置
# -*- coding: utf-8 -*import osfrom appium import webdriverdef before_feature(context, feature): app = 'E:\\test\\app-fast-develop.app' context.driver = webdriver.Remote( command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities={ 'app': app, 'platformName': 'ios', 'deviceName': 'iPhone 8', 'platformVersion': '11.1', 'bundleId': 'com.android.commonlib.appiumtest' })def after_feature(context, feature): context.driver.quit()
编写calculate.feature
#language: zh-CN功能: 求和 场景: 1+1=2 假如 第一个输入框输入 1 而且 第二个输入框输入 1 当 点击计算按钮 那么 结果应该为 2
最后编写steps.py
# -*- coding: utf-8 -*from behave import *@given(u'第一个输入框输入 1')def step_impl(context): el = context.driver.find_element_by_accessibility_id('textfield1') el.clear() el.set_value("1")@given(u'第二个输入框输入 1')def step_impl(context): el = context.driver.find_element_by_accessibility_id('textfield2') el.clear() el.set_value("1")@when(u'点击计算按钮')def step_impl(context): el = context.driver.find_element_by_accessibility_id('sum') el.click()@then(u'结果应该为 2')def step_impl(context): # el = context.driver.find_element_by_accessibility_id('result') el = context.driver.find_element_by_class_name('XCUIElementTypeStaticText') actual = el.get_attribute('value') print(actual) assert actual=='2', 'result is 2'
7.运行测试
behave# 或者behave --lang zh-CN
【Ruby + cucumber 基础用法】
github相关文档
【打印】
puts 'Hello World'#打印instance的所有方法puts instance.methods
【控件定位】
button定位
first_button // 查找第一个buttonbutton(value) // 查找第一个包含value的button,返回[UIAButton|XCUIElementTypeButton]对象buttons(value) // 查找所有包含value的所有buttons,返回[Array]对象 eg:button("登录") // 查找登录按钮
输入框定位
first_textfield // 查找第一个textfieldtextfield(value) // 查找第一个包含value的textfield,返回[TextField]eg:textfield("用户名") // 查找
使用accessibility_id查找
id(value) // 返回id等于value的元素eg:id("登录") // 返回登录按钮id("登录页面") // 返回登录页面
使用find查找
find(value) // 返回包含value的元素find_elements(:class, 'XCUIElementTypeCell') // 通过类名查找eg:find("登录页面")
使用xpath查找
xpath(xpath_str)
web元素定位
#测试web页面首先需要切换driver的上下文web = driver.available_contexts[1]driver.set_context(web)#定位web页面的元素:通过类选择器.re-bb定位css的元素driver.find_elements(:css, ".re-bb")
【参数传递 参数设置】
#arg1 为 (\d+)类型 arg2为"([^"]*)"类型(正则)And(/^在输入框输入 (\d+) "([^"]*)"$/) do |arg1, arg2| #寻找内容为"请输入密码"的输入框,并输入arg1+arg2 textfield("请输入密码").type arg1+arg2 end
【常用事件】
点击事件
#通过坐标点击tap(x: 68, y: 171)#通过按钮元素点击button("登录").click
手势滑动
// 滑动手势swipe(direction:, element: nil) // direction - Either 'up', 'down', 'left' or 'right'.eg: 上滑手势swipe(direction: "up", element: nil)
【延迟】
// waitwait { find("登录页面") } // 等待登录页面加载完成//等待某界面加载完成,等待SplashActivity加载完成,如果超时也会继续往下走,之后再判断SplashActivity是否存在wait{ elements = find_elements(:class, 'SplashActivity') }exist = exists { find_element(:class, 'SplashActivity') }// sleepsleep(2) // 延时2秒
【rspec断言】
相等
expect(actual).to eq(expected) # passes if actual == expectedexpect(actual).to eql(expected) # passes if actual.eql?(expected)expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected))
比较
expect(actual).to be > expectedexpect(actual).to be >= expectedexpect(actual).to be <= expectedexpect(actual).to be < expectedexpect(actual).to be_within(delta).of(expected)
类型判断
expect(actual).to be > expectedexpect(actual).to be >= expectedexpect(actual).to be <= expectedexpect(actual).to be < expectedexpect(actual).to be_within(delta).of(expected)
Bool值比较
expect(actual).to be_truthy # passes if actual is truthy (not nil or false)expect(actual).to be true # passes if actual == trueexpect(actual).to be_falsy # passes if actual is falsy (nil or false)expect(actual).to be false # passes if actual == falseexpect(actual).to be_nil # passes if actual is nilexpect(actual).to_not be_nil # passes if actual is not nil
错误
expect { ... }.to raise_errorexpect { ... }.to raise_error(ErrorClass)expect { ... }.to raise_error("message")expect { ... }.to raise_error(ErrorClass, "message")
异常
expect { ... }.to throw_symbolexpect { ... }.to throw_symbol(:symbol)expect { ... }.to throw_symbol(:symbol, 'value')
【python3 + behave基础用法】
Jenkins集成[Ruby + cucumber] 本部分待续…
输出报表命令
bundle exec cucumber --format html --out ./report/report.html
结果如下
1.Jenkins环境搭建方面参考这个 搭建Jenkins持续集成服务
PS:跑一个简单的demo集成看看
2.然后按照本文所介绍的再服务器上安装Appium测试环境。
PS:服务器本地跑下测试
3.我们可以在【构建】这部分加入测试,除了原来的build,可以加入Execute Shell
把build生成的apk拷贝到测试目录下;
然后进入测试目录运行bundle install安装依赖;
最终运行cucumber命令执行测试并输出报表
cucumber –format json -o ./report/cucumber.json
敏捷实践 (1) - 我们是如何自动化App验收标准
敏捷实践 (2) - appium支持与无法支持的测试
敏捷实践 (3) - Appium Ruby Console
敏捷实践(4) - 我们是如何改进AC
敏捷实践(5) - 敏捷开发=快这里写链接内容
更多相关文章
- Android开发插件的下载与安装
- Unity2018下Android(安卓)SDK设置
- 谷歌CTS测试之GTS测试简介
- 配置Mac Android(安卓)Studio环境
- 基于Cortex-a15的模拟环境搭建——Guest Android
- Android(安卓)NDK r5 windows系统上安装
- Window下Android(安卓)SDK安装
- AndroidKotLin系列--Android(安卓)Studio 第一步使用KotLin
- 如何在Android模拟器上安装apk文件