Appium入門指南 - 環境搭建和Case編寫

本文檔將詳細介紹如何搭建 Appium 的運行環境,以及如何編寫一個簡單的 UI 自動化測試用例。其中,也會穿插講解一些 Appium 的基本知識。關於 Appium 的更多信息,你們能夠查看官方文檔html

注意事項:node

  • 本文檔是在 macOS 系統的基礎上講解相關操做
  • 編程語言選擇了:Python 2.7
  • Appium 是跨平臺的 UI 自動化測試框架,支持 Android、iOS 等系統,本次只介紹基於 Android 的自動化測試

安裝 Appium

Appium 的安裝有兩種方式:python

一、下載 Appium Desktop,這個是 Appium 的客戶端軟件,包含了運行 Appium 所須要的一切,下載後安裝便可,支持 Mac、Windows、Linux 三大系統。由於安裝過程實在是太簡單了,因此不作詳細說明。
二、經過命令行的方式進行安裝,這個比較複雜,須要依次下載安裝多種配置/依賴來知足 Appium 的運行條件。着重介紹此種安裝方式。android

命令行安裝

如下命令都是在終端(Terminal)上運行的git

一、安裝包管理工具 Homebrewgithub

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

二、安裝 Node.jsweb

brew install node

三、安裝 Appium 服務端shell

npm install -g appium

四、安裝 appium-doctornpm

npm install -g appium-doctor

五、運行 appium-doctor,檢查 Appium 須要的全部依賴是否都知足編程

appium-doctor --android

其中有幾個依賴項是必需要知足的:

  • Node.js
  • ANDROID_HOME
  • JAVA_HOME
  • adb
  • android
  • emulator
  • $JAVA_HOME/bin

你們可根據這個命令運行結束後的提示信息去完成相應的依賴添加:

六、安裝 Appium 客戶端

pip install Appium-Python-Client

七、最後,由於須要使用 Python 語言編寫自動化測試用例,建議安裝 Python 語言的 IDE:PyCharm

腳本編寫

腳本編寫前的準備工做

一、啓動 Appium

(1)若是安裝了 Appium Desktop,可直接打開軟件點擊 "Start" 啓動 Appium 服務

(2)若是是經過命令行方式安裝的 Appium,則在終端(Terminal)輸入:

appium

二、啓動模擬器/測試設備鏈接至電腦

#啓動模擬器
emulator @<emulator_name>
#測試設備鏈接至電腦
(1)Settings-Developer options-USB debugging //打開usb調試模式
(2)adb devices //查看手機是否成功鏈接至電腦

三、安裝待測應用到模擬器/測試設備中

adb install <path_to_apk>

本次講解計算器應用 iClever Calculator Lite 爲例,可自行到 Google Play 上下載該應用,包名爲:weightloss.constellation.education.tools

建立腳本

在完成以上三步後,打開 Pycharm 或者其餘 IDE,新建一個 py 文件,完成自動化測試腳本基礎代碼的編寫。

一、新建 calculator_test.py 文件
二、導入類庫和包

#導入unittest測試框架
import unittest
#導入appium客戶端庫
from appium import webdriver
#導入time模塊
from time import sleep

三、建立一個類 CalculatorTest,繼承自 Python 的測試類 unittest.TestCase

class CalculatorTest(unittest.TestCase):
    pass

unittest 是 Python 的一個單元測試框架,包含了四個部分:

  • TestFixture
    • setUp
    • TestCase
    • TearDown
  • TestCase
  • TestSuite
  • TestRunner

關於各部分的概念和應用,在下面章節裏說明(參見代碼註釋)。

四、在類中建立三個方法:setUP()、tearDown()、test_case_1(),而後在類外面建立一個程序入口

class CalculatorTest(unittest.TestCase):
    # pass

    #SetUP,case運行前的環境初始化
    def setUp(self):
        pass

    #TearDown,case運行後的環境恢復
    def tearDown(self):
        pass

    #TestCase,測試用例1
    def test_case_1(self):
        pass


#程序入口
if __name__ == '__main__':
    #TestSuite,將全部測試用例載入suite
    suite = unittest.TestLoader().loadTestsFromTestCase(CalculatorTest)
    #TestRunner,運行測試用例
    unittest.TextTestRunner(verbosity=2).run(suite)

五、在 setUP() 中添加字典變量 desired_caps,初始化配置,提供創建 Session 所須要的信息

#SetUP,case運行前的環境初始化
    def setUp(self):
        # pass
        #字典變量,初始化配置,提供創建session的全部必要信息:http://appium.io/docs/en/writing-running-appium/caps/index.html
        desired_caps = {}
        #被測應用平臺:iOS/Android
        desired_caps['platformName'] = 'Android'
        #被測應用平臺版本:adb shell getprop ro.build.version.release
        desired_caps['platformVersion'] = '8.0.0'
        #測試設備名:adb devices
        desired_caps['deviceName'] = 'CB512FCM14'
        #被測應用包名
        desired_caps['appPackage'] = 'weightloss.constellation.education.tools'
        #被測應用啓動時的活動名
        desired_caps['appActivity'] = 'com.weightloss.constellation.education.tools.SplashActivityAlias'
        #服務端等待客戶端發送消息的超時時間
        desired_caps['newCommandTimeout'] = 150
        #在一個session開始前不重置被測程序的狀態
        desired_caps['noReset'] = True
        #是否支持uicode的鍵盤(輸入中文需設置)
        desired_caps['unicodeKeyboard'] = True
        #以desired_caps做爲參數初始化WebDriver鏈接
        #Appium服務器的IP:http://localhost
        #端口號:4723
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
        sleep(10)

