一、Appium介绍

Appium是一个开源的自动化测试工具,其支持iOS和安卓平台上的原生的,基于移动浏览器的,混合的应用。

1、Appium 理念

Appium是基于以下的四个理念设计来满足移动平台测试自动化的要求的:

1)您不应该因为需要自动化测试您的应用而不得不以任何形式去重新编译或者修改你的app

2)您不应该把自己固定在一门特定的语言和一个特定的框架上去实现和运行你的测试

3)当说到测试自动化APIs的时候,一个移动测试框架不应该做“重新发明轮子”的事情,

4)一个移动测试自动化框架应该是开源的,无论是在精神上,实际上,还是名义上!

2、使用Appium进行自动化测试有两个好处

Appium在不同平台中使用了标准的自动化APIs,所以在跨平台时,不需要重新编译或者修改自己的应用。

Appium支持Selenium WebDriver支持的所有语言,如java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure,或者Perl语言,更可以使用Selenium WebDriver的Api。Appium支持任何一种测试框架.Appium实现了真正的跨平台自动化测试。(本文主要介绍Python的用法)

3、Appium架构

Appium 是一个用Node.js编写的HTTP server,它创建、并管理多个 WebDriver sessions 来和不同平台交互,如 iOS ,Android等等.

Appium 开始一个测试后,就会在被测设备(手机)上启动一个 server ,监听来自 Appium server的指令. 每种平台像 iOS 和Android都有不同的运行、和交互方式。所以Appium会用某个桩程序“侵入”该平台,并接受指令,来完成测试用例的运行。

二、Appium环境搭建(Android)

1、首先需要准备

1) jdk(步骤不再啰嗦)

2) android SDK,下载地址:http://developer.android.com/sdk/index.html,下载sdk tools,可能需要FQ,提供一个国内下载地址:http://www.androiddevtools.cn/

3) appium,下载地址:http://appium.io/

4) nodejs,下载地址:https://nodejs.org/en/

5) appium lib,下载地址:http://appium.io/downloads.html

选择Python版本的Lib: Appium-Python-Client-0.22.tar.gz

由于Appium依赖于Selemium,所以还要下载 Selemium Lib: selenium-2.53.2.tar.gz   https://pypi.python.org/pypi/selenium

6) python, 下载地址:https://www.python.org/, 下载2.X 的版本。

上述软件都准备好后,则进入搭建步骤。

2、安装、配置

将上述软件依次安装。

1) android sdk安装完毕后,需要配置环境变量

新建ANDROID_HOME    D:\ProgramFiles (x86)\Android\android-sdk

在PATH中添加:%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools;

2)  nodejs安装完毕后,需要配置环境变量

在PATH中添加:D:\Program Files\nodejs;

3) appium安装完毕后,需要配置环境变量

D:\Program Files (x86)\Appium\node_modules\.bin;

4) 配置好后,启动cmd,

输入node -v,查看node安装版本

输入appium-doctor检查appium的安装环境是否成功,如下图:

5) 安装Python,配置环境变量,如C:\Python27,检查是否设置成功,如下图:

三、开始例子(Python)

1) 启动Appium

打开命令行,输入appium, 显示成功启动:

2)连接Android手机(或者模拟器)

3)编写客户端代码

假设我们的代码放在目录E:\PythonTest\AppiumClientPython 中。首先把 Appium-Python-Client-0.22.tar.gz 里面的 appium 目录解压到AppiumClientPython 中, 把 selenium-2.53.2.tar.gz里面的 selenium 目录解压到AppiumClientPython中。

创建文件hello_appium.py , 编辑内容:

#coding=utf-8

from appium import webdriver

desired_caps = {}

desired_caps['platformName'] = 'Android'

desired_caps['platformVersion'] = '4.4.2'

desired_caps['deviceName'] = 'Android Emulator'

desired_caps['appPackage'] = 'com.android.calculator2'

desired_caps['appActivity'] = '.Calculator'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

driver.find_element_by_name("1").click()

driver.find_element_by_name("5").click()

driver.find_element_by_name("9").click()

driver.find_element_by_name("9").click()

driver.find_element_by_name("5").click()

driver.find_element_by_name("+").click()

driver.find_element_by_name("6").click()

driver.find_element_by_name("=").click()

driver.quit()

4)运行

打开命令行,cd到E:\PythonTest\AppiumClientPython 中,运行 python hello_appium.py, 正常情况可以看到手机按照代码控制,打开计算器,逐个点击按钮完成计算。

四、Appium文档

1、安装应用后打开

import os

from appium import webdriver

APK_PATH = 'apk/ECloud-debug.apk'

