vcrpy是一个用于记录和重放HTTP交互的Python库。它允许开发者在进行测试时记录下HTTP请求和响应,并在后续的测试中重放这些记录,避免了对实际服务器的依赖,提高了测试的可靠性和速度。vcrpy支持多种HTTP库,如requests、http.client、urllib等,并且能够无缝集成到常见的测试框架中,如unittest和pytest。本文将详细介绍vcrpy库的安装、主要功能、基本操作、高级功能及其实践应用,并提供丰富的示例代码。
vcrpy可以通过pip进行安装。确保Python环境已激活,然后在终端或命令提示符中运行以下命令:
pip install vcrpy
以下示例展示了如何使用vcrpy记录HTTP请求和响应:
import requests
import vcr
# 创建VCR对象
my_vcr = vcr.VCR(
cassette_library_dir='cassettes', # 录音带存放目录
path_transformer=vcr.VCR.ensure_suffix('.yaml'), # 确保录音带文件后缀为.yaml
record_mode='once', # 录制模式
)
# 记录HTTP请求和响应
with my_vcr.use_cassette('example'):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json())
在第一次运行时,vcrpy会记录下HTTP请求和响应,并将其保存为cassettes/example.yaml文件。在后续运行时,将使用记录的响应,而不会再次发送请求到实际服务器。
在后续的测试中,vcrpy会自动重放记录的HTTP交互:
import requests
import vcr
# 创建VCR对象
my_vcr = vcr.VCR(
cassette_library_dir='cassettes',
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='none', # 仅重放录音带,不进行新的记录
)
# 重放记录的HTTP交互
with my_vcr.use_cassette('example'):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json())
以下示例展示了如何在unittest中使用vcrpy:
import unittest
import requests
import vcr
class TestAPI(unittest.TestCase):
@vcr.use_cassette('cassettes/unittest_example.yaml')
def test_get_post(self):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
self.assertEqual(response.status_code, 200)
self.assertIn('title', response.json())
if __name__ == '__main__':
unittest.main()
以下示例展示了如何在pytest中使用vcrpy:
import requests
import vcr
my_vcr = vcr.VCR(
cassette_library_dir='cassettes',
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='once',
)
@my_vcr.use_cassette('pytest_example.yaml')
def test_get_post():
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
assert response.status_code == 200
assert 'title' in response.json()
vcrpy允许过滤和替换请求和响应中的敏感信息。以下示例展示了如何过滤敏感信息:
import requests
import vcr
# 创建VCR对象,并过滤敏感信息
my_vcr = vcr.VCR(
cassette_library_dir='cassettes',
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='once',
filter_headers=['authorization'], # 过滤请求头中的authorization字段
filter_query_parameters=['api_key'], # 过滤请求参数中的api_key字段
)
with my_vcr.use_cassette('filter_example.yaml'):
response = requests.get('https://api.example.com/data', headers={'authorization': 'secret'})
print(response.json())
可以自定义录音带的存储目录,以便更好地组织测试用例。以下示例展示了如何自定义存储目录:
import requests
import vcr
# 创建VCR对象,并自定义存储目录
my_vcr = vcr.VCR(
cassette_library_dir='my_custom_cassettes', # 自定义存储目录
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='once',
)
with my_vcr.use_cassette('custom_directory_example.yaml'):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json())
vcrpy提供了多种录制模式,以下示例展示了如何使用不同的录制模式:
import requests
import vcr
# 使用不同的录制模式
my_vcr = vcr.VCR(
cassette_library_dir='cassettes',
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='new_episodes', # 仅当录音带不存在或请求未记录时录制
)
with my_vcr.use_cassette('record_mode_example.yaml'):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json())
vcrpy允许自定义匹配规则,以便更精确地匹配请求和响应。以下示例展示了如何自定义匹配规则:
import requests
import vcr
# 创建自定义匹配规则
def custom_matcher(r1, r2):
return r1.method == r2.method and r1.uri == r2.uri
# 使用自定义匹配规则
my_vcr = vcr.VCR(
cassette_library_dir='cassettes',
path_transformer=vcr.VCR.ensure_suffix('.yaml'),
record_mode='once',
match_on=['uri', 'method', custom_matcher], # 添加自定义匹配规则
)
with my_vcr.use_cassette('custom_matcher_example.yaml'):
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json())
以下示例展示了如何使用vcrpy测试API集成:
import requests
import vcr
import unittest
class TestAPIIntegration(unittest.TestCase):
@vcr.use_cassette('cassettes/api_integration.yaml')
def test_get_user(self):
response = requests.get('https://jsonplaceholder.typicode.com/users/1')
self.assertEqual(response.status_code, 200)
self.assertIn('name', response.json())
@vcr.use_cassette('cassettes/api_integration.yaml')
def test_get_posts(self):
response = requests.get('https://jsonplaceholder.typicode.com/posts?userId=1')
self.assertEqual(response.status_code, 200)
self.assertIsInstance(response.json(), list)
if __name__ == '__main__':
unittest.main()
以下示例展示了如何使用vcrpy测试与第三方服务的集成:
import requests
import vcr
import unittest
class TestThirdPartyService(unittest.TestCase):
@vcr.use_cassette('cassettes/third_party_service.yaml')
def test_send_email(self):
response = requests.post('https://api.emailservice.com/send', json={
'to': 'user@example.com',
'subject': 'Test Email',
'body': 'This is a test email.'
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()['status'], 'sent')
if __name__ == '__main__':
unittest.main()
以下示例展示了如何在持续集成环境中使用vcrpy:
# .github/workflows/test.yml
name: Run Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Run tests
run: |
pytest --vcr-record=none # 确保仅重放录音带,不进行新的记录
vcrpy库为Python开发者提供了一个功能强大且灵活的工具,用于记录和重放HTTP交互。通过其简洁的API和丰富的功能,用户可以轻松进行HTTP请求的记录和重放,提高测试的可靠性和速度。无论是在测试API集成、第三方服务还是在持续集成环境中,vcrpy都能提供强大的支持和便利。本文详细介绍了vcrpy库的安装、主要功能、基本操作、高级功能及其实践应用,并提供了丰富的示例代码。希望在实际项目中能够充分利用vcrpy库,提高HTTP请求处理和测试的效率和准确性。