Skip to content

Commit fc39b8e

Browse files
committed
Added pivot groups & snippets for MSTest & NUnit
1 parent f719297 commit fc39b8e

File tree

15 files changed

+1616
-25
lines changed

15 files changed

+1616
-25
lines changed

aspnetcore/test/integration-tests.md

Lines changed: 195 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ms.author: tdykstra
77
ms.custom: mvc
88
ms.date: 3/24/2025
99
uid: test/integration-tests
10+
zone_pivot_groups: unit-testing-framework
1011
---
1112
# Integration tests in ASP.NET Core
1213

@@ -63,7 +64,21 @@ The following test class, `BasicTests`, uses the `WebApplicationFactory` to boot
6364

6465
<xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601.CreateClient> creates an instance of `HttpClient` that automatically follows redirects and handles cookies.
6566

66-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/BasicTests.cs?name=snippet1)]
67+
:::zone pivot="xunit"
68+
69+
:::code language="csharp" source="snippets/xunit/IntegrationTests/BasicTests.cs?name=snippet1":::
70+
71+
:::zone-end
72+
:::zone pivot="mstest"
73+
74+
:::code language="csharp" source="snippets/mstest/IntegrationTests/BasicTests.cs?name=snippet1":::
75+
76+
:::zone-end
77+
:::zone pivot="nunit"
78+
79+
:::code language="csharp" source="snippets/nunit/IntegrationTests/BasicTests.cs?name=snippet1":::
80+
81+
:::zone-end
6782

6883
By default, non-essential cookies aren't preserved across requests when the [General Data Protection Regulation consent policy](xref:security/gdpr) is enabled. To preserve non-essential cookies, such as those used by the TempData provider, mark them as essential in your tests. For instructions on marking a cookie as essential, see [Essential cookies](xref:security/gdpr#essential-cookies).
6984

@@ -79,7 +94,21 @@ Web host configuration can be created independently of the test classes by inher
7994

8095
1. Inherit from `WebApplicationFactory` and override <xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601.ConfigureWebHost%2A>. The <xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder> allows the configuration of the service collection with [`IWebHostBuilder.ConfigureServices`](xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder.ConfigureServices%2A)
8196

82-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/CustomWebApplicationFactory.cs?name=snippet1)]
97+
:::zone pivot="xunit"
98+
99+
:::code language="csharp" source="snippets/xunit/CustomWebApplicationFactory.cs?name=snippet1":::
100+
101+
:::zone-end
102+
:::zone pivot="mstest"
103+
104+
:::code language="csharp" source="snippets/mstest/CustomWebApplicationFactory.cs?name=snippet1":::
105+
106+
:::zone-end
107+
:::zone pivot="nunit"
108+
109+
:::code language="csharp" source="snippets/nunit/CustomWebApplicationFactory.cs?name=snippet1":::
110+
111+
:::zone-end
83112

84113
Database seeding in the [sample app](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/test/integration-tests/10.x/IntegrationTestsSample) is performed by the `InitializeDbForTests` method. The method is described in the [Integration tests sample: Test app organization](#test-app-organization) section.
85114

@@ -96,13 +125,41 @@ Web host configuration can be created independently of the test classes by inher
96125
-->
97126
2. Use the custom `CustomWebApplicationFactory` in test classes. The following example uses the factory in the `IndexPageTests` class:
98127

99-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet1)]
128+
:::zone pivot="xunit"
129+
130+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet1":::
131+
132+
:::zone-end
133+
:::zone pivot="mstest"
134+
135+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet1":::
136+
137+
:::zone-end
138+
:::zone pivot="nunit"
139+
140+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet1":::
141+
142+
:::zone-end
100143

101144
The sample app's client is configured to prevent the `HttpClient` from following redirects. As explained later in the [Mock authentication](#mock-authentication) section, this permits tests to check the result of the app's first response. The first response is a redirect in many of these tests with a `Location` header.
102145

103146
3. A typical test uses the `HttpClient` and helper methods to process the request and the response:
104147

105-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet2)]
148+
:::zone pivot="xunit"
149+
150+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet2":::
151+
152+
:::zone-end
153+
:::zone pivot="mstest"
154+
155+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet2":::
156+
157+
:::zone-end
158+
:::zone pivot="nunit"
159+
160+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet2":::
161+
162+
:::zone-end
106163

107164
Any POST request to the SUT must satisfy the antiforgery check that's automatically made by the app's [data protection antiforgery system](xref:security/data-protection/introduction). In order to arrange for a test's POST request, the test app must:
108165

