WeChat applet UI automation testing practice: Minium+PageObject

The applet architecture is divided into a rendering layer and a logic layer . Although the operating environments of each platform are very similar, there are still some differences (as shown in the figure below). For example, JavaScript syntax and API support are inconsistent, and WXSS rendering performance is also different, so whether it is Whether it is manual testing or UI automation testing, it is necessary to check the real performance of the applet on iOS and Android respectively.

picture

Due to ecological reasons, there are currently few small program UI automation frameworks to choose from. In the framework selection process, I investigated the three frameworks of Appium, Airtest and Minium, and compared the three frameworks, forming the following chart:

picture

Appium’s means of realizing automated testing of WeChat applets is basically to apply the test plan for Hybrid Apps, by locating H5 App resource controls and combining screen coordinates to control the page elements of applets; NetEase’s Airtest is based on image recognition And Poco control recognition, I have done a more in-depth understanding of this framework before, but like Appium, for the automated testing of small programs, the above two cannot go deep into the logic layer of the small program, and can only act on the rendering layer. From another From a perspective, these two frameworks also belong to the category of black-box automated testing.

01 Minion

Next, let me introduce today's protagonist: Minium . It is the official WeChat mini-program automation framework, providing Python3 and JavaScript versions (the latter is currently out of maintenance, and the minium in the following article only refers to the Python version), and the latest version is 1.0.0b2. Minium is not limited to UI automation, it also provides many useful features, such as support for calling and mocking interfaces on some wx objects, support for obtaining and setting applet page data, support for directly triggering applet element binding events, and so on.

In addition, minium provides a test framework based on unittest package. Using this simple framework can also achieve twice the result with half the effort for small program testing. With the above functions, it not only simplifies some preparatory work for use cases, but also enables more targeted and comprehensive testing of small programs.

The download, installation and official documentation of minium can be viewed in the code base. The official documentation is relatively clear. In addition, the following websites are also helpful in the learning process:

  • WeChat Open Community : For some questions about the use of minium, you can search for "minium" in the upper right corner to find answers or ask questions;

  • WeChat developer tools : minium is strongly associated with WeChat developer tools, and development and debugging scripts need to use WeChat developer tools;

  • Minium Demo:  The official python version of the demo, the content is very simple, you can use it to get familiar with the framework, if you want to run the demo, you need to download the sample applet code first;

02 Minium + Page Object

Early GUI automation test scripts, whether it is Selenium or UFT, are usually composed of a series of sequential operations of page controls, which is a bit like a "journal account" at the operation level, which is mainly reflected in the following aspects :

  • The logic level of the script is not clear enough, it belongs to the All-in-one style, which not only locates the page elements, but also operates the elements;

  • The readability of the script is poor. In an actual project, it is difficult to visually see which control the script is operating from the code, and each line of the script directly describes the element operation on each page, and it is impossible to intuitively see the higher level of the script. business testing process;

  • Common steps are repeated across a large number of test scripts;

Page Object emerged to solve the above problems. It is the best design pattern for the development practice of UI automation testing projects. It adopts the design idea of ​​layered encapsulation, and different layers care about different problems. The page object layer only cares about element positioning, and the test case only cares about the test data. Reduce redundant codes by encapsulating interface elements and functional modules. In later maintenance, if element positioning or functional modules change, you only need to adjust the code encapsulated by page elements or functional modules, which significantly improves the maintainability of test cases .

Based on the PO mode, the directory structure and description of the Mini Program UI Automation Test Demo project are as follows:

picture

  • cases/: store business test cases;

  • outputs/: Minium test report;

  • pages/: page object model;

  • *config.json: Minium project configuration file;

  • suite.json: Minium test plan file;

  • route.py: Unified storage of mini-program page routes;

  • utils.py: store some public methods;

03 specific code

Let's start with the specific code and briefly describe the design ideas of the project.

The first is BasePage, which is the base class of the page model and is used to encapsulate methods common to all pages.

import abc

import time



class BasePage(abc.ABC):

    def __init__(self, mini, route, title=""):
         self.mini = mini
         self.route = route
         self.title = title 
  
  def open(self):
       """跳转到小程序目标页面"""
        self._open(self.route, self.title, open_type='redirect')

    def check_element(self):
        """页面元素审查
        在子类中实现此方法时,建议使用Minium框架中提供的断言方法,原因如下:
        调用 Minium 框架提供的断言方法,会拦截 assert 调用,记录运行时数据和截图,自动在测试报告
        中生成截图 (需要在配置文件中将 assert_capture 设置为True)
        但是如果直接assert或使用unittest.TestCase提供的断言,当断言失败时,无法自动生成截图
        """
        raise NotImplementedError    def on_page(self, route,title=None, wait_util_page_contain_keys: list = None):
        """通过对title和route断言,校验跳转进入的当前页是否符合预期"""
        if wait_util_page_contain_keysis not None and isinstance(wait_util_page_contain_keys, list):
            self.mini.page.wait_data_contains(wait_util_page_contain_keys)
        else:
            time.sleep(2)

        self.mini.assertEqual(self.current_route, route,
                              msg="页面路由不匹配, 预期:{},实际:{}".format(route, self.current_route))
        if title:
            self.mini.assertEqual(self.current_title, title,
                                  msg="页面标题不匹配, 预期:{},实际:{}".format(title, self.current_title))

     @property
     def current_title(self) -> str:
        """获取当前页面 head title, 具体项目具体分析,以下代码仅用于演示"""
        return self.mini.page.get_element("XXXXXX").inner_text

     @property
     def current_route(self) -> str:
        """获取当前页面route, 具体项目具体分析, 以下代码仅用于演示"""
        return self.mini.app.get_current_page().path     