其中,有兩個變量 "platformVersion""deviceName" 須要你們自行修改,可經過如下命令獲取測試設備系統版本號和設備名

adb shell getprop ro.build.version.release //獲取測試設備系統版本號
adb devices //獲取設備名

六、在 tearDown() 中調用 quit(),退出driver,關閉被測應用全部的關聯窗口

#TearDown,case運行後的環境恢復
    def tearDown(self):
        # pass
        #退出driver,關閉被測應用全部的關聯窗口
        self.driver.quit()

七、至此,一個基礎的 Appium 自動化測試腳本已編寫完成。經過終端(Terminal)進入腳本所在的目錄,輸入如下語句運行腳本

python calculator_test.py

自動化測試用例的編寫

在完成上述步驟後,一個基礎的自動化測試腳本便生成了。接下來,具體講解如何編寫 case。

case 的編寫,簡而言之有三步:

  • 1.動做執行
    • 查找和識別元素
    • 操做元素
  • 2.結果判斷
  • 3.報告展現

動做執行

查找和識別元素

元素,在這裏指的是應用程序用戶界面上的控件。能夠經過谷歌官方提供的工具 uiautomatorviewer 進行查找和識別。

一、進入 Android SDK 的 bin 目錄

cd ${ANDROID_HOME}/tools/bin //每一個人的Android sdk的目錄名不同哦

二、啓動 uiautomatorviewer

uiautomatorviewer


三、在測試設備上啓動應用,進入須要識別和操做的用戶界面。在 uiautomatorviewer 上,點擊左上角第二個按鈕"Device Screenshot(uiautomator dump)",對當前界面上的元素進行查找和識別

四、在獲取到界面上元素的佈局層級及其屬性後,能夠經過以下一些方法進行元素的識別

  • find_element_by_id---對應組件屬性中的"resource_id"
  • find_element_by_class_name---對應組件屬性中的"class"
  • find_element_by_name---對應組件屬性中的"text"
  • find_element_by_accessibility_id---對應組件屬性中的"content-desc"

更多方法,請查看 Appium 的官方文檔

http://appium.io/docs/en/writing-running-appium/finding-elements/
http://appium.io/docs/en/commands/element/find-elements/index.html#selector-strategies
https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md
http://appium.io/docs/en/writing-running-appium/android/uiautomator-uiselector/index.html
操做元素

元素操做的方法,分爲三種:

  • 獲取控件的信息
    • text(self)---獲取文本信息
    • click(self)---點擊
    • clear(self)---清空文本
    • is_enabled(self)---是否可用
    • is_selected(self)---是否已選
    • is_displayed(self)---是否顯示
    • send_keys(self, *value)---模擬輸入文本
  • 手勢操做
    • tap(self, positions, duration=None)---點擊,自定義座標
    • swipe(self, start_x, start_y, end_x, end_y, duration=None)---滑動
    • flick(self, start_x, start_y, end_x, end_y)---快速滑動
    • pinch(self, element=None, percent=200, steps=50)---縮小
    • zoom(self, element=None, percent=200, steps=50)---放大
    • scroll(self, origin_el, destination_el)---滾動
    • drag_and_drop(self, origin_el, destination_el)---拖曳
  • 系統操做
    • press_keycode()---模擬按鍵
    • long_press_keycode()---模擬長按鍵
    • reset()---重置程序到初始狀態
    • pull_file()---從手機上拉取文件
    • launch_app()---啓動應用程序
    • start_activity()---啓動活動
    • shake()---晃動手機
    • get_screenshot_as_file()---獲取截圖並保存在電腦上
    • push_file()---推送文件到手機

更多操做元素的方法,請查看 Appium 的官方文檔

本次實例,以 iClever Calculator Lite 爲被測應用,建立一個 test_plus() 方法,查找和識別以及操做元素

def test_plus(self):
        #預期結果等於10
        result = 10
        #經過ID找到7
        seven = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_7")
        #經過ID找到3
        three = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_3")
        #經過ID找到+
        plus = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_plus")
        #經過ID找到=
        equal = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_equal")
        #經過ID找到結果
        real_result = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/display")
        #點擊7
        seven.click()
        #點擊+
        plus.click()
        #點擊3
        three.click()
        #點擊=
        equal.click()

結果判斷

在找到元素並對元素進行相應操做後,須要確認結果是否符合預期

結果判斷有兩種方式:

  • 斷言
    • assertEqual(a, b)---判斷a==b
    • assertNotEqual(a, b)---判斷a!=b
    • assertTrue(x)---bool(x) is True
    • assertFalse(x)---bool(x) is False
  • 截圖對比
    • get_screenshot_as_file(self, filename)
    • save_screenshot(self, filename)
    • get_screenshot_as_png(self)
    • get_screenshot_as_base64(self)

