@@ -6,6 +6,23 @@ the Azure SDK test proxy.
6
6
Documentation of the motivations and goals of the test proxy can be found [ here] [ general_docs ] in the azure-sdk-tools
7
7
GitHub repository, and documentation of how to set up and use the proxy can be found [ here] [ detailed_docs ] .
8
8
9
+ ## Table of contents
10
+ - [ Update existing tests] ( #update-existing-tests )
11
+ - [ Using resource preparers] ( #using-resource-preparers )
12
+ - [ Run tests] ( #run-tests )
13
+ - [ Perform one-time setup] ( #perform-one-time-setup )
14
+ - [ Start the proxy server] ( #start-the-proxy-server )
15
+ - [ Record or play back tests] ( #record-or-play-back-tests )
16
+ - [ Register sanitizers] ( #register-sanitizers )
17
+ - [ Enable the test proxy in CI] ( #enable-the-test-proxy-in-ci )
18
+ - [ Fetch environment variables] ( #fetch-environment-variables )
19
+ - [ Record test variables] ( #record-test-variables )
20
+ - [ Migrate management-plane tests] ( #migrate-management-plane-tests )
21
+ - [ Advanced details] ( #advanced-details )
22
+ - [ What does the test proxy do?] ( #what-does-the-test-proxy-do )
23
+ - [ How does the test proxy know when and what to record or play back?] ( #how-does-the-test-proxy-know-when-and-what-to-record-or-play-back )
24
+ - [ Start the proxy manually] ( #start-the-proxy-manually )
25
+
9
26
## Update existing tests
10
27
11
28
### Current test structure
@@ -52,22 +69,37 @@ way as `recorded_by_proxy`.
52
69
> with "Test" in order to be properly collected by pytest by default. For more information, please refer to
53
70
> [ pytest's documentation] [ pytest_collection ] .
54
71
55
- ## Run the tests
72
+ ### Using resource preparers
73
+
74
+ Test suites that haven't fully migrated to using a ` test-resources.json ` file for test resource deployment might use
75
+ resource preparers, such as
76
+ [ ResourceGroupPreparer] ( https://github.com/Azure/azure-sdk-for-python/blob/main/tools/azure-sdk-tools/devtools_testutils/resource_testcase.py ) .
77
+ Migrating to [ PowerShell test resource deployment] [ test_resources ] is recommended (and test proxy migration might be a
78
+ good opportunity to look into this), but the test proxy can work with resource preparers.
79
+
80
+ Resource preparers need a management client to function, so test classes that use them will need to inherit from
81
+ [ AzureMgmtRecordedTestCase] [ mgmt_recorded_test_case ] instead of AzureRecordedTestCase.
82
+
83
+ ## Run tests
56
84
57
85
### Perform one-time setup
58
86
87
+ Docker is a requirement for using the test proxy. You can install Docker from
88
+ [ docs.docker.com] ( https://docs.docker.com/get-docker/ ) . After installing, make sure Docker is running and is using
89
+ Linux containers before running tests.
90
+
59
91
The test proxy is made available for your tests via a Docker container. Some tests require an SSL connection to work, so
60
92
the Docker image used for the container has a certificate imported that you need to trust on your machine. Instructions
61
- on how to do so can be found [ here] [ proxy_cert_docs ] .
93
+ on how to do so can be found [ here] [ proxy_cert_docs ] and need to be followed before running tests .
62
94
63
95
### Start the proxy server
64
96
65
97
The test proxy has to be available in order for tests to work in live or playback mode. There's a
66
98
[ section] ( #manually-start-the-proxy ) under [ Advanced details] ( #advanced-details ) that describes how to do this manually,
67
99
but it's recommended that tests use a ` pytest ` fixture to start and stop the proxy automatically when running tests.
68
100
69
- In a ` conftest.py ` file for your package's tests, add a session-level fixture that accepts ` devtools_testutils.test_proxy `
70
- as a parameter (and has ` autouse ` set to ` True ` ):
101
+ In a ` conftest.py ` file for your package's tests, add a session-level fixture that accepts
102
+ ` devtools_testutils.test_proxy ` as a parameter (and has ` autouse ` set to ` True ` ):
71
103
72
104
``` python
73
105
from devtools_testutils import test_proxy
@@ -78,18 +110,24 @@ def start_proxy(test_proxy):
78
110
return
79
111
```
80
112
113
+ The ` test_proxy ` fixture will fetch the test proxy Docker image and create a new container called
114
+ ` ambitious_azsdk_test_proxy ` if one doesn't exist already. If the container already exists, the fixture will start the
115
+ container if it's currently stopped. The container will be stopped after tests finish running, but will stay running if
116
+ test execution is interrupted.
117
+
81
118
If your tests already use an ` autouse ` d, session-level fixture for tests, you can accept the ` test_proxy ` parameter in
82
119
that existing fixture instead of adding a new one. For an example, see the [ Register sanitizers] ( #register-sanitizers )
83
120
section of this document.
84
121
85
- In general, if any fixture requires the test proxy to be available by the time it's used, that fixture should accept this
86
- ` test_proxy ` parameter.
122
+ In general, if any fixture requires the test proxy to be available by the time it's used, that fixture should accept
123
+ this ` test_proxy ` parameter.
87
124
88
125
### Record or play back tests
89
126
90
127
Configuring live and playback tests is done with the ` AZURE_TEST_RUN_LIVE ` environment variable. When this variable is
91
- set to "true" or "yes", live tests will run and produce recordings. When this variable is set to "false" or "no", or
92
- not set at all, tests will run in playback mode and attempt to match existing recordings.
128
+ set to "true" or "yes", live tests will run and produce recordings unless the ` AZURE_SKIP_LIVE_RECORDING ` environment
129
+ variable is set to "true". When ` AZURE_TEST_RUN_LIVE ` is set to "false" or "no", or not set at all, tests will run in
130
+ playback mode and attempt to match existing recordings.
93
131
94
132
Recordings for a given package will end up in that package's ` /tests/recordings ` directory, just like they currently
95
133
do. Recordings that use the test proxy are ` .json ` files instead of ` .yml ` files, so migrated test suites no longer
@@ -98,6 +136,10 @@ need old `.yml` recordings.
98
136
> ** Note:** at this time, support for configuring live or playback tests with a ` testsettings_local.cfg ` file has been
99
137
> deprecated in favor of using just ` AZURE_TEST_RUN_LIVE ` .
100
138
139
+ > ** Note:** the recording storage location is determined when the proxy Docker container is created. If there are
140
+ > multiple local copies of the ` azure-sdk-for-python ` repo on your machine, you will need to delete any existing
141
+ > ` ambitious_azsdk_test_proxy ` container before recordings can be stored in a different repo copy.
142
+
101
143
### Register sanitizers
102
144
103
145
Since the test proxy doesn't use [ ` vcrpy ` ] [ vcrpy ] , tests don't use a scrubber to sanitize values in recordings.
@@ -145,12 +187,60 @@ made to `https://fakeendpoint-secondary.table.core.windows.net`, and URIs will a
145
187
146
188
For more details about sanitizers and their options, please refer to [ devtools_testutils/sanitizers.py] [ py_sanitizers ] .
147
189
148
- ### Enabling the test proxy in CI
190
+ #### Note regarding body matching
191
+
192
+ In the old, ` vcrpy ` -based testing system, request and response bodies weren't compared in playback mode by default in
193
+ most packages. The test proxy system enables body matching by default, which can introduce failures for tests that
194
+ passed in the old system. For example, if a test sends a request that includes the current Unix time in its body, the
195
+ body will contain a new value when run in playback mode at a later time. This request might still match the recording if
196
+ body matching is disabled, but not if it's enabled.
149
197
150
- To enable using the test proxy in CI, you need to set the parameter ` TestProxy: true ` in the ` ci.yml ` and ` tests.yml `
151
- files in the service level folder. For example, in ` sdk/eventgrid/ci.yml ` :
198
+ Body matching can be turned off with the test proxy by calling the ` set_bodiless_matcher ` method from
199
+ [ devtools_testutils/sanitizers.py] [ py_sanitizers ] at the very start of a test method. This matcher applies only to the
200
+ test method that ` set_bodiless_matcher ` is called from, so other tests in the ` pytest ` session will still have body
201
+ matching enabled by default.
202
+
203
+ ### Enable the test proxy in CI
204
+
205
+ To enable using the test proxy in CI, you need to set the parameter ` TestProxy: true ` in the ` ci.yml ` file in the
206
+ service-level folder. For example, in ` sdk/eventgrid/ci.yml ` :
152
207
153
208
![ image] ( https://user-images.githubusercontent.com/45376673/142270668-5be58bca-87e5-45f5-b593-44f8b1f757bc.png )
209
+
210
+ The test proxy is only used in playback pipeline testing, so this parameter doesn't need to be set in ` tests.yml ` . For
211
+ live pipeline testing, requests are made directly to the service instead of going through the proxy first.
212
+
213
+ ### Fetch environment variables
214
+
215
+ Fetching environment variables, passing them directly to tests, and sanitizing their real values can be done all at once
216
+ by using the ` devtools_testutils `
217
+ [ PowerShellPreparer] ( https://github.com/Azure/azure-sdk-for-python/blob/main/tools/azure-sdk-tools/devtools_testutils/powershell_preparer.py ) .
218
+
219
+ The name "PowerShellPreparer" comes from its intended use with the PowerShell test resource management commands that are
220
+ documented in [ /eng/common/TestResources] [ test_resources ] . It's recommended that all test suites use these scripts for
221
+ live test resource management.
222
+
223
+ For an example of using the PowerShellPreparer with the test proxy, you can refer to the Tables SDK. The CosmosPreparer
224
+ and TablesPreparer defined in this [ preparers.py] [ tables_preparers ] file each define an instance of the
225
+ PowerShellPreparer, which are used to fetch environment variables for Cosmos and Tables, respectively. These preparers
226
+ can be used to decorate test methods directly; for example:
227
+
228
+ ``` python
229
+ from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy
230
+ from .preparers import TablesPreparer
231
+
232
+ class TestExample (AzureRecordedTestCase ):
233
+
234
+ @TablesPreparer ()
235
+ @recorded_by_proxy
236
+ def test_example_with_preparer (self , tables_storage_account_name , tables_primary_storage_account_key ):
237
+ ...
238
+ ```
239
+
240
+ Or, they can be used in a custom decorator, as they are in the ` cosmos_decorator ` and ` tables_decorator ` defined in
241
+ [ preparers.py] [ tables_preparers ] . ` @tables_decorator ` , for instance, is then used in place of ` @TablesPreparer() ` for
242
+ the example above (note that the method-style ` tables_decorator ` is used without parentheses).
243
+
154
244
### Record test variables
155
245
156
246
To run recorded tests successfully when there's an element of non-secret randomness to them, the test proxy provides a
@@ -188,6 +278,14 @@ class TestExample(AzureRecordedTestCase):
188
278
return variables
189
279
```
190
280
281
+ ## Migrate management-plane tests
282
+
283
+ For management-plane packages, test classes should inherit from [ AzureMgmtRecordedTestCase] [ mgmt_recorded_test_case ]
284
+ instead of AzureRecordedTestCase.
285
+
286
+ The rest of the information in this guide applies to management-plane packages as well, except for possible specifics
287
+ regarding test resource deployment.
288
+
191
289
## Advanced details
192
290
193
291
### What does the test proxy do?
@@ -235,7 +333,7 @@ Running tests in playback follows the same pattern, except that requests will be
235
333
The ` recorded_by_proxy ` and ` recorded_by_proxy_async ` decorators send the appropriate requests at the start and end of
236
334
each test case.
237
335
238
- ### Manually start the proxy
336
+ ### Start the proxy manually
239
337
240
338
There are two options for manually starting and stopping the test proxy: one uses a PowerShell command, and one uses
241
339
methods from ` devtools_testutils ` .
@@ -270,9 +368,12 @@ For more details on proxy startup, please refer to the [proxy documentation][det
270
368
[ detailed_docs ] : https://github.com/Azure/azure-sdk-tools/tree/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md
271
369
[ docker_start_proxy ] : https://github.com/Azure/azure-sdk-for-python/blob/main/eng/common/testproxy/docker-start-proxy.ps1
272
370
[ general_docs ] : https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/README.md
371
+ [ mgmt_recorded_test_case ] : https://github.com/Azure/azure-sdk-for-python/blob/main/tools/azure-sdk-tools/devtools_testutils/mgmt_recorded_testcase.py
273
372
[ proxy_cert_docs ] : https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/documentation/trusting-cert-per-language.md
274
373
[ py_sanitizers ] : https://github.com/Azure/azure-sdk-for-python/blob/main/tools/azure-sdk-tools/devtools_testutils/sanitizers.py
275
374
[ pytest_collection ] : https://docs.pytest.org/latest/goodpractices.html#test-discovery
276
375
[ pytest_fixtures ] : https://docs.pytest.org/latest/fixture.html#scope-sharing-fixtures-across-classes-modules-packages-or-session
277
376
[ sanitizers ] : https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md#session-and-test-level-transforms-sanitiziers-and-matchers
377
+ [ tables_preparers ] : https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/tables/azure-data-tables/tests/preparers.py
378
+ [ test_resources ] : https://github.com/Azure/azure-sdk-for-python/tree/main/eng/common/TestResources#readme
278
379
[ vcrpy ] : https://vcrpy.readthedocs.io
0 commit comments