@@ -135,15 +192,43 @@ The `Post_DeleteMessageHandler_ReturnsRedirectToRoot` test method of the [sample
135192

136193
Because another test in the `IndexPageTests` class performs an operation that deletes all of the records in the database and may run before the `Post_DeleteMessageHandler_ReturnsRedirectToRoot` method, the database is reseeded in this test method to ensure that a record is present for the SUT to delete. Selecting the first delete button of the `messages` form in the SUT is simulated in the request to the SUT:
137194

138-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet3)]
195+
:::zone pivot="xunit"
196+
197+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet3":::
198+
199+
:::zone-end
200+
:::zone pivot="mstest"
201+
202+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet3":::
203+
204+
:::zone-end
205+
:::zone pivot="nunit"
206+
207+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet3":::
208+
209+
:::zone-end
139210

140211
## Client options
141212

142213
See the <xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactoryClientOptions> page for defaults and available options when creating `HttpClient` instances.
143214

144215
Create the `WebApplicationFactoryClientOptions` class and pass it to the <xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601.CreateClient> method:
145216

146-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet1)]
217+
:::zone pivot="xunit"
218+
219+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet1":::
220+
221+
:::zone-end
222+
:::zone pivot="mstest"
223+
224+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet1":::
225+
226+
:::zone-end
227+
:::zone pivot="nunit"
228+
229+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet1":::
230+
231+
:::zone-end
147232

148233
***NOTE:*** To avoid HTTPS redirection warnings in logs when using HTTPS Redirection Middleware, set `BaseAddress = new Uri("https://localhost")`
149234

@@ -188,11 +273,39 @@ To test the service and quote injection in an integration test, a mock service i
188273

189274
`IntegrationTests.IndexPageTests.cs`:
190275

191-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet4)]
276+
:::zone pivot="xunit"
277+
278+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet4":::
279+
280+
:::zone-end
281+
:::zone pivot="mstest"
282+
283+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet4":::
284+
285+
:::zone-end
286+
:::zone pivot="nunit"
287+
288+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet4":::
289+
290+
:::zone-end
192291

193292
`ConfigureTestServices` is called, and the scoped service is registered:
194293

195-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/IndexPageTests.cs?name=snippet5&highlight=7-10,17,20-21)]
294+
:::zone pivot="xunit"
295+
296+
:::code language="csharp" source="snippets/xunit/IntegrationTests/IndexPageTests.cs?name=snippet5&highlight=7-10,17,20-21":::
297+
298+
:::zone-end
299+
:::zone pivot="mstest"
300+
301+
:::code language="csharp" source="snippets/mstest/IntegrationTests/IndexPageTests.cs?name=snippet5&highlight=7-10,17,20-21":::
302+
303+
:::zone-end
304+
:::zone pivot="nunit"
305+
306+
:::code language="csharp" source="snippets/nunit/IntegrationTests/IndexPageTests.cs?name=snippet5&highlight=7-10,17,20-21":::
307+
308+
:::zone-end
196309

197310
The markup produced during the test's execution reflects the quote text supplied by `TestQuoteService`, thus the assertion passes:
198311

@@ -214,7 +327,21 @@ In the SUT, the `/SecurePage` page uses an <xref:Microsoft.Extensions.Dependency
214327

215328
In the `Get_SecurePageRedirectsAnUnauthenticatedUser` test, a <xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactoryClientOptions> is set to disallow redirects by setting <xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactoryClientOptions.AllowAutoRedirect> to `false`:
216329

217-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/AuthTests.cs?name=snippet2)]
330+
:::zone pivot="xunit"
331+
332+
:::code language="csharp" source="snippets/xunit/IntegrationTests/AuthTests.cs?name=snippet2":::
333+
334+
:::zone-end
335+
:::zone pivot="mstest"
336+
337+
:::code language="csharp" source="snippets/mstest/IntegrationTests/AuthTests.cs?name=snippet2":::
338+
339+
:::zone-end
340+
:::zone pivot="nunit"
341+
342+
:::code language="csharp" source="snippets/nunit/IntegrationTests/AuthTests.cs?name=snippet2":::
343+
344+
:::zone-end
218345

219346
By disallowing the client to follow the redirect, the following checks can be made:
220347

@@ -223,11 +350,39 @@ By disallowing the client to follow the redirect, the following checks can be ma
223350

224351
The test app can mock an <xref:Microsoft.AspNetCore.Authentication.AuthenticationHandler%601> in <xref:Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.ConfigureTestServices%2A> in order to test aspects of authentication and authorization. A minimal scenario returns an <xref:Microsoft.AspNetCore.Authentication.AuthenticateResult.Success%2A?displayProperty=nameWithType>:
225352

