史上最全 Appium 自動化測試從基礎到框架實戰精華學習筆記(一)


史上最全 Appium 自動化測試從基礎到框架實戰精華學習筆記(一)

 

本文為霍格沃茲測試學院學員學習筆記。

對測試人來說,Appium 是非常重要的一個開源跨平台自動化測試工具,它允許測試人員在不同的平台(iOS、Android 等)使用同一套 API 來寫自動化測試腳本,這樣可大幅提升代碼復用率和工作效率。

本文匯總了從 Appium 基礎到自動化測試高級實戰中,所涉及到的方方面面的知識點精華內容(如下所示),希望對大家快速總結和復習有所幫助。

Appium 從基礎到自動化測試框架實戰

  1. Appium 基礎 1(環境搭建和簡介)
  2. Appium 基礎 2(元素定位和元素常用方法)
  3. Appium 基礎 3(手勢操作和 uiautomator 查找元素)
  4. Appium 基礎 4(顯式等待)
  5. Appium 基礎 5(toast 和參數化)
  6. Appium 基礎 6(webview)
  7. Appium_ 企業微信練習 (非 PO,增加和刪除聯系人)
  8. Appium_ 企業微信練習 (PO--增加聯系人)

Appium 環境搭建

JDK 的搭建

  • 下載 1.8 的 jdk
  • 新建環境變量:JAVA_HOME 值為:D:\Program Files\Java\jdk1.7.0
  • 新建環境變量:CLASSPATH 值為:.;%JAVA_HOME%\lib;(注意:點號表示當前目錄,不能省略)
  • 在系統變量 Path 的值的前面加入以下內容:%JAVA_HOME%\bin

SDK 的配置

  • 下載 sdk
  • 打開 sdk 的 sdk manager,安裝 tools 前 3 個東西和 google 的 usb 驅動
  • 配置 Android home 里面的 platform-tools 和 tools

Appium 的搭建

  • 安裝 node.js,配置 node.js 的環境變量
  • npm install -g cnpm --registry=https://registry.npm.taobao.org
  • cnpm install -g appium
  • cnpm install -g appium-doctor
  • pip install appium-python-client

appium 運行的 python 代碼

  • mumu 連接 adb 是:adb connect 127.0.0.1:7555
from appium import webdriver

#設置 caps 的值
desire_cap= {
    #默認是 Android
    "platformName":"android",
    #adb devices 的 sn 名稱
    "deviceName":"127.0.0.1:7555",
    #包名
    "appPackage":"com.xueqiu.android",
    #activity 名字
    "appActivity":".view.WelcomeActivityAlias"
}

#運行 appium,前提是要打開 appium server
driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",desire_cap)

Appium 的簡介

Appium 的引擎

  • Android 是 uiautomator2
  • ios 是 xcuitest

Appium 的設計理念

  • webdriver 是基於 http 協議的,第一連接會建立一個 session 會話,並通過 post 發送一個 json 告知服務端相關測試信息
  • client/server 設計模式
  • 客戶端通過 webdriver json wire 協議與服務器通訊
  • 多語言支持
  • server 可以放在任何地方
  • 服務器 nodejs 開發的 http 服務
  • appium 使用 appium-xcuitest-driver 來測試 iphone 設備,其中需要安裝 Facebook 出的 WDA(webdriver agent) 來驅動 ios 測試

Appium 的生態工具

  • adb:Android 控制工具
  • appium Destkop:內嵌 appium server 和 inspector 的綜合工具
  • appium server:appium 的核心工具,命令行工具
  • appium client:各種語言的客戶端封裝庫,用戶連接 appium server,包含 python、java、ruby 等
  • appcrawler 自動遍歷工具

獲取 App 的信息

  • 獲取當前元素界面:adb shell dumpsys activity top
  • 獲取任務列表:adb shell dumpsys activity activities
  • 獲取 app 的 package 和 activity:adb shell;然后 logcat | grep -i displayed
  • 啟動應用:adb shell am start -W -n "com.xueqiu.android/.view.WelcomeActivityAlias -S

Capability 設置

  • 文檔地址:http://appium.io/docs/en/writing-running-appium/caps/index.html
  • platformName:android 通常都是寫 android
  • deviceName:127.0.0.1:7555 這個通常是 adb devices 的名稱
  • appPackage:com.xueqiu.android 這個是 app 的 package 包名
  • appActivity:.view.WelcomeActivityAlias 這個是 app 的 activity 名
  • noReset:true, false 是否重置測試的環境(例如首次打開彈框,或者登陸信息)
  • unicodeKeyboard:true, false 是否需要輸入非英文之外的語言並在測試完成后重置輸入法,比如輸入中文
  • dontStopAppOnReset:true, false 首次啟動的時候,不停止 app
  • skipDeviceInitialization:true, false 跳過安裝,權限設置等操作

