腾讯出品小程序自动化测试框架【Minium】系列(四)API详解(上)
写在前面
不知道是不是因为之前出过书的原因,在写教程之类的文章,会潜意识有自带目录和章节的感觉在里面,有点说不出的感觉吧。
上篇文章我们介绍了关于元素定位的使用方法,这篇文章将为大家分享关于Minium
中Minium、App
模块的API
使用。
常用API使用详解
get_system_info()
获取系统信息
shutdown()
测试结束时调用, 停止 微信开发者IDE 以及 minium, 并回收资源。一般供测试框架调用
screen_shot()
截图
ide上仅能截取到wxml页面的内容,Modal/Actionsheet/授权弹窗等无法截取
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
save_path | str | Not None | 截图保存路径 |
format | str | raw | 截图数据返回格式,raw 或者 pillow |
示例代码如下:
def test_screen_shot(self):
"""
截图操作
:return:
"""
output_path = os.path.join(os.path.dirname(__file__), "outputs/test_screen_shot.png")
print(output_path)
if not os.path.isdir(os.path.dirname(output_path)):
os.mkdir(os.path.dirname(output_path))
if os.path.isfile(output_path):
os.remove(output_path)
ret = self.app.screen_shot(output_path) # 截图并存到`output_path`文件夹中
self.assertTrue(os.path.isfile(output_path))
evaluate()
向 app Service 层注入代码并执行
真机调试2.0下, 注入的代码只支持es5的语法
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
app_function | str | Not None | 代码字符串 |
args | list | Not None | 参数 |
sync | bool | False | 是否同步执行 |
Returns:
- sync == True: dict(result={"result": 函数返回值})
- sync == False: str(消息ID)。配合
get_async_response
用获取返回值
示例代码如下:
import minium
# sync == True
@minium.ddt_class
class TestApp(minium.MiniTest):
@minium.ddt_case([], ["1", "2"])
def test_evaluate_sync(self, args):
result = self.app.evaluate(
"function(){args=arguments;return 'test evaluate: '.concat(Array.from(args));}", args, sync=True
)
self.assertEqual(
result.get("result", {}).get("result"), "test evaluate: {}".format(",".join(args))
)
get_async_response()
获取
evaluate
方法异步调用的结果
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
msg_id | str | Not None | evaluate 返回的消息ID |
timeout | int | None | 等待超时时间,None: 立刻返回 |
示例代码如下:
import minium
# sync == False
@minium.ddt_class
class TestApp(minium.MiniTest):
@minium.ddt_case([], ["1", "2"])
def test_evaluate_async(self, args):
msg_id = self.app.evaluate(
"function(){args=arguments;return 'test evaluate: '.concat(Array.from(args));}", args, sync=False
)
# 你可以做一些其他操作后, 再通过get_async_response方法获取前面注入代码的运行结果
result = self.app.get_async_response(msg_id, 5)
self.assertEqual(
result.get("result", {}).get("result"), "test evaluate: {}".format(",".join(args))
)
get_all_pages_path()
获取所有已配置的页面路径
Returns:
list
示例代码如下:
def test_get_all_pages_path(self):
"""
获取所有已配置的页面路径
:return:list
"""
all_pages_path = self.app.get_all_pages_path()
self.assertListEqual(
['page/component/index', 'page/API/index', 'page/cloud/index', 'page/extend/index', 'page/animation/index',
'packageComponent/pages/view/view/view', 'packageComponent/pages/view/scroll-view/scroll-view',
'packageComponent/pages/view/swiper/swiper', 'packageComponent/pages/view/movable-view/movable-view',
'packageComponent/pages/view/cover-view/cover-view', 'packageComponent/pages/content/text/text',
'packageComponent/pages/content/icon/icon', 'packageComponent/pages/content/progress/progress',
'packageComponent/pages/content/rich-text/rich-text', 'packageComponent/pages/form/button/button',
'packageComponent/pages/form/checkbox/checkbox', 'packageComponent/pages/form/form/form',
'packageComponent/pages/form/input/input', 'packageComponent/pages/form/label/label',
'packageComponent/pages/form/picker/picker', 'packageComponent/pages/form/picker-view/picker-view',
'packageComponent/pages/form/radio/radio', 'packageComponent/pages/form/slider/slider',
'packageComponent/pages/form/switch/switch', 'packageComponent/pages/form/textarea/textarea',
'packageComponent/pages/form/editor/editor', 'packageComponent/pages/nav/navigator/navigator',
'packageComponent/pages/nav/navigator/navigate', 'packageComponent/pages/nav/navigator/redirect',
'packageComponent/pages/media/image/image', 'packageComponent/pages/media/video/video',
'packageComponent/pages/media/camera/camera', 'packageComponent/pages/media/live-pusher/live-pusher',
'packageComponent/pages/media/live-player/live-player', 'packageComponent/pages/map/map/map',
'packageComponent/pages/canvas/canvas-2d/canvas-2d', 'packageComponent/pages/canvas/webgl/webgl',
'packageComponent/pages/open/ad/ad', 'packageComponent/pages/open/open-data/open-data',
'packageComponent/pages/open/web-view/web-view',
'packageComponent/pages/obstacle-free/aria-component/aria-component',
'packageComponent/pages/doc-web-view/doc-web-view', 'packageAPI/pages/api/login/login',
'packageAPI/pages/api/get-user-info/get-user-info', 'packageAPI/pages/api/request-payment/request-payment',
'packageAPI/pages/api/jump/jump', 'packageAPI/pages/api/share/share',
'packageAPI/pages/api/share-button/share-button', 'packageAPI/pages/api/custom-message/custom-message',
'packageAPI/pages/api/subscribe-message/subscribe-message',
'packageAPI/pages/api/choose-address/choose-address',
'packageAPI/pages/api/choose-invoice-title/choose-invoice-title',
'packageAPI/pages/api/soter-authentication/soter-authentication', 'packageAPI/pages/api/setting/setting',
'packageAPI/pages/ar/visionkit-basic/visionkit-basic',
'packageAPI/pages/ar/visionkit-basic-v2/visionkit-basic-v2', 'packageAPI/pages/ar/plane-ar/plane-ar',
'packageAPI/pages/ar/plane-ar-v2/plane-ar-v2', 'packageAPI/pages/ar/plane-ar-3dof/plane-ar-3dof',
'packageAPI/pages/ar/2dmarker-ar/2dmarker-ar', 'packageAPI/pages/ar/3dmarker-ar/3dmarker-ar',
'packageAPI/pages/ar/osd-ar/osd-ar', 'packageAPI/pages/ar/face-detect/face-detect',
'packageAPI/pages/ar/body-detect/body-detect', 'packageAPI/pages/ar/hand-detect/hand-detect',
'packageAPI/pages/ar/ocr-detect/ocr-detect', 'packageAPI/pages/ar/photo-ocr-detect/photo-ocr-detect',
'packageAPI/pages/ar/photo-hand-detect/photo-hand-detect',
'packageAPI/pages/ar/photo-body-detect/photo-body-detect',
'packageAPI/pages/ar/photo-face-detect/photo-face-detect',
'packageAPI/pages/page/set-navigation-bar-title/set-navigation-bar-title',
'packageAPI/pages/page/navigation-bar-loading/navigation-bar-loading',
'packageAPI/pages/page/navigator/navigator', 'packageAPI/pages/page/pull-down-refresh/pull-down-refresh',
'packageAPI/pages/page/animation/animation', 'packageAPI/pages/page/action-sheet/action-sheet',
'packageAPI/pages/page/modal/modal', 'packageAPI/pages/page/toast/toast',
'packageAPI/pages/page/canvas/canvas', 'packageAPI/pages/page/get-wxml-node-info/get-wxml-node-info',
'packageAPI/pages/page/page-scroll/page-scroll',
'packageAPI/pages/page/intersection-observer/intersection-observer',
'packageAPI/pages/device/clipboard-data/clipboard-data', 'packageAPI/pages/device/bluetooth/bluetooth',
'packageAPI/pages/device/bluetooth/slave/slave',
'packageAPI/pages/device/screen-brightness/screen-brightness', 'packageAPI/pages/device/vibrate/vibrate',
'packageAPI/pages/device/add-contact/add-contact', 'packageAPI/pages/device/wifi/wifi',
'packageAPI/pages/device/get-network-type/get-network-type',
'packageAPI/pages/device/on-network-status-change/on-network-status-change',
'packageAPI/pages/device/get-system-info/get-system-info',
'packageAPI/pages/device/on-compass-change/on-compass-change',
'packageAPI/pages/device/make-phone-call/make-phone-call', 'packageAPI/pages/device/scan-code/scan-code',
'packageAPI/pages/device/on-accelerometer-change/on-accelerometer-change',
'packageAPI/pages/device/capture-screen/capture-screen', 'packageAPI/pages/device/ibeacon/ibeacon',
'packageAPI/pages/device/get-battery-info/get-battery-info', 'packageAPI/pages/media/image/image',
'packageAPI/pages/media/voice/voice', 'packageAPI/pages/media/file/file',
'packageAPI/pages/media/load-font-face/load-font-face',
'packageAPI/pages/media/background-audio/background-audio', 'packageAPI/pages/media/video/video',
'packageAPI/pages/media/audio/audio', 'packageAPI/pages/media/media-container/media-container',
'packageAPI/pages/location/get-location/get-location',
'packageAPI/pages/location/open-location/open-location',
'packageAPI/pages/location/choose-location/choose-location', 'packageAPI/pages/network/request/request',
'packageAPI/pages/network/web-socket/web-socket', 'packageAPI/pages/network/upload-file/upload-file',
'packageAPI/pages/network/download-file/download-file', 'packageAPI/pages/network/mdns/mdns',
'packageAPI/pages/network/udp-socket/udp-socket', 'packageAPI/pages/storage/storage/storage',
'packageAPI/pages/storage/get-background-fetch-data/get-background-fetch-data',
'packageAPI/pages/storage/get-background-prefetch-data/get-background-prefetch-data',
'packageAPI/pages/performance/get-performance/get-performance', 'packageAPI/pages/worker/worker/worker',
'packageAPI/pages/framework/two-way-bindings/two-way-bindings', 'packageAPI/pages/framework/wxs/wxs',
'packageAPI/pages/framework/resizable/resizable', 'packageAPI/pages/framework/wxs/movable',
'packageAPI/pages/framework/wxs/sidebar', 'packageAPI/pages/framework/wxs/stick-top',
'packageAPI/pages/framework/wxs/nearby', 'packageAPI/pages/ai/mobilenet/index',
'packageAPI/pages/ai/style-trans/index', 'packageCloud/pages/user/user-authentication/user-authentication',
'packageCloud/pages/database/crud/crud', 'packageCloud/pages/database/db-permission/db-permission',
'packageCloud/pages/database/server-date/server-date',
'packageCloud/pages/storage/upload-file/upload-file',
'packageCloud/pages/storage/download-file/download-file',
'packageCloud/pages/storage/get-temp-file-url/get-temp-file-url',
'packageCloud/pages/storage/delete-file/delete-file',
'packageCloud/pages/storage/cloud-file-component/cloud-file-component',
'packageCloud/pages/scf/get-wx-context/get-wx-context', 'packageCloud/pages/scf/scf-database/scf-database',
'packageCloud/pages/scf/scf-storage/scf-storage', 'packageCloud/pages/scf/scf-openapi/scf-openapi',
'packageExtend/pages/form/cell/cell', 'packageExtend/pages/form/slideview/slideview',
'packageExtend/pages/form/form/form', 'packageExtend/pages/form/uploader/uploader',
'packageExtend/pages/base/article/article', 'packageExtend/pages/base/icons/icons',
'packageExtend/pages/base/badge/badge', 'packageExtend/pages/base/flex/flex',
'packageExtend/pages/base/footer/footer', 'packageExtend/pages/base/gallery/gallery',
'packageExtend/pages/base/grid/grid', 'packageExtend/pages/base/loadmore/loadmore',
'packageExtend/pages/base/loading/loading', 'packageExtend/pages/base/panel/panel',
'packageExtend/pages/base/preview/preview', 'packageExtend/pages/operate/dialog/dialog',
'packageExtend/pages/operate/msg/msg', 'packageExtend/pages/operate/msg/msg_success',
'packageExtend/pages/operate/msg/msg_text', 'packageExtend/pages/operate/msg/msg_text_primary',
'packageExtend/pages/operate/msg/msg_fail',
'packageExtend/pages/operate/half-screen-dialog/half-screen-dialog',
'packageExtend/pages/operate/actionsheet/actionsheet', 'packageExtend/pages/operate/toptips/toptips',
'packageExtend/pages/navigation/navigation/navigation', 'packageExtend/pages/navigation/tabbar/tabbar',
'packageExtend/pages/search/searchbar/searchbar', 'packageExtend/pages/extend/emoji/emoji',
'packageExtend/pages/extend/video-swiper/video-swiper', 'packageExtend/pages/extend/index-list/index-list',
'packageExtend/pages/extend/recycle-view/recycle-view', 'packageExtend/pages/extend/sticky/sticky',
'packageExtend/pages/extend/tabs/tabs', 'packageExtend/pages/extend/vtabs/vtabs',
'packageExtend/pages/extend/barrage/barrage', 'packageExtend/pages/extend/select-text/select-text',
'packageExtend/pages/extend/wxml-to-canvas/wxml-to-canvas',
'packageExtend/pages/adapt/telescopic/telescopic', 'packageExtend/pages/adapt/linebreak/linebreak',
'packageExtend/pages/adapt/sidenavigation/sidenavigation',
'packageExtend/pages/adapt/pagination/pagination', 'packageExtend/pages/adapt/freelayout/freelayout',
'packageExtend/pages/adapt/layeredpresentation/layeredpresentation',
'packageExtend/pages/adapt/horizontalexpansion/horizontalexpansion',
'packageSkyline/pages/worklet/animation/index', 'packageSkyline/pages/worklet/gesture/index',
'packageSkyline/pages/worklet/bottom-sheet/index', 'packageSkyline/pages/share-element/list/index',
'packageSkyline/pages/share-element/card/index', 'packageSkyline/pages/half-page/scale-page/index',
'packageSkyline/pages/half-page/half-page/index', 'packageSkyline/pages/address-book/index',
'packageSkyline/pages/half-screen/index', 'packageSkyline/pages/tabs/index',
'packageSkyline/pages/album/index', 'packageSkyline/pages/preview/index',
'packageSkyline/pages/custom-route/index', 'packageSkyline/pages/custom-route/detail',
'packageSkyline/pages/scroll-view/index', 'packageXRFrame/pages/index/index',
'packageXRFrame/pages/scene-basic/index', 'packageXRFrame/pages/scene-basic-light/index',
'packageXRFrame/pages/scene-basic-animation/index', 'packageXRFrame/pages/scene-basic-particle/index',
'packageXRFrame/pages/scene-basic-touch/index', 'packageXRFrame/pages/scene-basic-visible-layer/index',
'packageXRFrame/pages/scene-basic-shadow/index', 'packageXRFrame/pages/scene-basic-video/index',
'packageXRFrame/pages/scene-basic-render-texture/index',
'packageXRFrame/pages/scene-basic-postprocessing/index',
'packageXRFrame/pages/scene-gltf-damageHelmet/index', 'packageXRFrame/pages/scene-gltf-unlit/index',
'packageXRFrame/pages/scene-gltf-animation/index', 'packageXRFrame/pages/scene-gltf-morph/index',
'packageXRFrame/pages/scene-gltf-light-loading/index', 'packageXRFrame/pages/scene-ar-basic/index',
'packageXRFrame/pages/scene-ar-2dmarker/index', 'packageXRFrame/pages/scene-ar-osdmarker/index',
'packageXRFrame/pages/scene-ar-camera/index', 'packageXRFrame/pages/scene-ar-face/index',
'packageXRFrame/pages/scene-ar-hand/index', 'packageXRFrame/pages/scene-ar-body/index',
'packageXRFrame/pages/scene-custom-logic/index', 'packageXRFrame/pages/scene-custom-render/index',
'packageXRFrame/pages/scene-scan-render/index', 'packageXRFrame/pages/scene-scan-team/index',
'packageXRFrame/pages/scene-classic-wxball/index', 'packageXRFrame/pages/scene-classic-video/index',
'packageXRFrame/pages/scene-classic-perspect/index', 'packageXRFrame/pages/scene-classic-portal/index',
'packageXRFrame/pages/scene-classic-osd/index', 'packageXRFrame/pages/scene-classic-face/index',
'packageXRFrame/pages/scene-last-record/index'],
all_pages_path,
"test ok",
)
get_current_page()
获取当前顶层页面
Returns:
- 页面对象
示例代码如下:
import minium
class AppTest(minium.MiniTest):
def test_get_current_page(self):
page = self.app.get_current_page() # 同self.app.current_page
self.assertIsNotNone(page.path)
self.assertNotEqual("", page.path)
print(page.path)
go_home()
跳转到小程序首页
示例代码如下:
def test_go_home(self):
"""
跳转到小程序首页
:return:
"""
self.page.get_element("view", inner_text="视图容器").click()
self.page.get_element("navigator", inner_text="view").click()
# 跳转到小程序首页
self.app.go_home()
navigate_to()
以导航的方式跳转到指定页面
不能跳到 tabbar 页面。支持相对路径和绝对路径, 小程序中页面栈最多十层
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | str | Not None | 页面路径 |
params | dict | None | 页面参数 |
is_wait_url_change | bool | True | 是否等待新的页面跳转 |
个人感觉就是跳转到指定页面,也可以理解为导航栏上的超链接带路径那种的
示例代码如下:
def test_navigate_to(self):
"""
跳转到指定页面
:return:
"""
pass_page = self.app.get_current_page()
self.app.navigate_to("/packageComponent/pages/view/view/view")
navigate_back()
关闭当前页面,返回上一页面
示例代码如下:
def test_navigate_to(self):
"""
返回上一页
:return:
"""
pass_page = self.app.get_current_page()
# 跳转到指定页面
self.app.navigate_to("/packageComponent/pages/view/view/view")
# 返回上一页
self.app.navigate_back()
redirect_to()
关闭当前页面,重定向到应用内的某个页面
不允许跳转到 tabbar 页面
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | str | Not None | 页面路径 |
params | dict | None | 页面参数 |
is_wait_url_change | bool | True | 是否等待新的页面跳转 |
个人感觉同navigate_to()
用法很像,各种细节感兴趣的同学可以自行尝试。
示例代码如下:
def redirect_to(self):
"""
重定向到指定页面
:return:
"""
# 重定向到指定页面
self.app.redirect_to("/packageComponent/pages/view/view/view")
relaunch()
关闭所有页面,打开到应用内的某个页面
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | str | Not None | 页面路径 |
示例代码如下:
def test_relaunch(self):
"""
关闭所有页面,打开到应用内的某个页面
:return:
"""
pass_page = self.app.get_current_page()
# 重定向到指定页面
self.app.redirect_to("/packageComponent/pages/view/view/view")
# 关闭所有页面,打开到应用内的某个页面
self.app.relaunch("/packageComponent/pages/view/movable-view/movable-view")
switch_tab()
跳转到 tabBar 页面
会关闭其他所有非tabBar
页面
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | str | Not None | 需要跳转的 tabBar 页面的路径(需在 app.json 的 tabBar 字段定义的页面),路径后不能带参数 |
is_click | bool | False | 切换tab的时候触发一次onTabItemTap |
示例代码如下:
def switch_tab(self):
"""
跳转到 tabBar 页面
:return:
"""
pass_page = self.app.get_current_page()
print(pass_page)
# 重定向到指定页面
self.app.redirect_to("/packageComponent/pages/view/view/view")
# 关闭所有页面,打开到应用内的某个页面
self.app.relaunch("/packageComponent/pages/view/movable-view/movable-view")
# 跳转到 tabBar 页面
self.app.switch_tab("/page/API/index")
什么是tabbar页面?
举个栗子,比如我们小程序的底部有图标加文字的几个按钮,每个按钮对应一个页面,而整个小程序中有很多页面,小程序底部图标加文字对应的几个页面是tabbar页面,这个在app.json中有设置。
eg:在app.json中设置对应的tabbar页面
"tabBar": {
"color": "#333",
"selectedColor": "#d43c33",
"backgroundColor": "#fff",
"position": "bottom",
"list": [
{
"pagePath": "pages/index/index",
"text": "主页",
"iconPath": "/static/images/tabs/tab-home.png",
"selectedIconPath": "/static/images/tabs/tab-home-current.png"
},
{
"pagePath": "pages/video/video",
"text": "视频",
"iconPath": "/static/images/tabs/select.png",
"selectedIconPath": "/static/images/tabs/selected.png"
},
{
"pagePath": "pages/personal/personal",
"text": "个人中心",
"iconPath": "/static/images/tabs/tab-my.png",
"selectedIconPath": "/static/images/tabs/tab-my-current.png"
}
]
}
get_perf_time()
查询小程序的性能指标,跟stop_get_perf_time配对使用
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
entry_types | list | Not None | 可选项为['render', 'script', 'navigation', 'loadPackage']中的1个或多个 |
stop_get_perf_time()
结束查询,跟get_perf_time配对使用
示例代码如下:
def test_get_perf_time(self):
"""
查询小程序的性能指标
:return:
"""
self.app.get_perf_time(entry_types=["navigation"])
self.app.navigate_to("/packageComponent/pages/view/view/view")
self.app.redirect_to("/packageComponent/pages/view/movable-view/movable-view")
perf_data = self.app.stop_get_perf_time()
print(perf_data)
可以看到一些路径跳转的耗时,结果如下:
[{
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063419,
'duration': 387,
'navigationType': 'navigateTo',
'path': 'packageComponent/pages/view/view/view',
'pageId': 53,
'referrerPath': 'page/component/index',
'referrerPageId': 52,
'navigationStart': 1674803063575
}, {
'entryType': 'render',
'name': 'firstRender',
'startTime': 1674803063575,
'duration': 74,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53,
'viewLayerReadyTime': 1674803063618,
'initDataSendTime': 1674803063603,
'initDataRecvTime': 1674803063619,
'viewLayerRenderStartTime': 1674803063619,
'viewLayerRenderEndTime': 1674803063646
}, {
'entryType': 'render',
'name': 'firstPaint',
'startTime': 1674803063583,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'render',
'name': 'firstContentfulPaint',
'startTime': 1674803063667,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'render',
'name': 'largestContentfulPaint',
'startTime': 1674803063667,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063419,
'duration': 387,
'navigationType': 'navigateTo',
'path': 'packageComponent/pages/view/view/view',
'pageId': 53,
'referrerPath': 'page/component/index',
'referrerPageId': 52,
'navigationStart': 1674803063575
}, {
'entryType': 'render',
'name': 'firstRender',
'startTime': 1674803063575,
'duration': 74,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53,
'viewLayerReadyTime': 1674803063618,
'initDataSendTime': 1674803063603,
'initDataRecvTime': 1674803063619,
'viewLayerRenderStartTime': 1674803063619,
'viewLayerRenderEndTime': 1674803063646
}, {
'entryType': 'render',
'name': 'firstPaint',
'startTime': 1674803063583,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'render',
'name': 'firstContentfulPaint',
'startTime': 1674803063667,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'render',
'name': 'largestContentfulPaint',
'startTime': 1674803063667,
'path': 'packageComponent/pages/view/view/view',
'pageId': 53
}, {
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063419,
'duration': 387,
'navigationType': 'navigateTo',
'path': 'packageComponent/pages/view/view/view',
'pageId': 53,
'referrerPath': 'page/component/index',
'referrerPageId': 52,
'navigationStart': 1674803063575
}, {
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063874,
'duration': 680,
'navigationType': 'redirectTo',
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54,
'referrerPath': 'packageComponent/pages/view/view/view',
'referrerPageId': 53,
'navigationStart': 1674803064353
}, {
'entryType': 'render',
'name': 'firstRender',
'startTime': 1674803064353,
'duration': 71,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54,
'viewLayerReadyTime': 1674803064393,
'initDataSendTime': 1674803064367,
'initDataRecvTime': 1674803064375,
'viewLayerRenderStartTime': 1674803064394,
'viewLayerRenderEndTime': 1674803064421
}, {
'entryType': 'render',
'name': 'firstPaint',
'startTime': 1674803064358,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'render',
'name': 'firstContentfulPaint',
'startTime': 1674803064425,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'render',
'name': 'largestContentfulPaint',
'startTime': 1674803064425,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063874,
'duration': 680,
'navigationType': 'redirectTo',
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54,
'referrerPath': 'packageComponent/pages/view/view/view',
'referrerPageId': 53,
'navigationStart': 1674803064353
}, {
'entryType': 'render',
'name': 'firstRender',
'startTime': 1674803064353,
'duration': 71,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54,
'viewLayerReadyTime': 1674803064393,
'initDataSendTime': 1674803064367,
'initDataRecvTime': 1674803064375,
'viewLayerRenderStartTime': 1674803064394,
'viewLayerRenderEndTime': 1674803064421
}, {
'entryType': 'render',
'name': 'firstPaint',
'startTime': 1674803064358,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'render',
'name': 'firstContentfulPaint',
'startTime': 1674803064425,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'render',
'name': 'largestContentfulPaint',
'startTime': 1674803064425,
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54
}, {
'entryType': 'navigation',
'name': 'route',
'startTime': 1674803063874,
'duration': 680,
'navigationType': 'redirectTo',
'path': 'packageComponent/pages/view/movable-view/movable-view',
'pageId': 54,
'referrerPath': 'packageComponent/pages/view/view/view',
'referrerPageId': 53,
'navigationStart': 1674803064353
}]
wait_for_page()
等待页面跳转成功
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
page_path | str | Not None | 需要等待的页面路径, 需要绝对路径, 如/pages/index |
示例代码如下:
def test_wait_for_page(self):
"""
等待页面跳转成功
:return:布尔类型
"""
self.page.get_element("view",inner_text='表单组件').click()
el = self.app.current_page.get_element('navigator',inner_text='button')
el.tap()
current_page=self.app.get_current_page()
time.sleep(3)
print(current_page)
ret = self.app.wait_for_page("/packageComponent/pages/form/button/button")
print(ret)
self.assertTrue(ret, "wait success")
self.assertEqual(self.app.current_page.path, "/packageComponent/pages/form/button/button", "path ok")
wait_util()
指定时间内, 剩余没有完成的异步请求数 <= {cnt}个, 此时认为页面异步加载完成
Parameters:
名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
cnt | int | Not None | 剩余的异步请求个数 |
max_timeout | int | 10 | 最大等待时间 |
示例代码如下:
def test_wait_util(self):
"""
确定指定时间内, 异步请求是否完成的
:return:布尔类型
"""
self.page.get_element("view",inner_text='表单组件').click()
el = self.app.current_page.get_element('navigator',inner_text='button')
el.tap()
ret = self.app.wait_util(0, 5) # 5s内, 页面没有任何未完成的异步请求
self.assertTrue(ret, "wait success")
写在最后
关于Minium
接口中minium、App
部分的APi
已经介绍完毕,这两个模块中部分Api没做分享感兴趣的同学可以到官方文章自行查看。
仔细看了下API
部分还真不少,下篇文章会为大家分享Page
、Element
这两个模块的Api
,感兴趣的同学可以蹲一下,建议收藏,也请星标我的公号(软件测试君),并帮忙转发给你更多的人,我需要你的支持,谢谢!
腾讯出品小程序自动化测试框架【Minium】系列(四)API详解(上)的更多相关文章
- Java生鲜电商平台-APP/小程序接口传输常见的加密算法及详解
Java生鲜电商平台-APP/小程序接口传输常见的加密算法及详解 说明:Java生鲜电商平台-APP/小程序接口传输常见的加密算法及详解,加密算法,是现在每个软件项目里必须用到的内容. 广泛应用在包括 ...
- 小程序学习笔记三:页面文件详解之视图层WXML、WXS、WXSS文件
视图层:Pages主要有 wxml页面文件和模板文件.wxs脚本文件.wxss样式文件:component是抽取出来的业务单元,同样拥有wxml页面文件和模板文件.wxs脚本文件.wxss样式文件 ...
- 微信小程序wx:key以及wx:key=" *this"详解:
今天写微信小程序无意中看到控制台给出了这样一行提示: 求解百度才知道,给大家分享一下: 1.wx:for定义 官方文档:在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲 ...
- 小程序学习笔记二:页面文件详解之 .json文件
页面配置文件—— pageName.json 每一个小程序页面可以使用.json文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项. 页面的 ...
- 「微信小程序」PHP异步进程async-helper实例详解
PHP异步进程async-helper实例详解 PHP 的异步进程助手,借助于 AMQP 实现异步执行 PHP 的方法,将一些很耗时.追求高可用.需要重试机制的操作放到异步进程中去执行,将你的 HTT ...
- 十一、微信小程序-var、let、const用法详解
let命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a // ...
- 微信小程序获取当前地址以及选择地址详解 地点标记
首先定义事件: bindtap='getLocation' <view class='store-bot' bindtap='getLocation'> <view class='c ...
- 自动化测试框架selenium+java+TestNG——TestNG详解
TestNG按顺序执行case package com.testngDemo; import org.testng.annotations.AfterClass; import org.testng. ...
- 微信小程序 导航 4种页面跳转 详解
1.wx.navigateTo 保留当前页面,跳转到应用内的某个页面,目前页面路径最多只能十层. 参数:url(可携带参数) .success .fail .complete 可用wxml代替: ...
- Ansible 小手册系列 四(详解配置文件)
[root@host-172-20-6-120 ansible]# ansible --version ansible 2.2.0.0 config file = /etc/ansible/ansib ...
随机推荐
- 3.CBV视图之csrf补充
CBV使用csrf装饰器关闭/开启 csrf验证,直接在函数上加装饰器无效的 #方法1 from django.views import View from django.views.decorato ...
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...
- go基础语法50问,来看看你的go基础合格了吗?
目录 1.使用值为 nil 的 slice.map会发生啥 2.访问 map 中的 key,需要注意啥 3.string 类型的值可以修改吗 4.switch 中如何强制执行下一个 case 代码块 ...
- Python基础之模块:1、模块的导入和使用
目录 一.模块 1.简介 2.模块的表现形式 二.模块的分类 1.自定义模块 2.内置模块 3.第三方模块 三.导入模块的句式 学前须知: 1.import句式 2.from...import...句 ...
- 论文笔记 - Noisy Channel Language Model Prompting for Few-Shot Text Classification
Direct && Noise Channel 进一步把语言模型推理的模式分为了: 直推模式(Direct): 噪声通道模式(Noise channel). 直观来看: Direct ...
- TASK 总结
信相连知识 1.python操作EXCEL 库:xlwings. 基本操作:打开.读写.关闭. 2.python操作问题库 库:JIRA 基本操作:提交问题 3.网页信息在网址不变时的获取 库:req ...
- js高级之函数高级部分
基于尚硅谷的尚硅谷JavaScript高级教程提供笔记撰写,加入一些个人理解 github源码 博客下载 原型与原型链 prototype : 显式原型属性,它默认指向一个Object空对象(即称为: ...
- C#使用GDI+同时绘制图像和ROI在picturebox上
Bitmap bmp; /// <summary> /// 绘制图像 /// </summary> /// <param name="g">Gr ...
- Java开发学习(四十四)----MyBatisPlus查询语句之查询条件
1.查询条件 前面我们只使用了lt()和gt(),除了这两个方法外,MybatisPlus还封装了很多条件对应的方法. MybatisPlus的查询条件有很多: 范围匹配(> . = .betw ...
- 4.10:Spark之wordcount
〇.概述 1.拓扑结构 2.目标 使用spark完成计数实验 一.启动环境 二.新建数据文件 三.查看文件内容 四.启动spark服务 五.编写代码 复制以下代码到shell中(复制后在终端右键-&g ...