前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pytest + yaml 框架 -12.支持执行sql 和 断言sql

pytest + yaml 框架 -12.支持执行sql 和 断言sql

作者头像
上海-悠悠
发布2023-01-03 14:04:19
1.4K0
发布2023-01-03 14:04:19
举报

前言

当我们在测试环境写好自动化的代码,领导说你把代码部署到联调环境再测一测,这时候去改用例里面的配置是很痛苦的。 所以我们在设计自动化用例的时候,就先要想到多环境的配置与切换。

多环境配置

如果需用到多套环境 test/uat 等,那么应该在用例的根目录(pytest.ini 同级文件)创建一个config.py 文件 pip 安装插件

代码语言:javascript
复制
pip install pytest-yaml-yoyo

多套环境切换功能在 v1.0.10 版本上实现

代码语言:javascript
复制
class Config:
    """多套环境的公共配置"""
    version = "v1.0"

class TestConfig(Config):
    """测试环境"""
    BASE_URL = 'http://192.168.1.1:8000'
    MYSQL_HOST = "192.168.1.1"
    MYSQL_USER = "root"
    MYSQL_PASSWORD = "123456"
    MYSQL_PORT = 3306
    MYSQL_DATABASE = "xxx"   # 连接数据的库名

class UatConfig(Config):
    """联调环境"""
    BASE_URL = 'http://192.168.1.3:8080'
    MYSQL_HOST = "http://192.168.1.3"
    MYSQL_USER = "root"
    MYSQL_PASSWORD = "654321"
    MYSQL_PORT = 3306
    MYSQL_DATABASE = "xxx"  # 连接数据的库名

# 环境关系映射,方便切换多环境配置
env = {
    "test": TestConfig,
    "uat": UatConfig
}

按以上的配置格式,配置不同的环境,最后做一个环境名称和配置的映射关系,必须是 env 命名,格式如下

代码语言:javascript
复制
env = {
    "test": TestConfig,
    "uat": UatConfig
}

那么在执行用例的时候,可以选择执行test 环境还是uat 环境,有 2 种方式可以配置待执行的环境

方法一: 在pytest.ini 中配置

代码语言:javascript
复制
[pytest]

env = test

方法二: 执行 pytest 命令的时候设置

代码语言:javascript
复制
pytest --env test

如果2个地方都有设置,那么优先级是:命令行参数--env test 大于 pytest.ini 中配置env = test.

测试环境的BASE_URL

在上一篇中讲到 pytest + yaml 框架 -11.全局 base_url 配置

代码语言:javascript
复制
环境地址优先级使用如下:
1.全局配置命令行参数--base-url优先级大于 pytest.ini 文件中的base_url 配置。
2.yaml 文件 config 中的base_url 优先级大于全局配置
3.request 请求的url 如果是绝对地址,那么base_url 无效
总的来说 : url 绝对地址 > config 中的base_url > 命令行参数--base-url > pytest.ini 文件中的base_url

这里我们新增了一个在config.py 中也可以配置全局的base_url (config.py 中的配置用大写命名 BASE_URL)

如果在 config.py 中配置全局的 BASE_URL ,那么也会生效。优先级会低于命令行和 pytest.ini 的配置

总的来说:url 绝对地址 > config 中的base_url > 命令行参数—base-url > pytest.ini 文件中的 base_url > config.py 的 BASE_URL

mysql 数据库配置

如果用例中需要执行mysql 数据库,或者在断言的时候需要查询mysql 数据库。先在config.py 中完成配置

代码语言:javascript
复制
class TestConfig(Config):
    """测试环境"""
    BASE_URL = 'http://192.168.1.1:8000'
    MYSQL_HOST = "192.168.1.1"
    MYSQL_USER = "root"
    MYSQL_PASSWORD = "123456"
    MYSQL_PORT = 3306
    MYSQL_DATABASE = "xxx"   # 连接数据的库名

当完成了MYSQL 相关的五个配置,那么有个内置的函数可以使用

  • query_sql(sql) 查询sql, 查询无结果返回None, 查询只有一个结果返回dict, 查询多个结果返回list of dict
  • execute_sql(sql) 执行sql, 操作新增,修改,删除的sql

断言执行sql

使用示例

