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请求处理和测试的效率和准确性。