Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to xunit v3 #1282

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 31 additions & 26 deletions tests/TodoApp.Tests/ApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace TodoApp;

[Collection(TodoAppCollection.Name)]
[Collection<TodoAppCollection>]
public class ApiTests
{
public ApiTests(TodoAppFixture fixture, ITestOutputHelper outputHelper)
Expand All @@ -31,10 +31,11 @@ public ApiTests(TodoAppFixture fixture, ITestOutputHelper outputHelper)
public async Task Can_Manage_Todo_Items_With_Api()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var client = await CreateAuthenticatedClientAsync();

// Act - Get all the items
var items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
var items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items", cancellationToken);

// Assert - There should be no items
items.ShouldNotBeNull();
Expand All @@ -47,20 +48,20 @@ public async Task Can_Manage_Todo_Items_With_Api()
var newItem = new CreateTodoItemModel { Text = text };

// Act - Add a new item
using var createdResponse = await client.PostAsJsonAsync("/api/items", newItem);
using var createdResponse = await client.PostAsJsonAsync("/api/items", newItem, cancellationToken);

// Assert - An item was created
createdResponse.StatusCode.ShouldBe(HttpStatusCode.Created);
createdResponse.Headers.Location.ShouldNotBeNull();

using var createdJson = await createdResponse.Content.ReadFromJsonAsync<JsonDocument>();
using var createdJson = await createdResponse.Content.ReadFromJsonAsync<JsonDocument>(cancellationToken);

// Arrange - Get the new item's URL and Id
var itemUri = createdResponse.Headers.Location;
var itemId = createdJson!.RootElement.GetProperty("id").GetString();

// Act - Get the item
var item = await client.GetFromJsonAsync<TodoItemModel>(itemUri);
var item = await client.GetFromJsonAsync<TodoItemModel>(itemUri, cancellationToken);

// Assert - Verify the item was created correctly
item.ShouldNotBeNull();
Expand All @@ -70,20 +71,20 @@ public async Task Can_Manage_Todo_Items_With_Api()
item.Text.ShouldBe(text);

// Act - Mark the item as being completed
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { }, cancellationToken);

// Assert - The item was completed
completedResponse.StatusCode.ShouldBe(HttpStatusCode.NoContent);

item = await client.GetFromJsonAsync<TodoItemModel>(itemUri);
item = await client.GetFromJsonAsync<TodoItemModel>(itemUri, cancellationToken);

item.ShouldNotBeNull();
item.Id.ShouldBe(itemId);
item.Text.ShouldBe(text);
item.IsCompleted.ShouldBeTrue();

// Act - Get all the items
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items",cancellationToken);

// Assert - The item was completed
items.ShouldNotBeNull();
Expand All @@ -98,25 +99,25 @@ public async Task Can_Manage_Todo_Items_With_Api()
item.LastUpdated.ShouldNotBeNull();

// Act - Delete the item
using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, cancellationToken);

// Assert - The item no longer exists
deletedResponse.StatusCode.ShouldBe(HttpStatusCode.NoContent);

items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items", cancellationToken);

items.ShouldNotBeNull();
items.Items.ShouldNotBeNull();
items.Items.Count.ShouldBe(beforeCount);
items.Items.ShouldNotContain(x => x.Id == itemId);

// Act
using var getResponse = await client.GetAsync(itemUri);
using var getResponse = await client.GetAsync(itemUri, cancellationToken);

// Assert
getResponse.StatusCode.ShouldBe(HttpStatusCode.NotFound);

var problem = await getResponse.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await getResponse.Content.ReadFromJsonAsync<ProblemDetails>(cancellationToken);

problem.ShouldNotBeNull();
problem.Status.ShouldBe(StatusCodes.Status404NotFound);
Expand All @@ -130,16 +131,17 @@ public async Task Can_Manage_Todo_Items_With_Api()
public async Task Cannot_Create_Todo_Item_With_No_Text()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var client = await CreateAuthenticatedClientAsync();
var item = new CreateTodoItemModel { Text = string.Empty };

// Act
var response = await client.PostAsJsonAsync("/api/items", item);
var response = await client.PostAsJsonAsync("/api/items", item, cancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(cancellationToken);

problem.ShouldNotBeNull();
problem.Status.ShouldBe(StatusCodes.Status400BadRequest);
Expand All @@ -153,25 +155,26 @@ public async Task Cannot_Create_Todo_Item_With_No_Text()
public async Task Cannot_Complete_Todo_Item_Multiple_Times()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var client = await CreateAuthenticatedClientAsync();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, cancellationToken);
createdResponse.StatusCode.ShouldBe(HttpStatusCode.Created);
createdResponse.Headers.Location.ShouldNotBeNull();