def _open(self, route, title, open_type=None):
        """
        小程序页面跳转可以使用以下三个方法, 一些区别如下:
        1.`navigate_to`: 此方法会保留当前页面,并跳转到应用内的某个页面(不能跳到tabbar页面). 小程序中页面栈最多十层, 如果超过十层时,再使用此方法
        跳转页面, 会抛出以下异常:`minium.framework.exception.MiniAppError: webview count limit exceed`. 因此需要在运行用例后及时清除页面栈;
        2. `redirect_to`: 关闭当前页面,重定向到应用内的某个页面,使用此方法跳转页面时,会替换页面栈,因此页面栈不会超限,但是也导致不支持页面回退;
        3. `relaunch`: 关闭所有页面,清空页面栈,打开到应用内的某个页面;
        """
        open_type = 'redirect' if open_type is None else open_type       if open_type.lower() == "navigate":
            self.mini.app.navigate_to(route)
        elif open_type.lower() == "redirect":
            self.mini.app.redirect_to(route)
        else:
            self.mini.app.relaunch(route)

        self.on_page(route, title)

The page model objects of a specific business need to inherit BasePage. Taking IndexPage as an example, the code is as follows:

from pages.BasePage import BasePage

from route import XXXXX



class IndexPage(BasePage):

    locators = {
        "AAA": "view#aaa",  
        "BBB": "view.bbb>image"
    }

    def check_element(self):
        self.mini.assertTrue(self.mini.page.element_is_exists(IndexPage.locators['AAA']) is True)
        self.mini.assertTrue(self.mini.page.element_is_exists(IndexPage.locators['BBB']) is True)

    def click_query_btn(self):
        self.mini.page.get_element("view", inner_text="xxxx").click()
        self.on_page(route=XXXXX.XXXX.route, title=XXXXX.XXXX.title)

BaseEntity is the base class of test cases, which is used to uniformly set the preparation and cleaning work of the test cases. The test cases of all projects inherit this class:

from pathlib import Path

import minium



class BaseEntity(minium.MiniTest):

    """测试用例基类"""
    @classmethod
    def setUpClass(cls):
         super(BaseEntity, cls).setUpClass()
         output_dir = Path(cls.CONFIG.outputs)
         if not output_dir.is_dir():
             output_dir.mkdir()

    @classmethod
    def tearDownClass(cls):
        super(BaseEntity, cls).tearDownClass()
        cls.app.go_home()

    def setUp(self):
        super(BaseEntity, self).setUp()

    def tearDown(self):
        super(BaseEntity, self).tearDown()

The code content of cases.Moudle_1.index_test.IndexTest is as follows:

from cases import BaseEntity

from pages.Moudle_1.IndexPage import IndexPage

from route import XXXXX



class ParkIndexTest(BaseEntity):

    def test_index_page(self):
         index_page = IndexPage(self, XXXXX.INDEX.route, XXXXX.INDEX.title)
         index_page.open()
         index_page.check_element()
         index_page.click_query_btn()

Summarize:

  • Advantages: The PO mode encapsulates the interaction details of the page interface, and the test case completes specific operations based on the page object, which allows our automated test script cases to focus more on the business rather than the interface details, improving the readability of the test case .

  • Disadvantages (personal opinion): Developing and maintaining the class of the page object (Page Class) is a very time-consuming and labor-intensive thing.

    Plan to be studied: Mini-program page objects are automatically generated, no need to manually maintain Page Class, only need to provide page routing, it will automatically generate the positioning information of the controls on this page, and automatically generate Page Class;

Finally: The complete software testing video tutorial below has been sorted out and uploaded, and friends who need it can get it by themselves [Guaranteed 100% free]

Software Testing Interview Documentation

We must study to find a high-paying job. The following interview questions are the latest interview materials from first-tier Internet companies such as Ali, Tencent, and Byte, and some Byte bosses have given authoritative answers. Finish this set The interview materials believe that everyone can find a satisfactory job.

Guess you like

Origin blog.csdn.net/AI_Green/article/details/132561940