使用unittest框架接口测试中,yaml文件中上一个接口的返回值在下一个接口的data中作为参数,yaml文件中如何进行编写
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在yaml文件中,可以使用以下格式来设置参数关联的情况:
test_case:
- name: Test1
url: http://www.example.com/api/login
method: post
data:
username: testuser
password: Test@123
- name: Test2
url: http://www.example.com/api/userinfo
method: get
headers:
Authorization: $Token
data:
user_id: $user_info.user_id
在上面的示例中,Test2接口的headers中使用了$Token参数,该参数是从上一个接口(Test1)的返回值中获取的。而Test2接口的data中,使用了$user_info.user_id参数,该参数是从上一个接口(Test1)返回值中的user_id字段获取的。
在使用unittest框架进行接口测试时,需要在测试类中编写函数来读取yaml文件中的测试用例、执行测试,并进行断言。下面是一个示例代码:
import unittest
import requests
import yaml
class TestAPI(unittest.TestCase):
def setUp(self):
self.base_url = "http://www.example.com/api/"
def test_api(self):
with open("test_case.yaml", "r") as f:
test_cases = yaml.safe_load(f)
for test_case in test_cases:
name = test_case["name"]
url = self.base_url + test_case["url"]
method = test_case["method"]
headers = test_case.get("headers", {})
data = test_case.get("data", {})
# 处理参数关联
for key, value in data.items():
if isinstance(value, str) and value.startswith("$"):
previous_key = value[1:]
previous_resp = previous_resp if previous_resp else {}
data[key] = eval("previous_resp" + previous_key)
# 发送请求
resp = requests.request(method, url, headers=headers, json=data)
resp_json = resp.json()
previous_resp = resp_json # 将当前接口的返回值存储到previous_resp中,供下一个接口使用
# 断言
self.assertEqual(resp.status_code, 200)
if __name__ == "__main__":
unittest.main()
在上面的代码中,setUp函数用于设置测试用例的基础URL。test_api函数读取test_case.yaml文件中的测试用例,遍历每个接口,并对参数关联进行处理,然后发送请求并断言。previous_resp变量用于存储上一个接口的返回值,在下一个接口中使用。
如果我的回答解决了您的问题,请采纳!
请看以下示例:
test_case_1:
url: http://example.com/api/login
method: post
headers:
Content-Type: application/json
data:
username: testuser
password: testpass
asserts:
- status_code: 200
- response_json.code: 0
extract:
token: response_json.token
test_case_2:
url: http://example.com/api/get_info
method: get
headers:
Authorization: Bearer ${test_case_1.token}
asserts:
- status_code: 200
- response_json.id: 123
- response_json.name: testuser
在上面的示例中,test_case_1
中 extract
的操作会将 response_json.token
存储在 test_case_1.token
中。下面的 test_case_2
,可以使用 ${test_case_1.token}
的方式引用 test_case_1
中存储的值,作为其请求头中 Authorization
字段的值。如果你需要在下一个接口中使用其他的值作为参数,也可以使用类似 test_case_1.token
的方式在不同的测试用例之间传递数据。
在使用unittest框架进行接口测试时,如果yaml文件中有动态参数关联的情况,可以使用python中的字符串模板来进行处理。您可以在yaml文件中定义一个动态参数,然后使用字符串模板的方式将该参数与其他参数进行关联。例如:
testcase1:
url: "/api/user/login"
method: "POST"
headers:
Content-Type: "application/json"
body:
username: "user1"
password: "password1"
expected:
code: 200
message: "login success"
dynamic_params:
token: "$response.body.token"
在上面的yaml文件中,我们定义了一个动态参数 token,并使用字符串模板的方式将其与响应body中的token字段进行关联。在测试用例中,我们可以通过解析yaml文件,获取到该动态参数的值,然后在后续的测试用例中使用。例如:
import unittest
import yaml
import requests
class TestApi(unittest.TestCase):
@classmethod
def setUpClass(cls):
with open("test.yaml", "r") as f:
cls.test_data = yaml.safe_load(f)
def test_login(self):
url = self.test_data["testcase1"]["url"]
method = self.test_data["testcase1"]["method"]
headers = self.test_data["testcase1"]["headers"]
body = self.test_data["testcase1"]["body"]
response = requests.request(method, url, headers=headers, json=body)
self.assertEqual(response.status_code, self.test_data["testcase1"]["expected"]["code"])
self.assertEqual(response.json()["message"], self.test_data["testcase1"]["expected"]["message"])
# 获取动态参数token的值,并保存到类属性中
self.__class__.token = response.json()["body"]["token"]
def test_query_user(self):
url = self.test_data["testcase2"]["url"]
method = self.test_data["testcase2"]["method"]
headers = self.test_data["testcase2"]["headers"]
# 使用字符串模板的方式,将动态参数token与url进行关联
url = url.format(token=self.__class__.token)
response = requests.request(method, url, headers=headers)
self.assertEqual(response.status_code, self.test_data["testcase2"]["expected"]["code"])
self.assertEqual(response.json()["message"], self.test_data["testcase2"]["expected"]["message"])
在上面的示例中,我们使用 test_login 测试用例中获取了动态参数token的值,并将其保存到了类属性中。然后,在后续的测试用例 test_query_user 中,我们可以使用字符串模板的方式,将该参数与请求url进行关联。这样就能够实现动态参数关联的功能了。
答案出自 https://www.wodianping.com/
-
username: admin9
password: 123456
-
username: normal
password: 789456
[
{
"username": "admin9",
"password": 123456
},
{
"username": "normal",
"password": 7894
}
]
写法:
"""
使用yaml数据驱动
"""
import unittest
from time import sleep
from selenium import webdriver
from ddt import ddt, data, unpack, file_data
@ddt
class YamlTest(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.get('file:///D:/%E6%A1%8C%E9%9D%A2/page/%E6%B3%A8%E5%86%8CA.html')
self.driver.maximize_window()
def tearDown(self) -> None:
driver = self.driver
sleep(3)
driver.quit()
# file_data 传入多个参数的时候,@unpack 的解包不起作用
@unittest.skip
@file_data('../user.yaml')
@unpack
def test_yaml01(self, username, password):
driver = self.driver
driver.find_element_by_id('userA').send_keys(username)
driver.find_element_by_id('passwordA').send_keys(password)
# 注意:传的参数名称要与yaml文件对应
# 在yaml数据中文件中采用对象(键值对)的方式来定义数据内容
@file_data('../user1.yaml')
def test_yaml02(self, username, password):
driver = self.driver
driver.find_element_by_id('userA').send_keys(username)
driver.find_element_by_id('passwordA').send_keys(password)
if __name__ == '__main__':
unittest.main()
注意:file_date 装饰器,可以直接读取yaml和json文件
在unittest框架接口测试中,yaml文件中上一个接口的返回值在下一个接口的data中作为参数的情况下,可以按照以下方法进行编写:
例如,假设上一个接口的名称为“interface1”,返回值为“result”,下一个接口的名称为“interface2”,需要使用上一个接口的返回值作为参数,则可以按照以下方式编写yaml文件:
interface1:
url: /api/test1
method: post
body:
username: testuser
password: testpass
validate:
- eq: [status_code, 200]
store:
- result
interface2:
url: /api/test2
method: post
body:
data: {"$ref": "#/interface1/result"}
validate:
- eq: [status_code, 200]
在上述示例中,我们定义了两个接口“interface1”和“interface2”。在“interface1”中,我们发送了一个post请求,将响应结果存储在“result”中。在“interface2”中,我们发送了另一个post请求,并将“$ref”关键字用于引用“interface1”中存储的“result”参数,以便在请求体中使用。
使用上述方法,您可以在yaml文件中轻松地引用上一个接口的返回值,并将其用作下一个接口的参数。希望这个例子对您有所帮助!