pytest + yaml 框架 -12.支援執行sql 和 斷言sql
前言
當我們在測試環境寫好自動化的程式碼,領導說你把程式碼部署到聯調環境再測一測,這時候去改用例裡面的配置是很痛苦的。
所以我們在設計自動化用例的時候,就先要想到多環境的配置與切換。
多環境配置
如果需用到多套環境 test/uat 等,那麼應該在用例的根目錄(pytest.ini 同級檔案)建立一個config.py 檔案
pip 安裝外掛
pip install pytest-yaml-yoyo
多套環境切換功能在 v1.0.10 版本上實現
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 命名,格式如下
env = {
"test": TestConfig,
"uat": UatConfig
}
那麼在執行用例的時候,可以選擇執行test 環境還是uat 環境,有 2 種方式可以配置待執行的環境
方法一: 在pytest.ini 中配置
[pytest]
env = test
方法二: 執行 pytest 命令的時候設定
pytest --env test
如果2個地方都有設定,那麼優先順序是:命令列引數 --env test
大於 pytest.ini 中配置env = test
測試環境的BASE_URL
在上一篇中講到 pytest + yaml 框架 -11.全域性 base_url 配置
環境地址優先順序使用如下: 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 中完成配置
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
使用示例
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,獲取資料庫的值
- eq: [$.username, '${query_sql(sql).username}']
可以開啟日誌
[pytest]
log_cli = true
log_cli_level = debug
env = test
檢視執行日誌
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': '[email protected]', '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, 得到結果
{'id': 2, 'password': 'pbkdf2_sha256$100000$rSQNBkIc2xOm$VGXiUZk
dsIueT/AsoPwlFSEL1vGODsK7eIjK0nawH/M=', 'last_login': None, 'is_superuser': 0, 'username': 'test', 'first_
name': '', 'last_name': '', 'email': '[email protected]', '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) 函式
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,得到提取結果
extract:
token: $.token
x: ${query_sql(sql).username}
用例前置和後置執行sql
如果需要在用例的前置和後置中執行sql, 可以用到hook 機制,在請求前和請求後執行函式
參考前面這篇pytest + yaml 框架 -6.hooks 鉤子功能實現