代码语言:javascript
复制
config:
  base_url: http://124.70.221.221:8201
  variables:
    username: test
    sql: select * from auth_user where username like 'test';

登录:
    name: step login
    request:
        url: /api/v1/login
        method: POST
        json:
            username: ${username}
            password: "123456"
    extract:
        token: $.token
    validate:
        - eq: [status_code, 200]
        - eq: [ok, true]
        - eq: [$.username, '${query_sql(sql).username}']

以上示例是断言的时候,执行sql,获取数据库的值

代码语言:javascript
复制
- eq: [$.username, '${query_sql(sql).username}']

可以开启日志

代码语言:javascript
复制
[pytest]

log_cli = true
log_cli_level = debug
env = test

查看运行日志

代码语言:javascript
复制
body:
     {"code": 0, "msg": "login success!", "username": "test", "token": "6112772900193da079e9fcc857613f6125
3648fd"}

2022-12-13 10:34:54 [INFO]: extract 提取变量-> {'token': '6112772900193da079e9fcc857613f61253648fd'}
2022-12-13 10:34:54 [DEBUG]: query sql: select * from auth_user where username like 'test';!
2022-12-13 10:34:54 [INFO]: query result: {'id': 2, 'password': 'pbkdf2_sha256$100000$rSQNBkIc2xOm$VGXiUZk
dsIueT/AsoPwlFSEL1vGODsK7eIjK0nawH/M=', 'last_login': None, 'is_superuser': 0, 'username': 'test', 'first_
name': '', 'last_name': '', 'email': '478391@qq.com', 'is_staff': 0, 'is_active': 1, 'date_joined': dateti
me.datetime(2022, 11, 11, 21, 22, 59, 971425)}
2022-12-13 10:34:54 [INFO]: validate 校验内容-> [{'eq': ['status_code', 200]}, {'eq': ['ok', True]}, {'eq'
: ['$.username', 'test']}]
2022-12-13 10:34:54 [INFO]: validate 校验结果-> eq: [200, 200]
2022-12-13 10:34:54 [INFO]: validate 校验结果-> eq: [True, True]
2022-12-13 10:34:54 [INFO]: validate 校验结果-> eq: [test, test]

从返回的body 里面提取username 使用表达式.username, 得到实际结果”test” ‘{query_sql(sql).username}’ 表达式会先调用query_sql(sql) 函数,引用前面设置的变量sql, 得到结果

代码语言:javascript
复制
{'id': 2, 'password': 'pbkdf2_sha256$100000$rSQNBkIc2xOm$VGXiUZk
dsIueT/AsoPwlFSEL1vGODsK7eIjK0nawH/M=', 'last_login': None, 'is_superuser': 0, 'username': 'test', 'first_
name': '', 'last_name': '', 'email': '478391@qq.com', 'is_staff': 0, 'is_active': 1, 'date_joined': dateti
me.datetime(2022, 11, 11, 21, 22, 59, 971425)}

得到的结果是一个字典,字典对象可以继续取值,于是'${query_sql(sql).username}' 就可以得到期望结果 “test”

用例的参数也可以查询sql

如果用例的参数,需要从sql中取值,我们也可以先定义变量,在用例中引用query_sql(sql) 函数

代码语言:javascript
复制
config:
  variables:
    sql: select * from auth_user where username like 'test';

登录:
    name: step login
    request:
        url: /api/v1/login
        method: POST
        json:
            username: ${query_sql(sql).username}
            password: "123456"
    extract:
        token: $.token
        x: ${query_sql(sql).username}
    validate:
        - eq: [status_code, 200]
        - eq: [ok, true]
        - eq: [$.username, test]

extract 中也可以支持执行sql,得到提取结果

代码语言:javascript
复制
  extract:
        token: $.token
        x: ${query_sql(sql).username}

用例前置和后置执行sql

如果需要在用例的前置和后置中执行sql, 可以用到hook 机制,在请求前和请求后执行函数 参考前面这篇 pytest + yaml 框架 -6.hooks 钩子功能实现

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从零开始学自动化测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 多环境配置
  • 测试环境的BASE_URL
  • mysql 数据库配置
  • 断言执行sql
  • 用例的参数也可以查询sql
  • 用例前置和后置执行sql
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档