1. 程式人生 > 實用技巧 >PO設計模式-實現移動端自動化測試

PO設計模式-實現移動端自動化測試

開發環境:python 3.6.5 + selenium 2.48.0 + pytest框架 + Android 5.1

工具:pycharm + Appium + Genymotion

測試機型:Samsung Galaxy S6

#需求:設計3個測試用例
#1.實現點選設定->顯示->放大鏡(查詢)->輸入內容->點選返回按鈕
#2.實現點選設定->更多->行動網路->首選網路型別->2G
#3.實現點選設定->更多->行動網路->首選網路型別->3G

以下是PO模式設計檔案目錄

加入我們,群,642830685,領取最新軟體測試資料大廠面試和Python自動化、介面、框架搭建學習資料!

實現設計模式前:

```

import time
from appium import webdriver


class TestSetting:

    def setup(self):
        # server 啟動引數
        desired_caps = {}
        # 裝置資訊
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '5.1'
        desired_caps['deviceName'] = '192.168.56.101:5555'
        
# app的資訊 desired_caps['appPackage'] = 'com.android.settings' desired_caps['appActivity'] = '.Settings' # 解決輸入中文 desired_caps['unicodeKeyboard'] = True desired_caps['resetKeyboard'] = True # 宣告我們的driver物件 self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub'
, desired_caps) def test_mobile_network_2g(self): self.driver.find_element_by_xpath("//*[contains(@text,'更多')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'行動網路')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'首選網路型別')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'2G')]").click() def test_mobile_network_3g(self): self.driver.find_element_by_xpath("//*[contains(@text,'更多')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'行動網路')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'首選網路型別')]").click() self.driver.find_element_by_xpath("//*[contains(@text,'3G')]").click() def test_mobile_display_input(self): self.driver.find_element_by_xpath("//*[contains(@text,'顯示')]").click() self.driver.find_element_by_id("com.android.settings:id/search").click() self.driver.find_element_by_id("android:id/search_src_text").send_keys("hello") self.driver.find_element_by_class_name("android.widget.ImageButton").click() def teardown(self): self.driver.quit()
···

實現設計模式後:


公共部分抽取在base資料夾


抽取前置配置:


base_driver.py

```

from appium import webdriver

def Testbase():
    # server 啟動引數
    desired_caps = {}
    desired_caps['platformName'] = 'Android'
    desired_caps['platformVersion'] = '5.1'
    desired_caps['deviceName'] = '192.168.56.101:5555'
    desired_caps['appPackage'] = 'com.android.settings'
    desired_caps['appActivity'] = '.Settings'
    desired_caps['unicodeKeyboard'] = True
    desired_caps['resetKeyboard'] = True
    # 解決輸入中文問題
    desired_caps['unicodeKeyboard'] = True
    desired_caps['resetKeyboard'] = True

    # 宣告driver物件
    driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
    return driver
```

抽取公共方法:

base_action.py

```

from selenium.webdriver.support.wait import WebDriverWait


class BaseAction:
    def __init__(self, driver):
        self.driver = driver
    # 顯示等待
    def find_elements(self, loc, time=10, poll=1):
        return WebDriverWait(self.driver, time, poll).until(lambda x: x.find_element(loc[0], loc[1]))

    # 定義一個函式,取按鈕的元素
    def act_click(self,loc):
        return self.act_title(loc).click()
    # 定義一個函式,取輸入框的元素
    def act_text(self,loc,text):
        return self.act_title(loc).send_keys(text)
    def act_title(self, loc):
        by = loc[0]
        value = loc[1]
        return self.driver.find_element(by, value)
```

頁面主體部分:

page

測試用例1:

display_page.py

```
from base.base_action import BaseAction
from selenium.webdriver.common.by import By

