目录
安卓主流的自动化测试框架及对比.................................... 2
Appium工具介绍................................................................. 2
环境搭建.............................................................................. 3
Appium使用实例................................................................. 7
脚本例子............................................................................ 13
安卓主流的自动化测试框架及对比
当前主流的几大自动化测试框架及工具有:
Appium、Robotium、AndroidTest、Monkey、monkeyRuner、UIAutomator、MonkeyTalk
其中适用的范围如下:
Appium测试 (功能测试,用户接受度测试,黑盒测试)
Robotium测试 (功能测试,用户接受度测试,黑盒+白盒测试)
AndroidTest (单元测试,逻辑测试,白盒测试)
Monkey (压力测试)
monkeyRuner (功能测试,用户接受度测试,黑盒测试)
UIAutomator - 官方(黑盒测试,功能测试)
MonkeyTalk (白盒测试,功能测试)
Appium工具介绍
Appium测试相当于黑盒测试,主要测试UI逻辑正确性。同时,也可作为自动化回归使用。
Appium的优势:
采用Appium时,无需对被测应用做任何修改;Appium对iOS和Android的原生自动化测试框架进行了封装,并提供了统一的API(WebDriver API),减少了自动化测试代码的维护工作量;Appium采用Client-Server的架构设计,并采用标准的HTTP通信协议;Server端负责与iOS/Android原生测试框架交互,无需测试人员关注细节实现;Client端基本上可以采用任意主流编程语言编写测试用例,减少了学习成本。
接下来的文章,以Appium工具+python语言进行介绍。
环境搭建
Android测试开发环境配置:
jdk的安装与配置(包括环境变量)
是否安装成功检查:
打开cmd,输入java -version 显示版本信息
android sdk安装与配置(包括环境变量)
是否安装成功检查:
打开cmd,输入adb ,显示:
连接手机:
手机用数据线连电脑,如果安装了91助手或者360什么的可以先下载手机驱动,确认手机能连上,打开cmd输入:adb devices,当屏幕上出现一串字符,后面显示devices说明连接成功(出现其它的提示,得检查自己的环境了)
Appium环境配置:
Python安装与配置(包括环境变量)
是否安装成功检查:
打开cmd,输入python,显示:
安装node.js
下载官网:https://nodejs.org/en/download/23
安装成功后,打开cmd,输入node –v查看版本号,然后输入npm:
出现下图信息后,表示node.js安装成功
安装appium
下载地址:https://bitbucket.org/appium/appium.app/downloads/16
直接双击appium-installer.exe文件安装就好,桌面会生成一个appium的图标,启动后界面显示如下:
安装好后,找到这个文件目录D:\appium\Appium\node_modules\.bin
2.将上面的地址添加到环境变量path下
3.打卡cmd,输入appium-doctor,检查环境是否OK,出现如下图所示,说明环境OK
Python开发环境:
本人使用的是PyCharm 开发工具,来编写代码,用起来还不错,推荐。
Appium使用实例
启动app
启动app需要获取到所测试的包名及launcherActivity,获取的方法很多,比如上一次介绍的当前Activity那个软件,可以获取到;这次介绍一个新的,sdk自带的工具aapt来获取它的包名及launcherActivity。
aapt即Android Asset
Packaging Tool,在SDK的build-tools目录下。需将D:\androidsdk\android-sdk-windows\build-tools\24.0.0目录下找到aapt.exe这个路径设置环境变量,添加到path下
打开cmd,输入aapt:下图表示环境已经OK了
获取apk的包名及launcherActivity
打开cmd输入:aapt dump badging C:\yylc.apk
起始脚本:
# coding=utf-8
from appium import webdriver
import time
import unittest # 导入unittest框架,此文用到了断言
import zidian # 导入字典包
desired_caps = {
'platformName': 'Android',
'deviceName': '5fce0d83',
'platformVersion': '6.0.1',
'appPackage': 'com.test54320',
'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
# 'unicodeKeyboard': True,
# 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
上方的driver的地址,就是appium设置中server的地址
Appium的相关配置如下(点击第一个安卓机器人的图标)
启动appium(三角形变成正方形,表示已启动)
在pycharm上运行脚本(确保手机已连接上电脑)
随后在手机上会弹出安装下面两个软件的提示,安装后,桌面上多两个图标。那么恭喜你启动成功!
接着就能看到我们app启动啦!!!到此为止,环境已经完全通了,接下来就是编写测试用例(脚本)的时候了。
脚本例子
此脚本实现的功能:(从字典中获取手机号及密码,登录app,并对结果页面进行断言)该脚本中会有很多我编写时候的遇到的一些问题所对应的解决办法的注释,注释是精华哈哈!!别忽略了!
源码:
# coding=utf-8
from appium import webdriver
import time
import unittest # 导入unittest框架,此文用到了断言
import zidian # 导入字典包
desired_caps = {
'platformName': 'Android',
'deviceName': '5fce0d83',
'platformVersion': '6.0.1',
'appPackage': 'com.test54320',
'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
# 'unicodeKeyboard': True,
# 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
driver.reset()
print('resetApp ok')
time.sleep(5)
# 判断是否已安装app
print(driver.is_app_installed("com.bench.test54317"))
time.sleep(1)
print('start')
driver.swipe(700, 700, 50, 700)
print('1')
time.sleep(1)
driver.swipe(700, 700, 50, 700)
print('2')
time.sleep(1)
driver.swipe(700, 700, 50, 700)
print('3')
time.sleep(1)
driver.find_element_by_id("com.bench.test54317:id/view_btn_go").click()
print('splash ok !')
time.sleep(3)
'''
driver.find_element_by_xpath("//android.widget.TabHost/android.widget.LinearLayout[contains(@index,3)]").click()
// android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[contains(@index,0)]");
# me = driver.find_element_by_xpath('//android.widget.TabHost/android.widget.LinearLayout[1]')
'''
time.sleep(1)
'''
# find_element_by_xpath中的xpath:/AA/BB[1] 的意思是:选择AA的第一个BB子元素,所以下方的脚本意思是:选择TabHost
# 的第二个LinearLayout的第四个FrameLayout子元素
# me = driver.find_element_by_xpath('//android.widget.TabHost/android.widget.LinearLayout[2]/'
# 'android.widget.FrameLayout[4]')----家里电脑ok
'''
'''
id_text = 'resourceId("com.bench.yylc.test54317:id/tv_main_tab").text("资产")'
print(id_text)
driver.find_element_by_android_uiautomator(id_text).click()
'''
me = driver.find_element_by_xpath("//android.widget.FrameLayout/android.widget.TabHost/"
"android.widget.LinearLayout/android.widget.RelativeLayout[4]")
print(me)
'''
# me1 = driver.find_element_by_id('com.bench.yylc.test54317:id/home_tab_wrapper')
# print(me1)
'''
me.click()
print('me ok')
driver.find_element_by_id("com.bench.test54317:id/viewMeAccount").click()
time.sleep(2)
# 输入手机号 数据字典
'''
创建字典用大括号,数据由 key/value 键值对组成,keys()方法返回字典中的键列表。
values()返回字典中的值列表,items()返回(key,value)元组。
新建一个字典放在lib包中info = zidian.zidian() 获取字典数据
通过.items()循环读取元组(键/值对)
通过info['user2']通过唯一的键名获取值
'''
info = zidian.userpwd()
for us in info.items():
print(us)
driver.find_element_by_id("com.bench.test54317:id/yyinput_edittext").send_keys(info['user1'])
print('input phone ok!')
# 点击下一步
time.sleep(2)
driver.find_element_by_id("com.bench.test54317:id/login_ip_next").click()
time.sleep(2)
# 输入密码
driver.find_element_by_id("com.bench.test54317:id/yyinput_edittext").send_keys(info['password1'])
print('input password ok!')
# 确定按钮
driver.find_element_by_id("com.bench.test54317:id/btn_login_ip_confirm").click()
print('login ok!')
# 对登录结果手机号进行断言
phone = driver.find_element_by_id('com.bench.test54317:id/txt_me_acc_phone').text
print(phone)
# 添加断言,若手机号不正确,则打印错误信息
# 断言1
try:
assert '158****0001' in phone
print('login is right1')
except AssertionError as e:
print('login is Error1')
# 断言2
try:
assert phone == '158****0001'
print('login is right2')
except AssertionError as e:
print('login is Error2')
# 断言3 (unittest)
'''
1. unittest 本身是一个python的测试框架,他有他自己的使用规则;
2. 如果用其中的方法,需要引入,方法:
import unittest
class Login(unittest.TestCase):
其中需要引入unittest,然后声明的类需要继承它的TestCase才可以访问其中的方法。
'''
class test_duanyan(unittest.TestCase):
def test_login(self):
self.assertEqual(phone, '158****0001', 'login assert fail!')
print('login duanyan3')
# 通过resourceId定位元素
id_text = 'resourceId("com.bench.test54317:id/tv_main_tab").text("资产")'
print(id_text)
driver.find_element_by_android_uiautomator(id_text).click()
time.sleep(2)
# 通过resourceId的 兄弟关系fromParent定位元素
brother = 'resourceId("com.bench.test54317:id/ic_main_tab").fromParent(text("首页"))'
print(brother)
driver.find_element_by_android_uiautomator(brother).click()
time.sleep(2)
# 通过resourceId的父子关系childSelector定位元素
son = 'resourceId("com.bench.test54317:id/layout_main_tab").childSelector(text("我"))'
print(son)
driver.find_element_by_android_uiautomator(son).click()
time.sleep(2)
# AssertionError(Exception)
# assertThat(el.getText(),equalTo("158****0001"))
# assertThat(phone,equalTo("158****0001"))
print(driver.current_activity)
time.sleep(5)
# 关闭app应用程序
driver.close_app()
print("close ok ")
# 退出 session
driver.quit()
print("quit ok ")
if __name__ == '__main__':
unittest.main()
# coding=utf-8
from appium import webdriver
import time
import unittest # 导入unittest框架,此文用到了断言
import zidian # 导入字典包
desired_caps = {
'platformName': 'Android',
'deviceName': '5fce0d83',
'platformVersion': '6.0.1',
'appPackage': 'com.test54320',
'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
# 'unicodeKeyboard': True,
# 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)