測試用的 apk

  • https://github.com/appium/appium/tree/master/sample-code/apps

Android 的基礎知識

Android 的布局

  • Android 是通過容器的布局屬性來管理子控件的位置關系,布局過程就是把界面上的所有的控件,根據他們的間距的大小,擺放在正確的位置
  • 線性布局:LinearLayout
  • 相對布局:RelativeLayout
  • 幀布局:FrameLayout
  • 絕對布局:AbsoluteLayout
  • 表格布局:TableLayout
  • 網格布局:GirdLayout
  • 約束布局:ConstraintLayout

Android 四大組件

  • activity:與用戶交互的可視化界面
  • service:實現程序后台運行的解決方案,比如 qq 音樂的音樂在后台運行,沒有界面
  • content provide:內容提供者,提供程序所需要的數據,比如?提供數據庫?
  • broadcast receiver:廣播接收器,監聽外部事件的到來(比如來電)

Android 常用的控件

  • TextView:文本控件
  • EditText:可編輯文本控件
  • Button:按鈕
  • ImageButton:圖標按鈕
  • ToggleButton:開關按鈕
  • ImageView:圖片控件
  • CheckBox:復選框控件
  • RadioButton:單選框控件

控件知識

  • dom:Document Object Model 文檔對象模型
  • dom 應用:最早應用於 html 和 js 的交互,用戶表示界的控件層級,界面的結構化描述,常見的格式為 html、xml。核心元素為節點和屬性
  • xpath:xml 路徑語言,用於 xml 中的節點定位
  • Android 的應用層級結構是定制的 xml
  • app source 類似於 dom,表示 app 的層級,表示界面里面所有的控件數的結構
  • 每個控件都有它的屬性(resourceid、xpath、aid),沒有 css 屬性

Appium 的元素定位

普通方式的定位

  • driver.find_element_by_accessibility_id() 對應 content-desc
  • driver.find_element_by_id() 對應 resource-id
  • driver.find_element_by_name() 對應 text
  • driver.find_element_by_xpath() 對應 xpath

By 的定位方式

  • 首先要 from appium.webdriver.common.mobileby import MobileBy as By
  • self.driver.find_element(By.ID,"") 對應 resource-id
  • self.driver.find_element(By.XPATH,"") 對應 xpath
  • self.driver.find_element(By.ACCESSIBILITY_ID,"") 對應 content-desc
  • self.driver.find_element(By.NAME,"") 對應 text