COMMAND_EXECUTOR_URL = 'http://localhost:4723/wd/hub'

desired_caps = {}

desired_caps['platformName'] = 'Android'

desired_caps['platformVersion'] = '5.0'

desired_caps['deviceName'] = 'Android Emulator'

desired_caps['app'] = os.path.abspath(APK_PATH)

driver = webdriver.Remote(COMMAND_EXECUTOR_URL, desired_caps)

2、查找控件

1)通过名称查找

btn = driver.find_element_by_name("+")

2)  通过ID查找

start_btn =driver.find_element_by_id('com.cn21.ecloud:id/instruction_close_btn')

或 start_btn = driver.find_element_by_id('instruction_close_btn')

3)通过类名查找

child_text =parent.find_element_by_class_name('android.widget.TextView')

4)通过android_uiautomator查找

start_btn =driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)')

以上find_element_by_XX 都是返回符合条件的第一个控件,如果要返回多个控件,可以调用 find_elements_by_XX, 返回的是一个list。

注意:如果找不到符合条件的控件,会抛出异常。

5)查找结点,不希望返回异常,写个函数就行了

def find_element_by_id_no_except(driver, id):

element = None

try :

element = driver.find_element_by_id(id)

except Exception,e:

print Exception, ':', e

return element

3、模拟按钮点击

login_btn.click()

注意:有的点击如果需要等待动画、或者网络请求,建议等待一会:

import time

time.sleep(2)  # 睡眠2秒

4、输入框输入文本

user_input.send_keys('123456')

注意:Android如果要正确输入,需要把使用系统自带的输入法,第三方输入法无法正确输入。

5、模拟点击返回键

driver.press_keycode(4)

其中按钮的定义,由Android里的KeyEvent.java里定义的,所以其它的Android按钮也是支持的。

6、关闭driver

driver.quit()

注意:一定要记得关闭driver, 否则下次连接的时候可能会出异常,因为Appium以为你上次未关闭,会创建Session失败。

为了避免代码出现异常而没有关闭,可以在捕获异常时再关闭。

7、滑动界面

下面的例子,演示点击屏幕中间,并向上拉动(相当于查看列表下面的内容了)。

from appium.webdriver.common.touch_action import TouchAction

def test_scroll_down(driver):

screen = driver.get_window_size()

action = TouchAction(driver)

action.press(x=screen['width']/2,y=screen['height']/2)

action.move_to(x=0,y=-screen['height']/10)

action.release()

action.perform()

等等,怎么获取界面的属性来验证正确性?

8、获取界面属性,控件属性

1)获取当前Activity名称

activity = driver.current_activity

2) 获取屏幕宽高

screen = driver.get_window_size()

3)获取控件文本

mobile_name.get_attribute('text') 或者 mobile_name.text

4)获取控件类名

mobile_name.get_attribute('className')

5)判断控件是否显示

mobile_name.is_displayed() 或者 mobile_name.get_attribute('displayed')

6)获得控件位置

mobile_name.location

7)获得控件大小

mobile_name.size

8)查找控件子结点

parent.find_elements_by_class_name('android.widget.TextView')

同样:查找控件的其它方法,也适用于查找子结点。

对于交互后的验证,无法验证到具体的数据内容,可以验证当前的Activity,或者文本,或者列表是否为空等等。

更多参考:http://blog.csdn.net/crisschan/article/details/50416860

五、结合单元测试框架编写用例

Python自带有unittest用于单元测试,其结构类似于JUnit。

一个测试类需要继承于unittest.TestCase, 方法setUp 用于测试初始化,每个用例开始前都会调用,tearDown用于用例结束时调用,每个以test开始的函数被当成一个用例。

test_random.py

import random

import unittest

class TestSequenceFunctions(unittest.TestCase):

def setUp(self):

self.seq = range(10)

def test_shuffle(self):

# make sure the shuffled sequence does not lose any elements

random.shuffle(self.seq)

self.seq.sort()

self.assertEqual(self.seq, range(10))

# should raise an exception for an immutable sequence

self.assertRaises(TypeError, random.shuffle, (1,2,3))

def test_choice(self):

element = random.choice(self.seq)

self.assertTrue(element in self.seq)

def test_sample(self):

with self.assertRaises(ValueError):

random.sample(self.seq, 20)

for element in random.sample(self.seq, 5):

self.assertTrue(element not in self.seq)

if __name__ == '__main__':

unittest.main(verbosity=2)

运行此测试: python test_random.py 可以查看测试的结果

上面结果显示,有2个用例测试通过,1个用例不通过。

可以在一个目录下写多个以test开头的测试文件,然后通过以下命令运行所有测试类:

python -m unittest discover . -v

六、完整例子

1、测试登陆登出功能

test_ecloud_login_logout.py

#coding=utf-8
# 测试天翼云登陆登出功能
# 用例1:快速登陆,验证登陆后的Activity为MainPageActivity
# 用例2:普通登陆,输入用户名密码,验证登陆后的Activity为MainPageActivity
# 用例3:快速登陆后注销,验证注销后的Activity为LoginActivity

import unittest
import appium_ecloud
import appium_util
from appium import webdriver
import os

class LoginLogoutTest(unittest.TestCase):
    ##
    
def setUp(self):
        #print('Installing ...')
        
desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '5.0'
        desired_caps['deviceName'] = 'Android Emulator'
        desired_caps['app'] = os.path.abspath(appium_ecloud.APK_PATH)
        self.driver = webdriver.Remote(appium_util.COMMAND_EXECUTOR_URL, desired_caps)
        
    def tearDown(self):
        self.driver.quit()
        
    def test_FastLogin(self):
        appium_ecloud.agree_document(self.driver)
        appium_ecloud.quick_login(self.driver)
        self.assertTrue(self.driver.current_activity.endswith('MainPageActivity'))
        
    def test_SlowLigin(self):
        appium_ecloud.agree_document(self.driver)
        appium_ecloud.slow_login(self.driver)
        self.assertTrue(self.driver.current_activity.endswith('MainPageActivity'))
        
    def test_Logout(self):
        appium_ecloud.agree_document(self.driver)
        appium_ecloud.quick_login(self.driver)
        if (self.driver.current_activity.endswith('MainPageActivity')):
            appium_ecloud.test_logout(self.driver)
            self.assertTrue(self.driver.current_activity.endswith('LoginActivity'))

if __name__ == '__main__':
    unittest.main(verbosity=2)

2、自动乱点测试崩溃的情况

auto_test_ecloud.py

#coding=utf-8
import random
import time
import traceback

import appium_ecloud

def auto_interact(driver):
    activity = driver.current_activity
    # 一定的机率滑动,返回键,点击
    
rate = random.random()
    if rate < 0.1:
        print activity + ' Scroll Down'
        appium_ecloud.test_scroll_down(driver)
    elif rate < 0.2:
        print activity + ' Scroll Up'
        appium_ecloud.test_scroll_up(driver)
    elif rate < 0.3:
        print activity + ' Key Back'
        driver.press_keycode(4)
    else:
        btn_list = driver.find_elements_by_android_uiautomator('new UiSelector().clickable(true)')
        if (len(btn_list) > 0):
            index = random.randint(0, len(btn_list) - 1)
            print activity + ' Click Button index = %d' % (index,)
            btn_list[index].click()

def main():
    driver = None
    try:
        driver = appium_ecloud.install_app()
        time.sleep(appium_ecloud.LONG_WAIT_TIME)
        appium_ecloud.agree_document(driver)
        appium_ecloud.quick_login(driver)
        step = 0
        while step < 100:
            if (driver.current_activity.endswith('LoginActivity')):
                appium_ecloud.test_login(driver)
            elif (driver.current_activity.endswith('.Launcher')):
                driver.background_app(1)
                driver.launch_app()
            else:
                auto_interact(driver)
                time.sleep(appium_ecloud.CLICK_WAIT_TIME)
            step += 1
        # 正常退出
        
driver.quit()

except Exception, e:
        print Exception, ":", e
        traceback.print_exc()
        # 异常退出
        
if (driver != None):
            driver.quit()

if __name__ == '__main__':
    for i in range(20000):
        try:
            main()
        except Exception, e:
            print Exception, ":", e
            traceback.print_exc()

注:为了更方便的编写python代码,推荐使用PyCharm IDE,编辑代码跟Java一样方便。

七、参考资料:

1)官网 http://appium.io/index.html

2)appium/python-client使用文档https://github.com/appium/python-client

3)搭建appium的android环境http://www.cnblogs.com/qiaoyeye/p/5131382.html

4)Appium移动自动化测试(四)http://www.cnblogs.com/fnng/p/4579152.html

5)AppiumPython API http://blog.csdn.net/crisschan/article/details/50416860

6)appium常用方法总结 http://www.cnblogs.com/fanxiaojuan/p/4882676.html