class DisplayPage(BaseAction):
    # 初始化方法
    # 顯示按鈕
    see_button = By.XPATH, "//*[contains(@text,'顯示')]"
    # 放大鏡按鈕
    search_button = By.ID, "com.android.settings:id/search"
    # 放大鏡旁邊的輸入文字
    search_edit_text = By.ID, "android:id/search_src_text"
    # 返回按鈕
    back_button = By.CLASS_NAME, "android.widget.ImageButton"
    #
    # # 定義一個函式,取按鈕的元素
    # def act_click(self,loc):
    #     return self.driver.find_element(loc[0],loc[1]).click()
    # # 定義一個函式,取輸入框的元素
    # def act_text(self,loc,text):
    #     return self.driver.find_element(loc[0],loc[1]).send_keys(text)

    # def __init__(self, driver):
    #     self.driver = driver


    # 點選顯示
    def click_see(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'顯示')]").click()
        # self.driver.find_element(self.see_button).click()
        self.act_click(self.see_button)

    # 點選放大鏡
    def click_search(self):
        # self.driver.find_element_by_id("com.android.settings:id/search").click()
        # self.driver.find_element(self.search_button).click()
        self.act_click(self.search_button)


    # 輸入文字
    def input_text(self, text):
        # self.driver.find_element_by_id("android:id/search_src_text").send_keys(text)
        # self.driver.find_element(self.search_edit_text).send_keys(text)
        self.act_text(self.search_edit_text,text)

    # 點選返回
    def click_back(self):
        # self.driver.find_element_by_class_name("android.widget.ImageButton").click()
        # self.driver.find_element(self.back_button).click()
        self.act_click(self.back_button)
```

測試用例2/3:

network_page.py

from selenium.webdriver.common.by import By
from base.base_action import BaseAction

class NetworkPage(BaseAction):

# 抽離元素
    # 更多按鈕
    more_button = By.XPATH, "//*[contains(@text,'更多')]"
    # 網路移動按鈕
    network_button = By.XPATH, "//*[contains(@text,'行動網路')]"
    #首選網路型別按鈕
    first_network_button = By.XPATH, "//*[contains(@text,'首選網路型別')]"
    # 2G選擇按鈕
    button_2g = By.XPATH, "//*[contains(@text,'2G')]"
    # 3G選擇按鈕
    button_3g = By.XPATH, "//*[contains(@text,'3G')]"

# 程式碼精簡方式,提取公共元素
    def click_more(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'更多')]").click()
        # self.driver.find_element(By.XPATH, "//*[contains(@text,'更多')]").click()
        self.act_click(self.more_button)


    def click_network(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'行動網路')]").click()
        # self.driver.find_element(By.XPATH, "//*[contains(@text,'行動網路')]").click()
        self.act_click(self.network_button)


    def click_first_network(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'首選網路型別')]").click()
        # self.driver.find_element(By.XPATH, "//*[contains(@text,'首選網路型別')]").click()
        self.act_click(self.first_network_button)

    def mobile_network_2g(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'2G')]").click()
        # self.driver.find_element(By.XPATH, "//*[contains(@text,'2G')]").click()
        self.act_click(self.button_2g)


    def mobile_network_3g(self):
        # self.driver.find_element_by_xpath("//*[contains(@text,'3G')]").click()
        # self.driver.find_element(By.XPATH, "//*[contains(@text,'2G')]").click()
        self.act_click(self.button_3g)

測試用例1的指令碼:

test_display.py

# 獲取本地地址
import sys, os
sys.path.append(os.getcwd())

from base.base_driver import Testbase
from page.display_page import DisplayPage

class TestDisplay:
    def setup(self):
        self.driver = Testbase()
        self.display_page = DisplayPage(self.driver)

    def test_mobile_display_input(self):
        # 點選顯示
        self.display_page.click_see()
        # 點選放大鏡
        self.display_page.click_search()
        # 文字輸入
        self.display_page.input_text("hello")
        # 點選返回
        self.display_page.click_back()

    def teardown(self):
        self.driver.quit()

測試用例2/3的指令碼:


test_network.py

import os, sys
sys.path.append(os.getcwd())
from page.network_page import NetworkPage
from base.base_driver import Testbase

class TestNetwork:
    def setup(self):
        self.driver = Testbase()
        self.network_page = NetworkPage(self.driver)
        self.network_page.click_more()
        self.network_page.click_network()
        self.network_page.click_first_network()

    def test_mobile_network_2g(self):

        self.network_page.mobile_network_2g()

    def test_mobile_network_3g(self):
        # self.network_page.click_more()
        # self.network_page.click_network()
        # self.network_page.click_first_network()
        self.network_page.mobile_network_3g()

    def teardown(self):
        self.driver.quit()

pytest框架的執行檔案:


pytest.ini


注意:因為檔案為ini格式,#不被識別為註釋標識,請刪掉註釋部分


[pytest]
#檔案路徑,和生成報告
addopts = -s --html=./report/report.html
testpaths = ./scripts
#執行的檔名
python_files = test_*.py
#執行檔案裡面的類
python_classes = Test*
#執行類中的那些方法
python_functions = test_*

如果您覺得對您有幫助,請點贊,收藏,分享三連!您的支援是筆者最大的動力!

加入我們,群,642830685,領取最新軟體測試資料大廠面試和Python自動化、介面、框架搭建學習資料!