专栏文章 小程序云测服务进阶使用—自定义测试之文件数据读取

微信小程序云测服务 · 2023年06月16日 · 最后由 tangoliver 回复于 2023年06月19日 · 8335 次阅读

背景介绍

小程序云测服务 支持用户可以使用 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 中给出了读取存储文件路径关键代码,思路就是:

  1. 先获取当前环境下,base_path.py 的绝对路径,如 /home/runtest/cases/bases/base_path.py
  2. 然后根据 base_path.py 的绝对路径,获取项目根路径,即返回上两级,如 /home/runtest/cases/
  3. 然后获取要读取的文件的相对路径(相对于项目根目录的路径)。例如我们要读 data 下的 1.csv,它相当于项目根目录下的相对路径是 /bases/data/1.csv
  4. 最后把项目根路径,与要读取文件的相对路径进行连接。例如连接后的路径为 /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 小助手反馈

共收到 1 条回复 时间 点赞

感谢分享,已阅读,找时间试试

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册