This article is excerpted from the teaching content of hogwarts “Test Development Practical Progress” course.
In the process of UI automation testing, faced with complex business scenarios, the following challenges are often encountered:
- Simple recording/playback speed is fast, but can not adapt to complex scenes;
- It is more flexible to write automatic test scripts, but the workload is heavy and the maintainability is poor.
- PageObject can adapt to various UI scenarios, but its structure is loose and cannot be transferred in multiple projects.
As a result, test teams often also need a custom testing framework that compensates for the shortcomings of existing frameworks.
Test frameworks encapsulate ideas
As the UI automatic test framework is used around the UI interface, the PageObject design mode is still used to encapsulate the UI and test, and the script can be effectively organized and applied coherently with the Pytest unit test, thus improving the maintainability and readability of the framework.
As the test framework is based on PageObject design mode, the main direction is PO improvement, data drive, exception handling, etc., such as:
- Data drive of test data: data is stored in external YAML file, and data is read by YAML tool.
- Data drive of data steps: put the operation steps in the external YAML file, use YAML tools to read the operation steps, and use special functions to parse and realize the operation steps;
- Automatic exception handling mechanism: encapsulation and improvement of element lookup module, including how to handle popovers;
Page_Object transformation
As a universal UI testing framework, PageObjet is not only suitable for Web automation testing, but also for Appium mobile automation testing. Its advantages are as follows:
- Reduce code duplication
- Improve test case readability
- Improve test case maintainability
PO transformation example (based on Snowball App)
This case will be the Snowball App Page Objetct encapsulation and improvement.
When the Snowball App is started, it will enter the home page. Click the search box to enter the search page, search for a stock and determine if the stock price is greater than 200:
PageObjetct has the following module relationships. All modules inherit BasePage, App to start, restart, and stop operations, and Main to enter the search page and enter the stock page:
The base_page module is the parent of all page classes. It defines common methods, such as wrapping the following find methods so that subclasses can call find:
from appium.webdriver.webdriver import WebDriverclass BasePage: _driver: WebDriver def __init__(self, driver: WebDriver = None): self._driver = driver def find(self, locator, value: str = None): If isinstance(locator, tuple): return self._driver.find_element(*locator) else: if isinstance(locator, tuple): return self._driver. return self._driver.find_element(locator, value)Copy the code
App module encapsulates the startup, restart, stop and other methods of the App. When the App starts, the main page will be entered, so the following main method should return main. The definition of main class will be explained later:
from appium import webdriverfrom test_appium.page.base_page import BasePagefrom test_appium.page.main import Mainclass App(BasePage): # specifies the package name and activity app _package = "com. Xueqiu. Android" _activity = ". The WelcomeActivityAlias "def start (self) : If self._driver is None: caps = {} caps["platformName"] = "android" caps["deviceName"] = "hogwarts" caps["appPackage"] = self._package Caps ["appActivity"] = self._activity caps["noReset"] = True # Initialize driver self._driver = Webdriver. Remote (" http://localhost:4723/wd/hub ", caps). Self _driver. Implicitly_wait (30) # if the driver is not null, Start the activity else: print(self._driver) self._driver.start_activity(self._package, self._activity) return self def restart(self): Pass def stop(self): pass def main(self) -> main: # return main(self._driver)Copy the code
The Main module is the PageObject of the home page. Its methods encapsulate the important functions of the home page. For example, goto_search_page in the following code encapsulates the click to Search and jump to the Search page:
from appium.webdriver.common.mobileby import MobileByfrom selenium.webdriver.common.by import Byfrom test_appium.page.base_page import BasePagefrom test_appium.page.profile import Profilefrom test_appium.page.search import Searchclass Main(BasePage): Def goto_search_page(self): Self.find (mobileby.id, "tv_search").click() # return Search(self._driver) def goto_stocks(self): pass def goto_trade(self): pass def goto_messages(self): passCopy the code
The Search module can Search for a stock and also get the price of the stock, as shown below:
The encapsulation code is as follows:
from appium.webdriver.common.mobileby import MobileByfrom selenium.webdriver.remote.webdriver import WebDriverclass Search: _driver: WebDriver def __init__(self, driver): self._driver = driver Def search(self, key: STR): self._driver.find_element(MobileBy.ID, "search_input_text").send_keys(key) self._driver.find_element(MobileBy.ID, Def get_price(self, key: STR) -> float: float return float(self._driver.find_element(MobileBy.ID, "current_price").text)Copy the code
Finally, create a test for the above code and create a test module test_Search:
import pytestfrom test_appium.page.app import Appclass TestSearch: def setup(self): self.main = App().start().main() def test_search(self): assert self.main.goto_search_page().search("alibaba").get_price("BABA") > 200Copy the code
(Article from Hogwarts Testing Institute)
Welfare benefits:
Front-line Internet famous enterprises test development position internal promotion channel
Test development internal communication circle, expand your test network
For free: Interface testing + Performance testing + Automated testing + Test development + Test cases + resume template + test documentation