赞
踩
在 Pytest 中,我们可以使用 fixture 来封装测试用例的前置和后置操作。fixture 是一个带有装饰器@pytest.fixture 的函数,它可以在测试用例执行前后执行一些代码,例如登录、退出登录、清理测试数据等
- import pytest
-
- @pytest.fixture(scope="module")
- def login():
- # 执行登录操作
- yield
- # 执行退出操作
-
- @pytest.fixture(scope="function")
- def clear_data():
- # 执行清除测试数据操作
- pass
-
- def test_case1(login, clear_data):
- # 执行测试用例1,需要登录和清除测试数据的支持
-
- def test_case2(login, clear_data):
- # 执行测试用例2,需要登录和清除测试数据的支持
-
- @pytest.fixture(scope="module")
- def logout():
- # 执行退出操作
- pass
-
- def test_case3(logout):
- # 执行测试用例3,只需要退出操作的支持
例如测试环境的配置、测试数据的读取等,可以使用yaml 或者 json 等配置文件进行管理。
- #使用pytest和json文件封装测试环境配置和测试数据读取
- import pytest
- import os
- import json
-
- @pytest.fixture(scope='session')
- def test_config():
- # 读取测试环境配置
- config_file = os.path.join(os.path.dirname(__file__), 'config.json')
- with open(config_file, 'r') as f:
- config = json.load(f)
- return config
-
- @pytest.fixture(scope='session')
- def test_data():
- # 读取测试数据
- data_file = os.path.join(os.path.dirname(__file__), 'test_data.json')
- with open(data_file, 'r') as f:
- data = json.load(f)
- return data
'运行
如上,我们将配置信息和测试数据分别存储在了config.json和test_data.json文件中。在fixture函数中,我们通过读取这两个文件来获取配置信息和测试数据。需要注意的是,我们需要使用os模块来获取json文件的路径。
例如发送 HTTP 请求、解析响应结果、断言等,可以使用 requests、jsonpath 等库进行实现。
- #封装发送 HTTP 请求、解析响应结果、断言
- import requests
-
- def send_request(method, url, data=None, headers=None):
- """
- 发送 HTTP 请求并返回响应结果
- """
- response = requests.request(method, url, data=data, headers=headers)
- return response
-
- def parse_response(response):
- """
- 解析 HTTP 响应结果并返回对应的数据
- """
- data = response.json()
- return data
-
- def assert_response(response, expected_status_code, expected_data=None):
- """
- 断言 HTTP 响应结果是否符合预期
- """
- assert response.status_code == expected_status_code
- if expected_data is not None:
- assert response.json() == expected_data
'运行
以上代码中,send_request 函数用于发送 HTTP 请求并返回响应结果,parse_response 函数用于解
析 HTTP 响应结果并返回对应的数据,assert_response 函数用于断言 HTTP 响应结果是否符合预期。
- #在编写测试用例时,可以使用这些函数来封装测试用例的前置和后置操作,避免重复的代码
- def test_create_user():
- # 发送创建用户的请求
- data = {"username": "testuser", "password": "testpassword"}
- response = send_request("POST", "http://localhost:8000/api/users/", data=data)
-
- # 解析响应结果
- data = parse_response(response)
-
- # 断言响应结果是否符合预期
- assert_response(response, 201, {"id": data["id"], "username": "testuser"})
'运行
在上面的测试用例中,我们使用 send_request 函数发送创建用户的请求,使用 parse_response 函数解析响应结果,使用 assert_response 函数断言响应结果是否符合预期。这样,我们就可以避免在每个测试用例中重复编写这些代码。
例如 pytest-html、allure-pytest 等,可以方便地生成美观的测试报告。
- #安装
- pip install pytest-html
-
- import pytest
- from datetime import datetime
- from _pytest.config import Config
-
- @pytest.fixture(scope="session")
- def html_report(request: pytest.FixtureRequest, config: Config):
- report_path = config.getoption("--html-report-path")
- report_name = f"report_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.html"
- report_file = f"{report_path}/{report_name}"
-
- def _generate_report():
- yield
- with open(report_file, "w", encoding="utf-8") as f:
- f.write(request.config._html.report_html)
-
- yield _generate_report
-
- if request.config.getoption("--html-open"):
- import webbrowser
- webbrowser.open(report_file, new=2)
在这个 fixture 中,我们使用了 Pytest 的 Config 类来获取命令行参数 --html-report-path,这个参数指定了测试报告的保存路径。然后我们在 _generate_report 函数中生成测试报告,并将测试报告保存到指定的路径。最后,我们将 _generate_report 函数作为 fixture 的返回值,这样测试用例就可以使用这个 fixture 来生成测试报告了。
使用这个 fixture 很简单,只需要在测试用例中添加一个参数即可:
- def test_example(html_report):
- # 测试代码
在运行测试用例时,可以使用 --html-report-path 参数来指定测试报告的保存路径,例如:
pytest --html-report-path=./reports
这样就可以将测试报告保存到 ./reports 目录下了。同时,我们还可以使用 --html-open 参数来在测试用例执行完毕后自动打开测试报告:
pytest --html-report-path=./reports --html-open
这样在测试用例执行完毕后,测试报告会自动在浏览器中打开。
- #安装
- pip install allure-pytest
-
- import pytest
- from datetime import datetime
- import os
- import shutil
- import subprocess
-
- @pytest.fixture(scope="session")
- def allure_report(request):
- report_dir = os.path.join(os.getcwd(), "allure-report")
- if os.path.exists(report_dir):
- shutil.rmtree(report_dir)
- cmd = f"pytest --alluredir={report_dir}"
- subprocess.call(cmd, shell=True)
- yield report_dir
- cmd = f"allure serve {report_dir}"
- subprocess.call(cmd, shell=True)
在这个 fixture 中,我们首先创建了一个新的测试报告目录,然后使用 Pytest 命令行工具来运行测试用例,并将测试报告保存到指定的目录中。在测试用例执行完毕后,我们使用 allure 命令行工具来生成并展示测试报告。
接下来,我们需要在测试用例中使用这个 fixture。在 Pytest 中,我们可以使用 @pytest.mark.usefixtures 装饰器来指定使用哪个 fixture。
- import pytest
-
- @pytest.mark.usefixtures("allure_report")
- def test_example():
- assert 1 + 1 == 2
'运行
在这个测试用例中,我们使用了 @pytest.mark.usefixtures("allure_report") 装饰器来指定使用 allure_report fixture。这样,在测试用例执行前,Pytest 会自动执行 allure_report fixture 中定义的操作。
最后,我们可以使用 Pytest 命令行工具来运行测试用例,并生成测试报告。以下是一个运行测试用例并生成测试报告的命令:
pytest --alluredir=./allure-report
在这个命令中,我们使用 --alluredir 参数来指定测试报告生成的目录。
运行完毕后,我们可以使用以下命令来展示测试报告:
allure serve ./allure-report
在 pytest 中,我们可以使用 Python 内置的 logging 模块来记录日志。具体来说,我们可以在 conftest.py 文件中定义一个 fixture 来封装日志模块,然后在测试用例中使用该 fixture 来记录日志。
- import logging
- import pytest
-
- @pytest.fixture(scope="session")
- def logger(request):
- logger = logging.getLogger('pytest')
- logger.setLevel(logging.DEBUG)
- log_file = request.config.getoption("--log-file")
- fh = logging.FileHandler(log_file, mode='w')
- fh.setLevel(logging.DEBUG)
- ch = logging.StreamHandler()
- ch.setLevel(logging.DEBUG)
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- fh.setFormatter(formatter)
- ch.setFormatter(formatter)
- logger.addHandler(fh)
- logger.addHandler(ch)
- return logger
'运行
在上面的代码中,我们定义了一个名为 logger 的 fixture,它的作用域是 session 级别。我们使用 logging.getLogger('pytest') 来获取一个名为 pytest 的 logger 对象,并将其日志级别设置为 DEBUG。然后,我们使用 request.config.getoption("--log-file") 来获取命令行参数中的日志文件路径,并创建一个 FileHandler 对象和一个 StreamHandler 对象来分别将日志写入文件和控制台。最后,我们将这两个 handler 添加到 logger 对象中,并返回 logger 对象。
在测试用例中,我们可以像下面这样使用 logger fixture 来记录日志:
- def test_something(logger):
- logger.debug('This is a debug message')
- logger.info('This is an info message')
- logger.warning('This is a warning message')
- logger.error('This is an error message')
- logger.critical('This is a critical message')
'运行
在上面的测试用例中,我们使用 logger.debug()、logger.info()、logger.warning()、logger.error() 和 logger.critical() 方法来记录不同级别的日志信息。这些日志信息将会被写入到我们在 conftest.py 文件中指定的日志文件中。
在 pytest 中封装公用的异常处理模块可以提高测试用例的可维护性和可读性,同时也可以减少代码重复。可以在 conftest.py 文件中定义 fixture 来封装异常处理模块。
- import pytest
-
- @pytest.fixture
- def exception_handler():
- try:
- yield
- except Exception as e:
- pytest.fail(str(e))
'运行
在测试用例中,可以使用 exception_handler fixture 来封装需要进行异常处理的代码块
- def test_something(exception_handler):
- # some code that may raise an exception
- assert True
'运行
如果测试用例中的代码块抛出异常,exception_handler fixture 会自动捕获并将异常信息转化为 pytest 的失败信息,从而使测试用例失败。如果代码块没有抛出异常,测试用例会正常执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。