在 test_plus() 裏添加斷言和截圖:

def test_plus(self):
        #預期結果等於10
        result = "10"
        #經過ID找到7
        seven = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_7")
        #經過ID找到3
        three = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_3")
        #經過ID找到+
        plus = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_plus")
        #經過ID找到=
        equal = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_equal")
        #經過ID找到結果
        real_result = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/display")
        #點擊7
        seven.click()
        #點擊+
        plus.click()
        #點擊3
        three.click()
        #點擊=
        equal.click()
        #斷言結果是否相等
        self.assertEqual(real_result.text, result)
        #截圖
        self.driver.get_screenshot_as_file(self.SCREEN_SHOT_PATH + "plus_result.png")

報告展現

當運行完全部的 test case 後,如何以直觀的形式展現結果?

Github 上有一個開源項目---HtmlTestRunner,可以以 HTML 的形式輸出報告。

一、安裝 HtmlTestRunner

pip install html-testRunner

二、導入 HtmlTestRunner 模塊,使用 HTMLTestRunner 替換 unittest.TextTestRunner

#導入HtmlTestRunner
import HtmlTestRunner

...

#程序入口
if __name__ == '__main__':
    #TestSuite,將全部測試用例載入suite
    suite = unittest.TestLoader().loadTestsFromTestCase(CalculatorTest)
    #TestRunner,運行測試用例
    # unittest.TextTestRunner(verbosity=2).run(suite)
    
    #運行case+輸出報告
    runner = HtmlTestRunner.HTMLTestRunner(output='cc_report')
    runner.run(suite)

示例:


附上完整的代碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Shengjie.Liu
# @Time    : 2019-06-03 14:47
# @File    : calculator_test.py
# @Desc    : 

#導入unittest測試框架
import unittest
#導入appium客戶端庫
from appium import webdriver
#導入time模塊
from time import sleep
#導入HtmlTestRunner
import HtmlTestRunner

class CalculatorTest(unittest.TestCase):
    # pass

    # 截圖路徑
    SCREEN_SHOT_PATH = "/Users/liushengjie/PycharmProjects/AppiumTest/share/"

    #SetUP,case運行前的環境初始化
    def setUp(self):
        # pass
        #字典變量,初始化配置,提供創建session的全部必要信息:http://appium.io/docs/en/writing-running-appium/caps/index.html
        desired_caps = {}
        #被測應用平臺:iOS/Android
        desired_caps['platformName'] = 'Android'
        #被測應用平臺版本:adb shell getprop ro.build.version.release
        desired_caps['platformVersion'] = '8.0.0'
        #測試設備名:adb devices
        desired_caps['deviceName'] = 'CB512FCM14'
        #被測應用包名
        desired_caps['appPackage'] = 'weightloss.constellation.education.tools'
        #被測應用啓動時的活動名
        desired_caps['appActivity'] = 'com.weightloss.constellation.education.tools.SplashActivityAlias'
        #服務端等待客戶端發送消息的超時時間
        desired_caps['newCommandTimeout'] = 150
        #在一個session開始前不重置被測程序的狀態
        desired_caps['noReset'] = True
        #是否支持uicode的鍵盤(輸入中文需設置)
        desired_caps['unicodeKeyboard'] = True
        #以desired_caps做爲參數初始化WebDriver鏈接
        #Appium服務器的IP:http://localhost
        #端口號:4723
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
        sleep(10)

    #TearDown,case運行後的環境恢復
    def tearDown(self):
        # pass
        #退出driver,關閉被測應用全部的關聯窗口
        self.driver.quit()

    #TestCase,測試用例1
    def test_case_1(self):
        pass

    def test_plus(self):
        #預期結果等於10
        result = "10"
        #經過ID找到7
        seven = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_7")
        #經過ID找到3
        three = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_3")
        #經過ID找到+
        plus = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_plus")
        #經過ID找到=
        equal = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/button_equal")
        #經過ID找到結果
        real_result = self.driver.find_element_by_id("weightloss.constellation.education.tools:id/display")
        #點擊7
        seven.click()
        #點擊+
        plus.click()
        #點擊3
        three.click()
        #點擊=
        equal.click()
        #斷言結果是否相等
        self.assertEqual(real_result.text, result)
        #截圖
        self.driver.get_screenshot_as_file(self.SCREEN_SHOT_PATH + "plus_result.png")


#程序入口
if __name__ == '__main__':
    #TestSuite,將全部測試用例載入suite
    suite = unittest.TestLoader().loadTestsFromTestCase(CalculatorTest)
    #TestRunner,運行測試用例
    # unittest.TextTestRunner(verbosity=2).run(suite)

    #運行case+輸出報告
    runner = HtmlTestRunner.HTMLTestRunner(output='cc_report')
    runner.run(suite)

此份文檔僅作拋磚引玉之用,但願同窗們能夠根據此文檔完成第一個 UI 自動化測試用例。至於以後的編寫,須要你們勤查資料,多看官網。

相關文章
相關標籤/搜索