小程序架构上分为渲染层和逻辑层,尽管各平台的运行环境十分相似,但是还是有些许的区别(如下图),比如说JavaScript 语法和 API 支持不一致,WXSS 渲染表现也有不同,所以不论是手工测试,还是UI自动化测试,都必须要在 iOS 和 Android 上分别检查小程序的真实表现。

由于生态方面的原因,目前可选择的小程序UI自动化框架较少。在框架选取过程中,我考察了Appium、Airtest和Minium三个框架,并将三者做了对比,形成了以下图表:

Appium实现微信小程序自动化测试的手段基本上还是套用针对 Hybrid App 的测试方案,通过定位H5 App资源控件,并结合屏幕坐标的方式来操控小程序的页面元素;网易推出的Airtest则是基于图像识别和Poco控件识别,之前也对此框架做过比较深入的了解(可以看我之前的文章),但是和Appium一样,对于小程序自动化测试来说,以上两者无法深入小程序逻辑层,只能作用于渲染层,从另外一个角度来说,这两个框架还属于黑盒自动化测试的范畴。

接下来再介绍一下今天的主角:Minium。它是微信小程序官方推出自动化框架, 提供了 Python3 和 JavaScript 版本(后者目前已停止维护,后文中的minium单指Python版本),目前最新的版本为1.0.0b2。 minium不仅限于 UI 自动化,它还提供了很多有用的特性,比如说支持调用和 Mock 部分 wx 对象上的接口,支持获取和设置小程序页面数据,支持直接触发小程序元素绑定事件等等。另外,minium提供一个基于unittest封装好的测试框架,利用这个简单的框架对小程序测试也可以起到事半功倍的效果。有了以上功能,不但可以简化用例的一些前期准备工作,更可以对小程序做更针对和更全面的测试。

minium的下载安装和官方文档,可以在代码库查看。官方文档写的还算较为清晰,除此之外,以下链接在学习过程中也有帮助。

微信开放社区: 一些minium使用方面的问题,可以在右上角搜索 "minium" 寻找答案或发起提问;

微信开发者工具: minium与微信开发者工具强关联,开发调试脚本都需要使用微信开发者工具;

Minium Demo: 官方提供的python版本的demo,内容非常简单,可以用来简单熟悉一下框架,若要运行demo需要先下载示例小程序代码;

Minium + Page Object

早期 GUI 自动化测试脚本,无论是Selenium还是UFT,脚本通常是由一系列的页面控件的顺序操作组成的,有点像操作级别的“流水账”,这主要体现在以下几个方面:

脚本逻辑层次不够清晰,属于 All-in-one 的风格,既有页面元素的定位查找,又有对元素的操作;

脚本的可读性差,在实际项目中,很难从代码中直观看出到底脚本在操作哪个控件,并且脚本的每一行都直接描述各个页面上的元素操作,无法直观的看出脚本更高层的业务测试流程;

通用步骤会在大量测试脚本中重复出现;

Page Object 就是为了解决以上问题而出现的,它是UI自动化测试项目开发实践的最佳设计模式,采用分层封装的设计思想,不同层关心不同的问题。页面对象层只关心元素定位问题,测试用例只关心测试的数据。通过对界面元素和功能模块的封装减少冗余代码,在后期维护中,若元素定位或功能模块发生变化,只需要调整页面元素或功能模块封装的代码,显著提高测试用例的可维护性。

基于PO模式,小程序UI自动化测试Demo项目的目录结构及说明如下:

cases/: 存放业务测试用例;

outputs/: Minium测试报告;

pages/: 页面对象模型;

*config.json: Minium项目配置文件;

suite.json: Minium测试计划文件;

route.py: 统一存放小程序页面路由;

utils.py: 存放一些公共方法;

下面再从具体代码入手,简单讲述一下项目的设计思路。

首先是BasePage,它是页面模型基类,用于封装所有页面公用的方法。

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_keys is 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)

具体业务的页面模型对象都需要继承BasePage,以IndexPage为例,代码如下所示:

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为测试用例基类,用于统一设置用例准备和清理工作,所有项目的测试用例都继承此类:

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()

cases.Moudle_1.index_test.IndexTest代码内容如下:

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()

总结:

优点:PO模式对页面界面交互细节进行了封装,而测试用例基于页面对象完成具体操作,这样可以使我们的自动化测试脚本案例更关注业务,而非界面细节,提高了测试案例的可读性。

缺点(个人观点):开发和维护页面对象的类(Page Class),是一件很耗费时间和体力的事儿。

待研究方案:小程序页面对象自动生成,不用再手工维护 Page Class ,只需要提供页面路由,就会自动生成这个页面上控件的定位信息,并自动生成 Page Class;

一言以蔽之:如果没有深入实践自动化测试,提高测试效率根本无从谈起。

微信小程序python自动化测试_微信小程序UI自动化测试实践:Minium+PageObject相关推荐

  1. 微信 小程序 python 商城_微信小程序——商城篇

    前言 随着wepy和mpvue的出现及流行,开发小程序变的越来越便捷和强大,作为基佬社区的一份子,我们都需要把自己遇到的问题以及如何解决的方式相互分享,这样才能帮助到更多的朋(ji)友(lao).如有 ...

  2. 微信 小程序 python 渲染_微信小程序渲染html内容

    最近又做了一个新的小程序关于物流订单查询欢迎来体验 遇到了一个小问题:数据中返回电话号码的字符串识别出来并且高亮和可以绑定事件.比如数据中包含您的派送员黄xx正在派件,电话:137xxxx41460已 ...

  3. 微信小程序 python接口_微信小程序-封装请求基准路径、接口API 和使用

    1.在文件夹utils下新建 request.js文件 2.封装请求代码 // 基准路径 //路径仅为举例 const baseurl ='https://127.0.0.1' //get请求 fun ...

  4. 微信跳一跳python代码_微信跳一跳python程序

    #源码下载地址:https://files.cnblogs.com/files/cnfan/jump.rar importosimportcv2importnumpy as npimporttimei ...

  5. 猿来小课Python视频老师简述让程序员崩溃的瞬间

    作为一个资深的程序猿,我日常的任务就是和代码无数次交锋,在公司敲代码时不知道你们有没有遇到过让你崩溃的瞬间呢?本篇文章猿来小课Python视频老师就收集整理了一些让程序员崩溃的瞬间,让我们下面一起来对 ...

  6. Python+Selenium.webdriver实现WEB端UI自动化测试(实例脚本)

    本篇记录基于Python+Selenium.webdriver实现WEB端UI自动化测试,其中测试用例使用excel维护.为了在实际项目种的扩展应用,建议学习webdriver的元素定位方法,欢迎在评 ...

  7. ATX+Python+uiautomator2环境下进行手机UI自动化测试

    ATX+Python+uiautomator2环境下进行手机UI自动化测试 环境搭建 手机环境初始化 在网页端的UI查看器中查看控件及属性 以下是一些自己测试的脚本 环境搭建 开始配置uiautoma ...

  8. 微信小程序python自动化测试_微信小程序的自动化测试框架

    微信小程序的自动化测试框架 微信发布了小程序的自动化测试框架Minium,提供了多种运行验证方式,其特点: 支持一套脚本,iOS & Android & 模拟器,三端运行 提供丰富的页 ...

  9. 微信小程序 python 自动化测试_微信小程序的自动化测试框架

    微信小程序的自动化测试框架 微信发布了小程序的自动化测试框架Minium,提供了多种运行验证方式,其特点: 支持一套脚本,iOS & Android & 模拟器,三端运行 提供丰富的页 ...

最新文章

  1. Linux查看目录挂载点
  2. c语言退出程序命令_C语言#error命令,阻止程序编译
  3. delphi 调 web api_小程序web同构Kbone
  4. mysql 读写分离 max_MaxScale实现MySQL读写分离和负载均衡
  5. mouted vue 操作dom_vue中关于dom的操作
  6. UI设计灵感|迷人的概念加载动画设计
  7. js高级(类和对象)
  8. 波卡生态DAO基础设施完成150万美元战略融资
  9. 对服务与工厂感到困惑
  10. VS2015断点调试方法
  11. 安装apk出现Parse error when parsing manifest. Discontinuing installation.解决方案
  12. 1. paip.discuz X2.5 积分(金钱)功能API总结
  13. Ubuntu双网卡绑定
  14. 海思Hi3519AV100sensor移植之一-- imx307
  15. python 66:re正则表达式5(全- tcy)
  16. (转) Csrss进程剖析
  17. 面经——嵌入式常见面试题总结100题(下)
  18. STM32L0外接32768HZ晶振应该接多大的负载电容才合适
  19. 大学英语综合教程二 Unit 5 课文内容英译中 中英翻译
  20. 根据出生日期获取农历信息

热门文章

  1. fifo计算机组成原理课程设计,计算机组成原理实验课题.doc
  2. node项目---编辑修改学生信息页面
  3. 使用 React 遍历对象
  4. 抖音赚钱记,新手如何玩转抖音,每天赚300起(连载十八)
  5. C++结构型模式-享元模式用法总结
  6. json转化为dataframe 和dataframe转化为json
  7. C语言实现八进制转十进制
  8. 上传文件服务器异常怎么办,解决上传图片服务器发生故障的问题
  9. 基于MATLAB的频率分析
  10. 使用国内npm安装electron