Appium使用教程_Android篇相关推荐

  1. .Net魔法堂:史上最全的ActiveX开发教程——发布篇

    一. 前言 接着上一篇<.Net魔法堂:史上最全的ActiveX开发教程--开发篇>,本篇讲述如何发布我们的ActiveX. 二.废话少讲,马上看步骤! 1. 打包  C#开发的Activ ...

  2. SpringCloud 教程 | 第二篇: 服务消费者(rest+ribbon)

    转载请标明出处: blog.csdn.net/forezp/arti- 本文出自方志朋的博客 在上一篇文章,讲了服务的注册和发现.在服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于h ...

  3. python语言自学教程-3D图示Python标准自学教程入门篇

    内容简介: Python入门篇教程从最基础的计算机发展史.Python的来源与发展历史开始讲起: 依次讲解python变量与表达式.数据类型.运算符.流程控制语句等,末尾通过课堂练习.课后作业以及微型 ...

  4. 【helloworld】-微信小程序开发教程-入门篇【1】

    1. 开篇导言 本节目标:旨在演示如何用开发者工具构建并运行简单的 helloworld 应用. 目标用户:无编程经验,但对微信小程序感兴趣的同学. 学习目标:开发者工具的基本使用流程,即创建.导入. ...

  5. linux usb3.0改2.0,TX1入门教程硬件篇-切换USB2.0与USB3.0

    TX1入门教程硬件篇-切换USB2.0与USB3.0 说明: 介绍如何切换TX1USB口的为2.0或3.0版本 步骤: 编辑extlinux.conf文件,修改usb_port_owner_info= ...

  6. 微信公众号开发入门教程第一篇

    微信公众号开发入门教程第一篇 关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/ ...

  7. Fiddler抓包使用教程-扫盲篇

    Fiddler抓包使用教程-扫盲篇 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72823370 本文出自[赵彦军的博客] 1.什 ...

  8. spring boot 跨域请求_SpringBoot 系列教程 web 篇之自定义请求匹配条件 RequestCondition...

    191222-SpringBoot 系列教程 web 篇之自定义请求匹配条件 RequestCondition 在 spring mvc 中,我们知道用户发起的请求可以通过 url 匹配到我们通过@R ...

  9. 【iVX 初级工程师培训教程 10篇文拿证】01 了解 iVX 完成新年贺卡

    目录 [iVX 初级工程师培训教程 10篇文拿证]01 了解 iVX 完成新年贺卡 [iVX 初级工程师培训教程 10篇文拿证]02 数值绑定及自适应网站制作 [iVX 初级工程师培训教程 10篇文拿 ...

  10. 【iVX 初级工程师培训教程 10篇文拿证】02 数值绑定及自适应网站制作

    目录 [iVX 初级工程师培训教程 10篇文拿证]01 了解 iVX 完成新年贺卡 [iVX 初级工程师培训教程 10篇文拿证]02 数值绑定及自适应网站制作 [iVX 初级工程师培训教程 10篇文拿 ...

最新文章

  1. Groovy安装与入门实例
  2. Nginx:作为缓存,支持Range回源
  3. mysql启动失败LSB_MySQL数据库服务启动失败
  4. python 多次读取文件的细节
  5. LeetCode 369. 给单链表加一(递归)
  6. Intel 64/x86_64/IA-32/x86处理器 - 指令格式(9) - 64位指令格式(通用格式)
  7. Python 3.6.x字符串格式化方法小结
  8. eclipse 项目导入时报错invalid project description
  9. CSU 1115: 最短的名字(字典树)
  10. 6本Android开发必备图书
  11. 老男孩linux培训某节课前考试试题及答案分享 【转】
  12. 国标GB28181协议国标视频平台国标流媒体服务器EasyGBS向上级联多个平台设备及通道选择错位问题解析
  13. java炫酷龙卷风源码,龙卷风's Blog
  14. 小项目一:使用fping统计网络中主机的网络连通情况
  15. 明源云客微信抢房技巧_明源云客车位线上开盘体验 - 微信抢房_软件抢房_网上选房_手机抢房_代抢房 - 爱抢房...
  16. 多看阅读设置自动翻页教程
  17. Centos重装ssh服务
  18. weixuan -奥利给turtle
  19. Python 进阶视频课 - 10. LSMC 美式百慕大期权定价
  20. gm220s路由器怎么设置_二级路由器怎么设置_二级路由器设置图解教程-192路由网...

热门文章

  1. 简单的python的socket编程实例
  2. 我的QQ斗地主史及斗地主经验
  3. 产业变革新机遇,与5G同行,驰骋在浪潮之巅
  4. 升级在谷歌电子市场上传的应用
  5. 计算机基础知识经典问答题,计算机基础知识问答题及答案一
  6. MATLAB数字图像处理
  7. 和秋叶一起学PPT之线条(课时六)
  8. 微博这样的软件怎么测试,新浪微博都盘上了,这个测试玩嗨了!
  9. 力扣 面试题 08.04. 幂集
  10. 【剑指Offer速刷与技巧笔记】剑指Offer重点面试刷题