Xpath 的定位方式

  • driver.find_element_by_xpath("//*[@text=' 掃一掃 ']")
  • driver.find_element_by_xpath("//*[@resource-id='com.taobao.taobao:id/tv_scan_text']")
  • driver.find_element_by_xpath("//*[@content-desc=' 幫助 ']")
  • driver.find_element(By.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']") and 的使用
  • 父類和兄弟類的方法://[@text=' 性別 ']/..//[@text=' 男 ']。其中 /.. 表示父類,//* 就是兄弟,孫子等類
  • //*[Contains(@text,"tong")] 這是 xpath 的 text 模糊搜索的方法

元素的方法

元素的常用方法

  • 點擊方法:element.click()
  • 輸入操作:element.send_keys("tong")
  • 設置元素的值:element.set_value("tongtong")
  • 清除操作:element.clear()
  • 是否可見:element.is_displayed 返回 true or false
  • 是否可用:element.enabled() 返回 true or false
  • 是否被選中:element.is_selected() 返回 true or false
  • 獲取屬性值:element.get_attribute(name)

屬性值介紹

  • get_attribute(name) 獲取的屬性名稱和 uiautomatorviewer 的一致,但是 index 的值獲取不了
  • 真假獲取的值是 true 和 false 的字符串,並不是 python 的 boolean 值

元素常用的屬性

  • 獲取元素文本:element.text
  • 獲取元素坐標:element.location
  • 結果:{'y':19,'x':498}
  • 獲取元素尺寸(高和寬):element.size
  • 結果:{'width':500,'height':22}

實戰小案例 1

  1. 打開雪球 app
  2. 點擊搜索輸入框
  3. 向搜索輸入框輸入 “阿里巴巴”
  4. 在搜索的結果里選擇阿里巴巴,然后點擊
  5. 獲取這只上香港 阿里巴巴的股價,並判斷這只股價的價格>200
代碼
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By

class TestFind():
    #設置 caps 的值
    def setup(self):
        self.desire_cap= {
            #默認是 Android
            "platformName":"android",
            #adb devices 的 sn 名稱
            "deviceName":"127.0.0.1:7555",
            #包名
            "appPackage":"com.xueqiu.android",
            #activity 名字
            "appActivity":".view.WelcomeActivityAlias",
            "noReset":"true",
            "unicodeKeyboard":True
        }
        #運行 appium,前提是要打開 appium server
        self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
        self.driver.implicitly_wait(5)

    def test_search(self):
        """
        1. 打開雪球 app
        2. 點擊搜索輸入框
        3. 向搜索輸入框輸入 “阿里巴巴”
        4. 在搜索的結果里選擇阿里巴巴,然后點擊
        5. 獲取這只上香港 阿里巴巴的股價,並判斷這只股價的價格>200
        :return:
        """
        sleep(3)
        #點擊搜索框
        self.driver.find_element(By.ID,"com.xueqiu.android:id/tv_search").click()
        #向搜索框輸入阿里巴巴
        self.driver.find_element(By.ID,"com.xueqiu.android:id/search_input_text").send_keys(" 阿里巴巴 ")
        #找到搜索框預覽結果的阿里巴巴,並點擊
        self.driver.find_element(By.XPATH,"//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']").click()
        #選擇 HK 股價的元素
        prices=self.driver.find_elements(By.ID,"com.xueqiu.android:id/current_price")[1]
        #提取股價的 text 屬性
        price=float(prices.text)

        #判斷股價是否大於 200
        assert price > 200

實戰小案例 2

  1. 打開雪球首頁
  2. 定位首頁的搜索框
  3. 判斷搜索框是否可用,並查看搜索框 name 屬性值
  4. 打印搜索框這個元素的左上角坐標和它的寬高
  5. 向搜索框輸入:alibaba
  6. 判斷阿里巴巴是否可見
  7. 如果可見,打印搜索成功點擊,如果不可見,打印搜索失敗
代碼
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy as By


class TestFind():
    #設置 caps 的值
    def setup(self):
        self.desire_cap= {
            #默認是 Android
            "platformName":"android",
            #adb devices 的 sn 名稱
            "deviceName":"127.0.0.1:7555",
            #包名
            "appPackage":"com.xueqiu.android",
            #activity 名字
            "appActivity":".view.WelcomeActivityAlias",
            "noReset":"true",
            "unicodeKeyboard":True
        }
        #運行 appium,前提是要打開 appium server
        self.driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",self.desire_cap)
        self.driver.implicitly_wait(5)

    def test_element_function(self):
        """
        1. 打開雪球首頁
        2. 定位首頁的搜索框
        3. 判斷搜索框是否可用,並查看搜索框 name 屬性值
        4. 打印搜索框這個元素的左上角坐標和它的寬高
        5. 向搜索框輸入:alibaba
        6. 判斷阿里巴巴是否可見
        7. 如果可見,打印搜索成功點擊,如果不可見,打印搜索失敗
        :return:
        """
        sleep(8)
        #找到搜索框的元素
        search=self.driver.find_element(By.ID, "com.xueqiu.android:id/tv_search")
        #當搜索框是可用(類似可點擊)后才進行下面的操作,is_enabled() 返回 Ture or False
        if search.is_enabled():
            #打印搜索框的 text 值
            print(search.text)
            #打印搜索框左上角的坐標
            print(search.location)
            #打印搜索框的高和寬
            print(search.size)
            #點擊搜索框,才可以進行下面的操作
            search.click()
            #在搜索框中輸入阿里巴巴
            self.driver.find_element(By.ID, "com.xueqiu.android:id/search_input_text").send_keys(" 阿里巴巴 ")
            #定義找到預覽結果的阿里巴巴的元素
            alibaba=self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name' and @text=' 阿里巴巴 ']")
            #當 alibaba 元素可見,打開搜索成功,否則打印搜索失敗
            if alibaba.is_displayed():
                print(" 搜索成功 ")
            else:
                print(" 搜索失敗 ")

更多內容,我們在后續文章分享。

想觀看更多內容,可關注公眾號:霍格沃茲測試學院


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM