Skip to content

Commit

Permalink
Migrate to xunit v3
Browse files Browse the repository at this point in the history
Migrate tests to xunit v3.
  • Loading branch information
martincostello committed Dec 22, 2024
1 parent a41def2 commit b78435f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 35 deletions.
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

0 comments on commit b78435f

Please sign in to comment.