226-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/AuthTests.cs?name=snippet4&highlight=11-18)]
353+
:::zone pivot="xunit"
354+
355+
:::code language="csharp" source="snippets/xunit/IntegrationTests/AuthTests.cs?name=snippet4&highlight=11-18":::
356+
357+
:::zone-end
358+
:::zone pivot="mstest"
359+
360+
:::code language="csharp" source="snippets/mstest/IntegrationTests/AuthTests.cs?name=snippet4&highlight=11-18":::
361+
362+
:::zone-end
363+
:::zone pivot="nunit"
364+
365+
:::code language="csharp" source="snippets/nunit/IntegrationTests/AuthTests.cs?name=snippet4&highlight=11-18":::
366+
367+
:::zone-end
227368

228369
The `TestAuthHandler` is called to authenticate a user when the authentication scheme is set to `TestScheme` where `AddAuthentication` is registered for `ConfigureTestServices`. It's important for the `TestScheme` scheme to match the scheme your app expects. Otherwise, authentication won't work.
229370

230-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/IntegrationTests/AuthTests.cs?name=snippet3&highlight=7-12)]
371+
:::zone pivot="xunit"
372+
373+
:::code language="csharp" source="snippets/xunit/IntegrationTests/AuthTests.cs?name=snippet3&highlight=7-12":::
374+
375+
:::zone-end
376+
:::zone pivot="mstest"
377+
378+
:::code language="csharp" source="snippets/mstest/IntegrationTests/AuthTests.cs?name=snippet3&highlight=7-12":::
379+
380+
:::zone-end
381+
:::zone pivot="nunit"
382+
383+
:::code language="csharp" source="snippets/nunit/IntegrationTests/AuthTests.cs?name=snippet3&highlight=7-12":::
384+
385+
:::zone-end
231386

232387
For more information on `WebApplicationFactoryClientOptions`, see the [Client options](#client-options) section.
233388

@@ -239,7 +394,21 @@ See [this GitHub repository](https://github.com/blowdart/idunno.Authentication/t
239394

240395
Set the [environment](xref:fundamentals/environments) in the custom application factory:
241396

242-
[!code-csharp[](~/../AspNetCore.Docs.Samples/test/integration-tests/10.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/CustomWebApplicationFactory.cs?name=snippet1&highlight=36)]
397+
:::zone pivot="xunit"
398+
399+
:::code language="csharp" source="snippets/xunit/CustomWebApplicationFactory.cs?name=snippet1&highlight=36":::
400+
401+
:::zone-end
402+
:::zone pivot="mstest"
403+
404+
:::code language="csharp" source="snippets/mstest/CustomWebApplicationFactory.cs?name=snippet1&highlight=36":::
405+
406+
:::zone-end
407+
:::zone pivot="nunit"
408+
409+
:::code language="csharp" source="snippets/nunit/CustomWebApplicationFactory.cs?name=snippet1&highlight=36":::
410+
411+
:::zone-end
243412

244413
## How the test infrastructure infers the app content root path
245414

@@ -259,8 +428,22 @@ To disable shadow copying when using xUnit, create a `xunit.runner.json` file in
259428

260429
## Disposal of objects
261430

431+
:::zone pivot="xunit"
432+
262433
After the tests of the `IClassFixture` implementation are executed, <xref:Microsoft.AspNetCore.TestHost.TestServer> and <xref:System.Net.Http.HttpClient> are disposed when xUnit disposes of the [`WebApplicationFactory`](xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601). If objects instantiated by the developer require disposal, dispose of them in the `IClassFixture` implementation. For more information, see [Implementing a Dispose method](/dotnet/standard/garbage-collection/implementing-dispose).
263434

435+
:::zone-end
436+
:::zone pivot="mstest"
437+
438+
After the tests of the `TestClass` are executed, <xref:Microsoft.AspNetCore.TestHost.TestServer> and <xref:System.Net.Http.HttpClient> are disposed when MSTest disposes of the [`WebApplicationFactory`](xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601) in the `ClassCleanup` method. If objects instantiated by the developer require disposal, dispose of them in the `ClassCleanup` method. For more information, see [Implementing a Dispose method](/dotnet/standard/garbage-collection/implementing-dispose).
439+
440+
:::zone-end
441+
:::zone pivot="nunit"
442+
443+
After the tests of the test class are executed, <xref:Microsoft.AspNetCore.TestHost.TestServer> and <xref:System.Net.Http.HttpClient> are disposed when NUnit disposes of the [`WebApplicationFactory`](xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601) in the `TearDown` method. If objects instantiated by the developer require disposal, dispose of them in the `TearDown` method. For more information, see [Implementing a Dispose method](/dotnet/standard/garbage-collection/implementing-dispose).
444+
445+
:::zone-end
446+
264447
## Integration tests sample
265448

266449
The [sample app](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/test/integration-tests/10.x/IntegrationTestsSample) is composed of two apps:

0 commit comments

Comments
 (0)