微信小程序自动化测试框架 小程序云测服务进阶使用—自定义测试之文件数据读取
背景介绍
小程序云测服务 支持用户可以使用 Minium 框架编写测试用例
在用户编写用例时,经常遇到的一个场景就是文件数据读取,例如:
- 将用例相关参数放在 csv 文件中,然后再用例里面去读取对应的配置,执行不同的逻辑
- 使用 数据驱动测试 时,将数据驱动源从 YAML、CSV 等文件传入
执行文件数据读取相关用例时,获取文件路径是关键
很多用户会发现在本地执行 Minium 用例时可以执行成功,在云测执行就会报 No such file or directory
文件找不到这样的错误
产生这样报错的原因有很多种,比如:
- 用例直接使用绝对路径去定位,如
D:\minium\xxx
, 而在云测执行时,这样的路径显然是不存在的 - 用例使用相对路径定位,用户本地执行用例时,使用 PyCharm 等工具执行。PyCharm 可能 配置了环境变量,或者将当前执行路径加入环境变量,所以本地执行可以找到文件并执行成功。当在云测服务执行时,是在用例的根目录执行的,此时可能无法找到文件地址
解决方案
为了帮助用户解决在用例中文件路径找不到的问题,我们给出了可以在本地和云测同时跑通的 示例代码 ,目录结构如下所示。其中 bases/base_path.py
给出了读取存储文件路径关键代码,test/first_test.py
给出了具体 case 使用的示例
─ddt-project
│ │ config.json
│ │
│ ├─bases
│ │ │ base_path.py //处理文件路径
│ │ │ __init__.py
│ │ │
│ │ └─data //存储文件数据
│ │ 1.csv
│ │ 3.yml
│ │ 4.xlsx
│ │
│ └─test //测试用例
│ first_test.py
│ __init__.py
1. 获取文件路径
bases/base_path.py 中给出了读取存储文件路径关键代码,思路就是:
- 先获取当前环境下,base_path.py 的绝对路径,如
/home/runtest/cases/bases/base_path.py
- 然后根据 base_path.py 的绝对路径,获取项目根路径,即返回上两级,如
/home/runtest/cases/
- 然后获取要读取的文件的相对路径(相对于项目根目录的路径)。例如我们要读 data 下的 1.csv,它相当于项目根目录下的相对路径是
/bases/data/1.csv
- 最后把项目根路径,与要读取文件的相对路径进行连接。例如连接后的路径为
/home/runtest/cases/bases/data/1.csv
这样无论在什么环境下,最终读取的都是当前环境的绝对路径,保证文件能够读取成功
关键函数如下所示:
def get_path(self):
# 获取当前文件绝对路径
file_Path = Path(f'{os.path.abspath(__file__)}')
# 获取项目根目录文件目录(用例文件的上两级)
curPath = os.path.abspath(os.path.dirname(os.path.dirname(file_Path)))
# 路径连接,获取csv/ymal/excel文件路径
filePath = Path(f'{os.path.join(curPath, self.path)}')
获取到文件路径后,可以开始读取文件了,读取 csv 文件的示例代码如下:
def read_file(self):
# 获取文件路径
filePath = self.get_path()
with open(filePath, encoding="UTF8") as f:
reader = csv.reader(f) # 创建 读取器
ls = []
for row in reader: # 循环得到后面的所有数据
ls.append(row)
return ls
2. 在测试用例中使用
在前面提到,很多用户会在测试用例中使用 @minium.ddt_case()
修饰器,进行 DDT 数据驱动测试。这时可以从文件中读取数据来驱动 Case
例如,读取 CSV 文件数据进行测试,CSV 文件数据如下:
0,3,bindPickerChange
1,9:30,bindTimeChange
2,2022-10-1,bindDateChange
用例代码
@minium.ddt_unpack
@minium.ddt_case(*read_file('bases/data/1.csv')) # 存储文件的相对路径
def test_pick(self, index, value, method):
"""
测试选择器
不会进行真正的滚动选择操作, 通过派发change事件来模拟选择完成操作
"""
self.logger.warn(f'{index}—{value}—{method}')
index = int(index)
self.app.redirect_to("/pages/testelement/testelement")
self.page.wait_for(3)
callback = Callback()
els = self.page.get_elements("picker")
self.app.hook_current_page_method(method, callback.callback)
els[index].click() # 阻止picker弹起
els[index].pick(value) # 用trigger模拟pick完成的动作
self.assertTrue(callback.wait_called(timeout=10), "callback called")
self.assertEqual(callback.get_callback_result()["detail"]["value"], value, "pick ok")
a. 本地跑测
执行 minitest
命令,例如 minitest -m test.first_test -c config.json -g
。具体可参考 简单例子
本地跑测日志 如下
DEBUG 2023-06-14 11:23:05,905 connection.py _safely_send 417 SEND > {"id":"6edf07f7-21de-4c7f-8e21-d551de4fd35c","method":"Element.triggerEvent","params":{"type":"change","detail":{"value":"3"},"elementId":"6a8bcf97-0de5-4708-a994-2afb05be4fae","pageId":12}}
DEBUG 2023-06-14 11:23:05,967 connection.py _on_message 652 RECV < {"method":"App.bindingCalled","params":{"name":"page_hook_bindPickerChange_super_callback","args":[{"type":"change","timeStamp":3929,"target":{"id":"","offsetLeft":0,"offsetTop":1178,"dataset":{}},"currentTarget":{"id":"","offsetLeft":0,"offsetTop":1178,"dataset":{}},"mark":{},"detail":{"value":"3"},"mut":false,"_userTap":false}]}
b. 云测跑测
云测跑测可参考文档,上传测试用例 ,自定义 Minium 测试
云测测试报告示例截图
需要帮助
如果在微信小程序自动化测试过程中遇到任何问题,欢迎在 微信小程序云测服务 专区发帖反馈
也可以微信扫描二维码加入云测官方企业微信群,联系 MiniTest 小助手反馈