第一章 认识Appium,环境搭建,实战开发登录自动化脚本(完成)

第二章 Appium 自动化功能参数设置和API学习(完成)

第三章 Appium 自动化项目工程,框架方法封装,自动化登录脚本实战(完成)

第四章 Appium 自动化对接robot framework,让自动化实现更高效(待更新)

第五章 Appium 自动化接入jenkins&自动化报告邮件,CI Run起来(待更新)

第六章 FQA(待更新)

第一章 认识Appium,环境搭建,实战开发登录自动化脚本

1.1 Appium 框架介绍

Appium是一个开源、跨平台的测试框架,可以用来测试原生及混合的移动端应用。Appium支持IOS、Android及FirefoxOS平台。Appium使用WebDriver的json wire协议,来驱动Android系统的UIAutomator框架。Appium也集成了Selendroid,来支持老android版本。Appium集成FaceBook的WDA在客户端实现一个WebDriver server,借助这个server远程控制iOS设备实现自动化。

1.1.1 Appium 框架原理

Appium 是在手机操作系统自带的测试框架基础上实现的,Android自带的UI自动化测试工具是“ UIAutomator”。

Appium框架原理如图1-1-1所示,由Appium Client客户端和Appium Server服务器两部分构成。

「手把手」一起Android自动化

图1-1-1 Appium架构原理

图1-1-1含义解析如下:

1. 第1部分为Appium client(客户端):主要是测试脚本和Appium Client。

    a. Appium Client:主要实现了Appium功能的WebDriver协议的Library(如python的:Appium-Python-Client)并负责与Appium Server通信。Appium Client 与Appium Server进行通信时会先发送一组Desired Capabilities(后面章节会详细介绍Desired Capabilities内容)的Json对象给Appium Server请求建立会话Session,Appium Server收到请求数据后就创建一个会话连接Session,并将该SessionId返给Appium Client(就是我们用到的driver)。然后自动化脚本命令都用这个SessionId(driver)来跟Appium Server发送命令。目前支持的Appium客户端Library有多种语言(Python,Ruby,Java,JavaScript,PHP,C#,Object C),本书就是基于Python来讲解。  没Python基础的伙伴可以边学习本书边学习python(后续我也会专门开一本《「手把手」学习Python》)。

    b. TestScripts:自动化脚本(比如本书就是用的Python来编写自动化脚本)。

2. 第2部分为Appium Server(Appium服务器):Appium Server是一个基于Node.js实现的HTTP服务器,是Appium框架的核心。主要是接受Appium Client发起的连接,监听Appium Client发来的命令,并将命令发送给Bootstrap.jar(他就会在手机上面执行),然后将Bootstrap.jar执行返回的结果返回给Appium Client。

3. 第3部分为Bootstrap.jar:Bootstrap.jar是运行在手机上面的一个程序,该程序接收Appium Server发送过来的命令,并在测试手机上执行测试,然后把执行结果再返给Appium Server。Appium Server与Bootstrap.jar之间是通过TCP来通信,该通信由Appium Server发起建立。

4. 第4部分是什么呢,暂时不讲,后续会在「手把手」一起iOS自动化中专门讲。 

1.1.2 Appium 框架特点

1. Appium Client 存在多种的语言实现,所以测试人员可以选择自己熟悉的语言来开发自动化脚本。

2. Appium框架支持多中应用程序的测试(可以用来测试原生及混合的移动端应用)。

3. Appium框架被测试的应用一般不需要特殊编译,一般情况可以直接拿来测试。

4. Appium框架可以跨平台,很多API可以同时用在Android和iOS(关于API后面章节会详细讲解)。

5. Appium框架是基于UI的测试框架,验证都是通过界面UI来进行(后面框架封装过程中我们可以接入接口和UI结合验证)。

1.2. Appium环境搭建

1.2.1 Android环境配置

1. 下载安装Android SDK(这个直接网上下载就可以了)。

2. 配置Android SDK环境变量:右击“我的电脑”,选择“属性”“高级系统设置”“环境变量”,在系统变量中添加“ANDROID_HOME”的变量,值为AndroidSDK的安装路径。如图1-2-1所示:

「手把手」一起Android自动化

图1-2-1 Android SDK环境变量

1.2.2 Python环境安装及配置

1. 下载安装Python:进入https://www.python.org/downloads页面下载安装(我安装的是3.6.0)。

2. 配置python环境变量:右击“我的电脑”,选择“属性”“高级系统设置”“环境变量”,在系统变量中的“PATH”变量,值为Pthon的安装路径。系统命令窗口中输入 Python –V,正确显示版本号证明配置OK。如图1-2-2和1-2-3所示:

「手把手」一起Android自动化

图1-2-2 python环境变量配置

「手把手」一起Android自动化

图1-2-3 python环境变量验证

1.2.3 安装Appium客户端

1. 启动 一个命令行工具输入“pip install Appium-Python-Client”,命令行窗口提示安装成功则安装完成。

2. 在python开发工具中 from appium import webdriver 然后执行不报错则安装成功。如图 1-2-4所示:

「手把手」一起Android自动化

图1-2-4 验证 Appium-Python-Client 安装成功

1.2.4 安装Appium服务器

1. 直接下载安装即可:https://bitbucket.org/appium/appium.app/downloads/。

2. 安装后启动起来,可视化界面中点击右上角的小火箭按钮默认配置启动,启动成功画面如图1-2-5所示:

「手把手」一起Android自动化

图1-2-5 Appium Server启动成功画面

1.2.5 Node.js安装

Node.js不是必须安装的,只有在用命令启动Appium Server时才需要安装一个独立的Node.js。

1. 安装Node.js:https://nodejs.org/en/download/下载并安装。

2. 用命令启动Appium Server,启动一个命令行窗口,将当前路径切换到Appium Server安装目录下的\bin目录下,执行命令“node appium.js --session-override”(--session-override该参数设置后,测试异常退出时,会话也会被退出;不设置该参数,测试异常退出时,该会话会依然存在,下次创建会话就会失败)。

1.2.6 adb环境变量配置

adb工具这里不多说,只是后面经常会用到,所以这边简单说下安装和配置好环境变量,以便小伙伴们在学习时可以顺畅的走下去。

1. adb工具在Android SDK中自带就有,路径为sdk\platform-tools目录下,如图1-2-6所示:

「手把手」一起Android自动化

图1-2-6 adb工具及路径

2. 配置adb环境变量:右击“我的电脑”,选择“属性”“高级系统设置”“环境变量”,在系统变量中的“PATH”变量,值为adb.exe所在路径,如图1-2-7所示:

「手把手」一起Android自动化

图1-2-7 adb 环境变量配置

3. 系统命令窗口中任意目录执行adb命令, 不存在adb command not found,则配置成功。

1.3 UI Automator viewer工具介绍

UI Automator viewer是在Android平台通过截屏并分析XML布局文件的方式为用户提供控件信息查看服务的,是Android SDK自带的工具,该工具位于Android SDK目录下的tools目录下。启动程序为:uiautomatorviewer.bat;如图1-3-1 和 1-3-2所示:

「手把手」一起Android自动化

图1-3-1 UI Automator viewer所在目录

「手把手」一起Android自动化

图1-3-2 uiautomatorviewer.bat工具

1.3.1 UI Automator viewer工具使用

在此以 雅堂小超APP 来配合介绍UI Automator viewer工具;还是给赞助商安利一下:“雅堂小超,家门口的互联网超市”腾讯应用宝就可下载哈。

此处我使用夜神模拟器代替手机设备(真机只需要在手机-设置-开发者-打开允许手机连接就能查看到设备信息),使用模拟器需要手动adb连接设备,不然系统命令窗口中执行adb devices 无设备信息如图1-3-3所示。夜神模拟器连接命令 adb connect 127.0.0.1:62001(逍遥模拟器 adb connect 127.0.0.1:21503)如图1-3-4所示,连接后执行adb devices显示设备信息如图1-3-5所示:

「手把手」一起Android自动化

图1-3-3 无设备信息

「手把手」一起Android自动化

图1-3-4 adb连接命令

「手把手」一起Android自动化

图1-3-5 adb连接后查看设备信息

1. 双击启动uiautomatorviewer.bat界面,如图1-3-6所示

「手把手」一起Android自动化

图1-3-6 uiautomatorviewer.bat启动界面

2. 工具栏区域介绍

    从左至右:打开已保存的文件按钮;获取详细布局按钮;获取简洁布局按钮;保存布局按钮。点击保存按钮,将存储两个文件,一个是图片文件,一个是.uix文件(XML布局结构)。

3. 截图区介绍

    显示当前手机屏幕显示的布局图片,手机屏幕变动时需要点击工具栏中的第二个/第三个按钮进行更新截图。

4. 布局区介绍

    已XML树的形式,显示控件布局。

5. 控件属性区介绍

    截图区域点击某一控件时,显示该控件的属性。

    雅堂小超APP登录页面的uiautomatorviewer展示,此时截取区域点击的是登录按钮如图1-3-7展示。具体控件属性使用,实战中讲解!

「手把手」一起Android自动化

图1-3-7

1.4 登录自动化用例实战

1.4.1 环境准备检查

1. 我们需要获取被测试手机设备信息

    a. 手机平台:当然我们这是Android。

    b. 被测试手机系统版本:模拟器版本4.4.2,如图1-4-1所示。

「手把手」一起Android自动化

图1-4-1

    c. 手机设备名称:模拟器可以不填(用adb devices命令)

2. 我们需要获取被测试APP的包名和启动Activity名称

    a. 系统命令窗口中执行命令 adb shell 如图1-4-2所示。

「手把手」一起Android自动化

                    图1-4-2

    b. 再执行命令  dumpsys activity | grep mFocusedActivity获取包名和启动Activity名称 如图1-4-3。

「手把手」一起Android自动化

图1-4-3

3. 我们需要获取登录流程中使用到的控件的属性(如id……)

    a. 流程:启动APP—>点击“我的”—>点击“立即登录”—>输入“用户名”—>输入“密码”—>点击“登录”—>检查是否登录成功。

    b. 获取“我的”控件id属性:cn.yt.market.client:id/tv_mine,方法如图1-4-4所示:

「手把手」一起Android自动化

图1-4-4

    c. 同样的方法获取其他控件属性,“立即登录”:cn.yt.market.client:id/tv_user_name;“用户名输入框”:cn.yt.market.client:id/et_phone_num;“密码输入框”:cn.yt.market.client:id/ed_user_pwd;“登录按钮”:cn.yt.market.client:id/btn_login;登录成功检查用户名控件id属性:cn.yt.market.client:id/tv_user_name;登录成功检查用户名控件txt值:ju***hen(隐私所以星号代替)。

4. 配置并启动Appium服务器

    a. 打开Appium服务器程序,因为是本机测试,设置中默认配置端口和本机IP,如图1-4-5所示:

「手把手」一起Android自动化

图1-4-5

    b. 启动Appium服务  如图1-4-6所示:

「手把手」一起Android自动化

图1-4-6

1.4.2 开发一个登录自动化测试脚本

开始开发自动化登录脚本

    a. 在脚本开始位置添加对Appium的Python客户端库的引入,代码如下:

        from appium import webdriver

    b. 添加一个字典变量,我定义名称为desiredCaps,并向desiredCaps添加键和值,代码如下:

  #定义desiredCaps字典变量

  desiredCaps = {}
  #向desiredCaps字典变量添加测试平台key和value
  desiredCaps["platformName"] = "Android"
  #向desiredCaps字典变量添加被测手机系统版本key和value
  desiredCaps["paltformVersion"] = "4.4.2"
  #向desiredCaps字典变量添加被测App包名key和value
  desiredCaps["appPackage"] = "cn.yt.market.client"
  #向desiredCaps字典变量添加被测App启动Activity名称key和value
  desiredCaps["appActivity"] = ".activity.MainActivity"
  #向desiredCaps字典变量添加手机名称key和value;虚拟机我就直接赋值为空字符
  desiredCaps["deviceName"] = ""

    c. 以desiredCaps作为参数初始化Webdriver,代码如下,代码解释如图1-4-7所示:   

 #初始化Appium的Webdriver连接,获取driver
  driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",desiredCaps)

「手把手」一起Android自动化

图1-4-7

    d. 登录流程测试代码如下   

 #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(10)
  #查找“我的”控件根据控件id属性
  searchMine = driver.find_element_by_id("cn.yt.market.client:id/tv_mine")
  #根据查到的element点击“我的”控件,进入我的页面
  searchMine.click()
               
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(2)
  #我的页面,查找“立即登录”控件根据控件id属性
  searchUserName = driver.find_element_by_id("cn.yt.market.client:id/tv_user_name")
  #根据查到的element点击“立即登录”控件,进入登录页面
  searchUserName.click()
               
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(2)
  #登录页面,查找“用户名输入框”控件根据控件id属性
  searchPhoneNum = driver.find_element_by_id("cn.yt.market.client:id/et_phone_num")
  #根据查到的element输入用户名
  searchPhoneNum.send_keys("******")
  #登录页面,查找“密码输入框”控件根据控件id属性
  searchUserPwd = driver.find_element_by_id("cn.yt.market.client:id/ed_user_pwd")
  #根据查到的element输入用户名
  searchUserPwd.send_keys("******")
               
  #登录页面,查找“登录”控件根据控件id属性
  searchLogin = driver.find_element_by_id("cn.yt.market.client:id/btn_login")
  #根据查到的element点击“立即登录”控件,进入登录页面
  searchLogin.click()
               
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(10)
  #登录成功,我的页面查找“用户名”控件根据控件id属性
  sucSearchUserName = driver.find_element_by_id("cn.yt.market.client:id/tv_user_name")
  #根据查到的element检查其text属性是否正确
  if sucSearchUserName.text == "*****":
     print "登录成功"
     #测试完成,断开连接
     driver.quit()
  else:
     print "登录失败"
     #测试完成,断开连接
     driver.quit()

    PS:Webdriver提供的查找控件方法有好几种:通过控件ID,控件的类型,控件的文本,控件的XPath路径,我建议小伙伴们首选控件ID,因为ID查找效率高且比较稳定,一般很少改变。当然有些控件可能没有ID或者存在多个控件ID相同,在框架方法封装章节我会详细讲解策略和方法

    这样我们的自动化登录脚本就开发完了,保存脚本,运行就能看到效果了。

完整代码如下:

 #coding=utf-8        
  from appium import webdriver
  import time

     
  #定义desiredCaps字典变量
  desiredCaps = {}
  #向desiredCaps字典变量添加测试平台key和value
  desiredCaps["platformName"] = "Android"
  #向desiredCaps字典变量添加被测手机系统版本key和value
  desiredCaps["paltformVersion"] = "4.4.2"
  #向desiredCaps字典变量添加被测App包名key和value
  desiredCaps["appPackage"] = "cn.yt.market.client"
  #向desiredCaps字典变量添加被测App启动Activity名称key和value
  desiredCaps["appActivity"] = ".activity.MainActivity"
  #向desiredCaps字典变量添加手机名称key和value;虚拟机我就直接赋值为空字符
  desiredCaps["deviceName"] = ""
             
  #初始化Appium的Webdriver连接,获取driver
  driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",desiredCaps)
             
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(10)
  #查找“我的”控件根据控件id属性
  searchMine = driver.find_element_by_id("cn.yt.market.client:id/tv_mine")
  #根据查到的element点击“我的”控件,进入我的页面
  searchMine.click()
             
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(2)
  #我的页面,查找“立即登录”控件根据控件id属性
  searchUserName = driver.find_element_by_id("cn.yt.market.client:id/tv_user_name")
  #根据查到的element点击“立即登录”控件,进入登录页面
  searchUserName.click()
             
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(2)
  #登录页面,查找“用户名输入框”控件根据控件id属性
  searchPhoneNum = driver.find_element_by_id("cn.yt.market.client:id/et_phone_num")
  #根据查到的element输入用户名
  searchPhoneNum.send_keys("******")
  #登录页面,查找“密码输入框”控件根据控件id属性
  searchUserPwd = driver.find_element_by_id("cn.yt.market.client:id/ed_user_pwd")
  #根据查到的element输入用户名
  searchUserPwd.send_keys("******")
             
  #登录页面,查找“登录”控件根据控件id属性
  searchLogin = driver.find_element_by_id("cn.yt.market.client:id/btn_login")
  #根据查到的element点击“立即登录”控件,进入登录页面
  searchLogin.click()
             
  #由于程序启动和activity加载快慢问题,需要等待加载完成后执行
  time.sleep(10)
  #登录成功,我的页面查找“用户名”控件根据控件id属性
  sucSearchUserName = driver.find_element_by_id("cn.yt.market.client:id/tv_user_name")
  #根据查到的element检查其text属性是否正确
  if sucSearchUserName.text == "*****":
     print "登录成功"
     #测试完成,断开连接
     driver.quit()
  else:
     print "登录失败"
     #测试完成,断开连接
     driver.quit()

上面这个自动化登录脚本样例,仅用于小伙伴们入门如何下手去写一个Appium的测试脚本。它是很脆弱的执行效率较低的,会受环境和App本身影响很大,比如固定等待时间(这个时间不可控,该方式不可取),另外对脚本运行过程中出现的异常没有做处理,如果脚本异常会导致整个脚本失败。我们心中的自动化肯定是想高效稳定的!这些问题在框架方法封装章节会进行详细讲解。

后续章节请访问:https://yuedu.baidu.com/ebook/b944a65626284b73f242336c1eb91a37f11132c8

                


相关文章: