微信小程序自动化测试框架 Minium——PO模式测试用例

这篇具有很好参考价值的文章主要介绍了微信小程序自动化测试框架 Minium——PO模式测试用例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍PO模式的测试用例,PO模式优点及层级间的关系,相关配置及运行

minitest的测试小程序和测试case:minitest-demo

  • miniprogram-demo:测试小程序
  • testcase:测试case,同时也包含文档的测试case
  • testcase-PO:Page Object(PO) 模式的测试case

PO简介

PO模式是自动化测试项目开发实践的最佳设计模式之一。通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化,只需要调整页面元素封装的代码,提高测试用例的可维护性、可读性。

优点:

  • 减少代码冗余
  • 业务和实现分离
  • 降低维护成本

PO用例层级

  1. 基础层base,初始化、封装Minium的原生方法
  • BaseCase:初始化Minium实例,继承MiniTest类
  • BaseDef:封装Minium的页面跳转、元素定位等方法
  1. 操作层pages,页面对象层,各页面的元素定位,操作等
  • BasePage:封装公用页面基础操作方法,继承BaseDef类
  • HomePage:首页相关元素定位及相关操作等,继承BaseDef类
  1. 测试用例层,主要负责业务逻辑和数据驱动(继承BaseCase类,初始化BasePage、HomePage类)
  • AppTest:测试hook用例
  • ElementTest:测试操作不同组件用例
  • LoginTest:测试登录授权用例
  • NativeTest:测试处理原生控件用例
  • PageTest:测试页面元素定位用例

BaseCase基类

测试用例基类,继承MiniTest类。复写minium.MiniTest类里面的setUpClass、tearDownClass、setUp、tearDown方法

class BaseCase(minium.MiniTest):
    """
    初始化Minium实例,测试用例基类
    """

    @classmethod
    def setUpClass(cls):
        super(BaseCase, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(BaseCase, cls).tearDownClass()

    def setUp(self):
        pass

    def tearDown(self):
        pass

BaseDef公用方法类

封装Minium的页面跳转、元素定位等方法

class BaseDef:
    """
    封装Minium的页面跳转、元素定位等方法
    """

    def __init__(self, mini):
        """
        基类初始化 Minium 实例
        """
        self.mini = mini

    def navigate_to_page(self, route):
        """
        跳转到指定页面
        """
        self.mini.app.navigate_to(route)
        ret = self.wait_page(route)
        return ret

    def redirect_to_page(self, route):
        """
        跳转到指定页面并关闭当前页面
        """
        self.mini.app.redirect_to(route)
        ret = self.wait_page(route)
        return ret

	## ...

/pages 页面对象类

页面对象层,各页面的元素定位,操作等

BasePage基础页面对象类

封装公用页面基础操作方法,继承BaseDef类。例如hook wx API接口,点击元素,获取回调;hook 原生控件弹窗,点击元素,处理弹窗,获取回调等

class BasePage(base_def.BaseDef):
    """
    封装公用页面基础操作方法
    """

    def hook_wx_method(self, method, selector):
        """
        封装hook wx API接口,获取回调
        :param method: API接口
        :param selector: 触发元素选择器
        :return: 信号量,回调信息
        """
        called = threading.Semaphore(0)  # 信号量
        callback_args = None

        def callback(args):
            nonlocal callback_args
            called.release()
            callback_args = args

        # hook wx API接口,获取回调后执行callback
        self.mini.app.hook_wx_method(method, callback=callback)
        # 点击元素
        self.mini.page.get_element(selector).tap()
        is_called = called.acquire(timeout=10)
        # 释放hook
        self.mini.app.release_hook_wx_method(method)
        return is_called, callback_args

	## ...
HomePage首页页面对象类

首页相关元素定位及相关操作等,继承BaseDef类

微信小程序测试用例,微信小程序自动化测试框架,微信小程序,测试用例,小程序

class HomePage(base_def.BaseDef):
    """
    首页相关元素定位及相关操作等
    """

    locator = {
        'app': '/page/view/navigator[1]/button',  # App接口测试
        'page': '/page/view/navigator[2]/button',  # Page接口测试
        'element': '/page/view/navigator[3]/button',  # Element接口测试
        'native': '/page/view/navigator[4]/button',  # Native接口测试
    }

    # 进入不同接口测试
    def interface_page(self, key):
        ele = self.mini.page.get_element(self.locator[key])
        ele.tap()
        ret = False
        if key == 'app':
            ret = self.wait_page(router.appPage)
        elif key == 'page':
            ret = self.wait_page(router.pagePage)
        elif key == 'element':
            ret = self.wait_page(router.elementPage)
        elif key == 'native':
            ret = self.wait_page(router.nativePage)

        return ret

/test测试用例类

主要负责业务逻辑和数据驱动

AppTest

app页面测试用例,测试hook调用

class AppTest(BaseCase):

    def setUp(self) -> None:
        super().setUp()
        # 页面跳转
        self.HomePage.interface_page("app")

    def __init__(self, methodName='runTest'):
        """
        初始化AppTest类,初始化基础页、首页类
        """
        super(AppTest, self).__init__(methodName)
        self.HomePage = home_page.HomePage(self)
        self.BasePage = base_page.BasePage(self)

    def test_hook_wx_method(self):
        """
        hook 小程序方法 getSystemInfo
        :return:
        """
        is_called, callback_args = self.BasePage.hook_wx_method("getSystemInfo", "#testhook1")
        self.assertTrue(is_called, "callback called")
        self.assertDictContainsSubset(
            {"errMsg": "getSystemInfo:ok"}, callback_args[0], "getSystemInfo"
        )
ElementTest

element页面测试用例,测试操作不同组件用例

class ElementTest(BaseCase):

    def setUp(self) -> None:
        super().setUp()
        # 页面跳转
        self.HomePage.interface_page("element")

    def __init__(self, methodName='runTest'):
        """
        初始化ElementTest类,初始化基础页、首页类
        """
        super(ElementTest, self).__init__(methodName)
        self.HomePage = home_page.HomePage(self)
        self.BasePage = base_page.BasePage(self)

    def test_move(self):
        """
        movable-view 容器拖拽滑动
        """
        ele = self.BasePage.get_element_selector("movable-view")
        # reset 重置
        ele.move_to(0, 0)  # 把movable-view复位
        time.sleep(2)
        rect = ele.rect  # 记录初始位置
        self.logger.warn(rect)
        ele.move_to(20, 100)  # 移动到坐标为20, 100的地方
        time.sleep(2)
        self.assertDictContainsSubset(
            {
                "left": 20 + rect.x,
                "top": 100 + rect.y,
            },
            ele.rect,
        )
				
	## ...
LoginTest

login页面测试用例,测试登录授权用例

class LoginTest(BaseCase):

    @classmethod
    def setUpClass(cls) -> None:
        super().setUpClass()
        try:
            # 清空授权
            cls.mini.clear_auth()
        except:
            pass

    def setUp(self) -> None:
        super().setUp()
        # 页面跳转
        self.HomePage.switch_to_tabbar("/pages/mine/mine")

    def __init__(self, methodName='runTest'):
        """
        初始化登录类,初始化基础页、首页类
        """
        super(LoginTest, self).__init__(methodName)
        self.HomePage = home_page.HomePage(self)
        self.BasePage = base_page.BasePage(self)

    def test_wechat_login(self):
        """
        微信登录
        """
        self.BasePage.get_element_xpath("/page/view/navigator[1]/button").tap()
        time.sleep(2)
        ret = self.BasePage.wait_page(router.loginPage)
        self.assertTrue(ret, "页面跳转")

        # hook 页面方法,并获取回调信息
        is_called, callback_args = self.BasePage.hook_native_method(
            method="getUserProfile",
            selector="/page/view/button",
            attr_method="allow_get_user_info")

        self.assertTrue(is_called, "callback called")
        self.assertDictContainsSubset(
            {"errMsg": "getUserProfile:ok"}, callback_args[0], "授权用户信息")
			
	## ...
NativeTest

native页面测试用例,测试处理原生控件用例

class NativeTest(BaseCase):

    @classmethod
    def setUpClass(cls) -> None:
        super().setUpClass()
        try:
            # 清空授权
            cls.mini.clear_auth()
        except:
            pass

    def setUp(self) -> None:
        super().setUp()
        # 页面跳转
        self.HomePage.interface_page("native")

    def __init__(self, methodName='runTest'):
        """
        初始化NativeTest类,初始化基础页、首页类
        """
        super(NativeTest, self).__init__(methodName)
        self.HomePage = home_page.HomePage(self)
        self.BasePage = base_page.BasePage(self)


    def test_01_show_modal(self):
        """
        showModal弹框授权
        :return:
        """
        is_called, callback_args = self.BasePage.hook_native_method(
            method="showModal",
            selector="#testModal",
            attr_method="handle_modal")

        self.assertTrue(is_called, "callback called")
        # 小程序API showModal方法回调信息断言
        self.assertDictContainsSubset(
            {"errMsg": "showModal:ok"}, callback_args[0]
        )
		
	## ...	
PageTest

page页面测试用例,测试页面元素定位用例

class PageTest(BaseCase):

    def setUp(self) -> None:
        super().setUp()
        # 页面跳转
        self.HomePage.interface_page("page")

    def __init__(self, methodName='runTest'):
        """
        初始化PageTest类,初始化基础页、首页类
        """
        super(PageTest, self).__init__(methodName)
        self.HomePage = home_page.HomePage(self)
        self.BasePage = base_page.BasePage(self)

    def test_custom_element(self):
        """
        自定义组件定位
        """
        ele = self.BasePage.get_element_custom("mytest>>>test2>>>text")
        self.assertEqual("this is test2", ele.inner_text, "元素定位")
		
	## ...		

config.json配置

{
  "project_path":"D:\\Program Files\\workspace\\miniApplet\\miniprogram-demo",
  "dev_tool_path":"D:\\download\\devtools\\微信web开发者工具\\cli.bat",
  "platform": "ide",
  "outputs": "outputs"
}

测试计划suit.json配置

配置需要执行的内容和顺序,以及所在的包。

pkg_list 字段说明要执行用例的内容和顺序, pkg_list 是一个数组,每个数组元素是一个匹配规则,会根据 pkg 去匹配包名,找到测试类,然后再根据 case_list 里面的规则去查找测试类的测试用例。可以根据需要编写匹配的粒度。注意匹配规则不是正则表达式,而是通配符文章来源地址https://www.toymoban.com/news/detail-726966.html

{
  "pkg_list": [
    {
      "case_list": [
        "test_*"
      ],
      "pkg": "test.*_test"
    }
  ]
}

运行

// 按照suite.json测试计划执行,输出报告
minitest -c config.json -s suite.json -g       
// 执行page_test中的测试用例
minitest -c config.json -m test.page_test -g 
// 执行page_test中的测试用例test_custom_element用例
minitest -c config.json -m test.page_test --case test_custom_element  

需要帮助

到了这里,关于微信小程序自动化测试框架 Minium——PO模式测试用例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序UI自动化测试实践:Minium+PageObject

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

    2024年04月09日
    浏览(39)
  • 教你如何使用自定义测试(Minium)进行微信小程序自动化测试

    目录 前言: 一、 编写用例 基本操作 处理小程序API 处理小程序原生控件 数据驱动 二、 执行用例 本地执行 云测服务测试 三、 最佳实践 四、总结 前言: 微信小程序自动化测试是保障小程序质量的重要手段,Minium是一个可为微信小程序编写自定义测试的自动化测试框架。它

    2024年02月09日
    浏览(44)
  • minium-小程序自动化测试框架

    提起 UI 自动化测试,web 端常用 Selenium,手机端常用 Appium,那么很火的微信小程序可以用什么工具来进行自动化测试?本篇将介绍一款专门用于微信小程序的自动化测试工具 - minium。 简介 minium 是为小程序专门开发的自动化框架, 提供了 Python 和 JavaScript 版本。使用 minium 可

    2024年02月22日
    浏览(30)
  • 腾讯出品小程序自动化测试框架【Minium】系列(七)测试框架的设计和开发

    整个框架的开发及调通是在3月27日晚上22点完成,如下: 这篇文章真的是拖了太久了,久到我居然把代码部分完成后,彻底给忘了,这记性,真的是年纪大了! 1、框架搭建设计要素 日志测试步骤 报告失败截图 配置文件数据源设计 公共函数API封装 测试数据参数化、解耦 测

    2023年04月08日
    浏览(31)
  • 微信小程序的自动化测试框架

    微信发布了小程序的自动化测试框架Minium,提供了多种运行验证方式,其特点: 支持一套脚本,iOS Android 模拟器,三端运行 提供丰富的页面跳转方式,看不到也能去得到 可以获取和设置小程序页面数据,让测试不止点点点 可以直接触发小程序元素绑定事件 支持往 AppSerive

    2024年02月04日
    浏览(35)
  • 微信小程序自动化测试实战教程,框架源码应有尽有

    目录 1. 微信小程序自动化测试介绍 2. 搭建微信小程序自动化测试框架 步骤1:选择测试工具 步骤2:搭建测试环境 步骤3:编写测试脚本 步骤4:执行测试 3. 实现微信小程序自动化测试的关键技术 技术1:微信小程序自动化测试工具 技术2:测试脚本的编写 技术3:测试环境的

    2024年02月14日
    浏览(36)
  • 微信小程序自动化测试——微信小程序云测服务!

    MiniTest 微信小程序云测服务是一套由微信测试团队自主研发,联合WeTest云真机能力,共同推出的微信小程序自动化测试服务。 服务基于云真机,支持开发者简单快捷地实现小程序智能化Monkey测试,录制回放,自定义测试和性能分析等能力,并提供详细的测试结果及性能数据,

    2024年04月15日
    浏览(41)
  • 【APP自动化测试必知必会】Appium之微信小程序自动化测试

    H5 是指第 5 代 HTML ,也指用 H5 语言制作的一切数字产品。 所谓 HTML 是“超文本标记语言”的英文缩写。我们上网所看到网页,多数都是由 HTML 写成的。 “超文本”是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。而“标记”指的是 这些超文本必须由包含属性

    2024年02月09日
    浏览(85)
  • 【接口测试】微信小程序接口自动化的实现方案

    前几天看到有人问微信小程序怎么进行接口自动化,所以想把自己如何进行微信小程序接口自动化的方法分享下。 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html这是微信小程序的登陆流程,小程序登陆需要在小程序内部调用 wx.login() 的方法拿到 code,然后去请

    2024年02月09日
    浏览(33)
  • 微信小程序自动化测试最佳实践(附 Python 源码)

    小程序运行环境 微信小程序技术架构 使用 Chrome 调试小程序 小程序的性能测试 微信小程序的自动化测试​编辑 源码-微信小程序自动化测试 Python 版代码示例 小程序自动化测试需要跨过的几个坎 写在最后 随着微信小程序的功能和生态日益完善,很多公司的产品业务形态逐渐

    2024年02月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包