var itemUri = createdResponse.Headers.Location;

using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { }, cancellationToken);
completedResponse.StatusCode.ShouldBe(HttpStatusCode.NoContent);

// Act
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { }, cancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(cancellationToken);

problem.ShouldNotBeNull();
problem.Status.ShouldBe(StatusCodes.Status400BadRequest);
Expand All @@ -185,25 +188,26 @@ public async Task Cannot_Complete_Todo_Item_Multiple_Times()
public async Task Cannot_Complete_Deleted_Todo_Item()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var client = await CreateAuthenticatedClientAsync();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, cancellationToken);
createdResponse.StatusCode.ShouldBe(HttpStatusCode.Created);
createdResponse.Headers.Location.ShouldNotBeNull();

var itemUri = createdResponse.Headers.Location;

using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, cancellationToken);
deletedResponse.StatusCode.ShouldBe(HttpStatusCode.NoContent);

// Act
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { }, cancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.NotFound);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(cancellationToken);

problem.ShouldNotBeNull();
problem.Status.ShouldBe(StatusCodes.Status404NotFound);
Expand All @@ -217,25 +221,26 @@ public async Task Cannot_Complete_Deleted_Todo_Item()
public async Task Cannot_Delete_Todo_Item_Multiple_Times()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var client = await CreateAuthenticatedClientAsync();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, cancellationToken);
createdResponse.StatusCode.ShouldBe(HttpStatusCode.Created);
createdResponse.Headers.Location.ShouldNotBeNull();

var itemUri = createdResponse.Headers.Location;

using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, cancellationToken);
deletedResponse.StatusCode.ShouldBe(HttpStatusCode.NoContent);

// Act
using var response = await client.DeleteAsync(itemUri);
using var response = await client.DeleteAsync(itemUri, cancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.NotFound);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(cancellationToken);

problem.ShouldNotBeNull();
problem.Status.ShouldBe(StatusCodes.Status404NotFound);
Expand Down
7 changes: 3 additions & 4 deletions tests/TodoApp.Tests/TodoApp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);CA1861</NoWarn>
<OutputType>Exe</OutputType>
<RootNamespace>TodoApp</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
Expand All @@ -10,16 +11,15 @@
<PackageReference Include="coverlet.msbuild" Version="6.0.2" PrivateAssets="All" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageReference Include="JustEat.HttpClientInterception" Version="5.0.0" />
<PackageReference Include="MartinCostello.Logging.XUnit" Version="0.4.0" />
<PackageReference Include="MartinCostello.Logging.XUnit.v3" Version="0.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.49.0" />
<PackageReference Include="ReportGenerator" Version="5.4.1" />
<PackageReference Include="Shouldly" Version="4.2.1" />
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" />
<PackageReference Include="Xunit.SkippableFact" Version="1.5.23" />
<PackageReference Include="xunit.v3" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<Content Include="oauth-http-bundle.json;xunit.runner.json;xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
Expand All @@ -31,7 +31,6 @@
<ItemGroup>
<Using Include="Shouldly" />
<Using Include="Xunit" />
<Using Include="Xunit.Abstractions" />
</ItemGroup>
<PropertyGroup>
<CollectCoverage>true</CollectCoverage>
Expand Down
14 changes: 9 additions & 5 deletions tests/TodoApp.Tests/UITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace TodoApp;

[Collection(HttpServerCollection.Name)]
[Collection<HttpServerCollection>]
public class UITests : IAsyncLifetime
{
public UITests(HttpServerFixture fixture, ITestOutputHelper outputHelper)
Expand Down Expand Up @@ -98,7 +98,7 @@ await browser.WithPageAsync(async page =>
await items[0].DeleteAsync();
await items[1].CompleteAsync();

await Task.Delay(TimeSpan.FromSeconds(0.5));
await Task.Delay(TimeSpan.FromSeconds(0.5), TestContext.Current.CancellationToken);

// Assert
items = await app.GetItemsAsync();
Expand All @@ -120,13 +120,17 @@ await browser.WithPageAsync(async page =>
});
}

public Task InitializeAsync()
public ValueTask InitializeAsync()
{
InstallPlaywright();
return Task.CompletedTask;
return ValueTask.CompletedTask;
}

public Task DisposeAsync() => Task.CompletedTask;
public ValueTask DisposeAsync()
{
GC.SuppressFinalize(this);
return ValueTask.CompletedTask;
}

private static void InstallPlaywright()
{
Expand Down
Loading