一、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测试工具的更多相关文章

  1. 测试耗电量的工具(Android)

    Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资源的性能测试小工具. 支持SDK:Android2.2以及以上版本 Emmagee功能介绍 1.检测当前时间被测应用占用的CP ...

  2. 【转】web测试内容及工具经典总结

    基于Web的系统测试在基于Web的系统开发中,如果缺乏严格的过程,我们在开发.发布.实施和维护Web的过程中,可能就会碰到一些严重的问题,失败的可能性很大.而且,随着基于Web的系统变得越来越复杂,一 ...

  3. 30款基本UX工具 - 用户测试与反馈工具

    日期:2013-9-5  来源:GBin1.com 在上一篇30款基本UX工具 - 思维流程工具 & 原型工具中,我们提到了10款用于头脑风暴和原型创建的工具,用于帮助我们在用户体验上可以做的 ...

  4. Apache JMeter开源压力测试/负载测试工具 2.12 官方最新版

    软件介绍   Jmeter是一款使用Java开发的,开源免费的,测试工具, 主要用来做功能测试和性能测试(压力测试/负载测试),而且用Jmeter 来测试 Restful API, 非常好用. 如何学 ...

  5. Android应用测试性能的工具Emmagee,导出文件格式问题分析

    原文引用自:http://www.open-open.com/lib/view/open1367026451078.html Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资 ...

  6. 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具

    ===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...

  7. 360在线网站安全检测,web安全测试AppScan扫描工具,XSS常用的攻击手法

    360在线网站安全检测,web安全测试AppScan扫描工具,XSS常用的攻击手法 如何做好网站的安全性测试 360网站安全检测 - 在线安全检测,网站漏洞修复,网站后门检测http://websca ...

  8. 测试mysql性能工具

    mysqlslap mysqlslap可以模拟服务器的负载,并输出计时信息.它包含在MySQL 5.1 的发行包中,应该在MySQL 4.1或者更新的版本中都可以使用.测试时可以执行并发连接数,并指定 ...

  9. mysql测试和sysbench工具详解

    前言 作为一名后台开发,对数据库进行基准测试,以掌握数据库的性能情况是非常必要的.本文介绍了MySQL基准测试的基本概念,以及使用sysbench对MySQL进行基准测试的详细方法. 文章有疏漏之处, ...

随机推荐

  1. 如何使用懒加载 - umi

    .umirc.js文件 plugins: [       dynamicImport: true,

  2. LeakCanary检测内存泄漏

    内存泄漏原因: 线程造成的内存泄漏 Handler造成的内存泄漏 单例导致内存泄露 静态变量导致内存泄露 非静态内部类导致内存泄露 未取消注册(BroadcastReceiver )或回调导致内存泄露 ...

  3. vue 组件传值,(太久不用就会忘记,留在博客里,方便自己查看)

    一 :父组件 传值给 子组件 方法: props //父组件 <template lang="html"> <div> <h3>我是父亲< ...

  4. Cloudera Manager简介

    Hadoop家族 整个Hadoop家族由以下几个子项目组成: Hadoop Common: Hadoop体系最底层的一个模块,为Hadoop各子项目提供各 种工具,如:配置文件和日志操作等. HDFS ...

  5. postMessage 跨域

    基于 postMessage 和 localStorage 的跨域本地存储方案 安·记 2014-09-07 2099 阅读 跨域 存储 localStorage HTML5 的 postMessag ...

  6. LoadRunner接口脚本web_submit_data编写过程中遇到的问题及分享

    工作中需要接口测试,报文编辑器一条条手工发费时费力,因此考虑利用web_submit_data函数POST方法进行报文编辑.在报文编辑中主要遇到了三个问题,其中一个问题耗时两天查到问题所在,在这里与大 ...

  7. 关于查看本机ssh公钥以及生成公钥

    1.查看本机公钥: 打开git bush,执行  cd ~/.ssh  进入.ssh文件夹(C:\Users\Administrator\.ssh) 执行  ls  命令,查看列表 执行 cat id ...

  8. java处理大数据量任务时的可用思路--未验证版,具体实现方法有待实践

    1.Bloom filter适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集基本原理及要点:对于原理来说很简单,位数组+k个独立hash函数.将hash函数对应的值的位数组置1,查找时如 ...

  9. AdaBoost算法详解与python实现

    1. 概述 1.1 集成学习 目前存在各种各样的机器学习算法,例如SVM.决策树.感知机等等.但是实际应用中,或者说在打比赛时,成绩较好的队伍几乎都用了集成学习(ensemble learning)的 ...

  10. 常用命令--windows

    查看端口号是否占用并杀进程 1 netstat -ano | findstr " " 2 tasklist | findstr " " 3 taskkill / ...