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 #2969

Merged
merged 1 commit into from
Dec 21, 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
8 changes: 3 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Include="JustEat.HttpClientInterception" Version="5.0.0" />
<PackageVersion Include="MartinCostello.Logging.XUnit" Version="0.4.0" />
<PackageVersion Include="MartinCostello.Logging.XUnit.v3" Version="0.5.0" />
<PackageVersion Include="MartinCostello.OpenApi.Extensions" Version="1.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="9.0.0" />
Expand Down Expand Up @@ -55,10 +55,8 @@
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.2.0" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
<PackageVersion Include="Verify.Xunit" Version="28.6.1" />
<PackageVersion Include="xRetry" Version="1.9.0" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="Verify.XunitV3" Version="28.6.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
<PackageVersion Include="xunit.v3" Version="1.0.0" />
</ItemGroup>
</Project>
10 changes: 7 additions & 3 deletions tests/LondonTravel.Site.Tests/BrowserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,18 @@ public void Dispose()
}

/// <inheritdoc/>
public Task InitializeAsync()
public ValueTask InitializeAsync()
{
InstallPlaywright();
return Task.CompletedTask;
return ValueTask.CompletedTask;
}

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

/// <summary>
/// Runs the specified test with a new instance of <see cref="ApplicationNavigator"/> as an asynchronous operation.
Expand Down
10 changes: 5 additions & 5 deletions tests/LondonTravel.Site.Tests/EndToEnd/ApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@

namespace MartinCostello.LondonTravel.Site.EndToEnd;

[Collection(WebsiteCollection.Name)]
[Collection<WebsiteCollection>]
[Trait("Category", "EndToEnd")]
public class ApiTests(WebsiteFixture fixture)
{
[SkippableFact]
[Fact]
public async Task Cannot_Get_Preferences_Unauthenticated()
{
// Arrange
using var client = fixture.CreateClient();

// Act
using var response = await client.GetAsync("/api/preferences");
using var response = await client.GetAsync("/api/preferences", TestContext.Current.CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand All @@ -32,7 +32,7 @@ public async Task Cannot_Get_Preferences_Unauthenticated()
result.RootElement.GetStringArray("details").ShouldBeEmpty();
}

[SkippableFact]
[Fact]
public async Task Cannot_Get_Preferences_With_Invalid_Token()
{
// Arrange
Expand All @@ -42,7 +42,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Token()
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);

// Act
using var response = await client.GetAsync("/api/preferences");
using var response = await client.GetAsync("/api/preferences", TestContext.Current.CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd;
/// <summary>
/// The base class for end-to-end tests.
/// </summary>
[Collection(WebsiteCollection.Name)]
[Collection<WebsiteCollection>]
[Trait("Category", "EndToEnd")]
public abstract class BrowserEndToEndTest : BrowserTest
{
Expand Down
12 changes: 6 additions & 6 deletions tests/LondonTravel.Site.Tests/EndToEnd/ResourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

namespace MartinCostello.LondonTravel.Site.EndToEnd;

[Collection(WebsiteCollection.Name)]
[Collection<WebsiteCollection>]
[Trait("Category", "EndToEnd")]
public class ResourceTests(WebsiteFixture fixture)
{
[SkippableTheory]
[Theory]
[InlineData("/", MediaTypeNames.Text.Html)]
[InlineData("/.well-known/apple-app-site-association", MediaTypeNames.Application.Json)]
[InlineData("/.well-known/assetlinks.json", MediaTypeNames.Application.Json)]
Expand Down Expand Up @@ -49,16 +49,16 @@ public async Task Can_Load_Resource(string requestUri, string contentType)
using var client = fixture.CreateClient();

// Act
using var response = await client.GetAsync(requestUri);
using var response = await client.GetAsync(requestUri, TestContext.Current.CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync()}");
response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync(TestContext.Current.CancellationToken)}");
response.Content.Headers.ContentType?.MediaType.ShouldBe(contentType);
response.Content.Headers.ContentLength.ShouldNotBeNull();
response.Content.Headers.ContentLength.ShouldNotBe(0);
}

[SkippableFact]
[Fact]
public async Task Response_Headers_Contains_Expected_Headers()
{
// Arrange
Expand All @@ -81,7 +81,7 @@ public async Task Response_Headers_Contains_Expected_Headers()

// Act
using var client = fixture.CreateClient();
var response = await client.GetAsync("/");
var response = await client.GetAsync("/", TestContext.Current.CancellationToken);

// Assert
foreach (string expected in expectedHeaders)
Expand Down
16 changes: 8 additions & 8 deletions tests/LondonTravel.Site.Tests/EndToEnd/SocialLoginTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd;

public class SocialLoginTests(WebsiteFixture fixture, ITestOutputHelper outputHelper) : BrowserEndToEndTest(fixture, outputHelper)
{
[SkippableFact]
[Fact]
public async Task Can_Sign_In_With_Google()
{
Skip.IfNot(
Assert.SkipUnless(
string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")),
"Sign-in blocked when run in GitHub Actions.");

Expand All @@ -28,10 +28,10 @@ await SignInAsync(
});
}

[SkippableFact]
[Fact]
public async Task Can_Sign_In_With_Microsoft_Account()
{
Skip.IfNot(
Assert.SkipUnless(
string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")),
"Sign-in is being flaky in GitHub Actions.");

Expand All @@ -48,10 +48,10 @@ await SignInAsync(
});
}

[SkippableFact]
[Fact]
public async Task Can_Sign_In_With_Twitter()
{
Skip.IfNot(
Assert.SkipUnless(
string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")),
"Sign-in blocked when run in GitHub Actions.");

Expand All @@ -72,8 +72,8 @@ private async Task SignInWithSocialProviderAsync(string providerName, Func<IPage
string? userName = Environment.GetEnvironmentVariable($"WEBSITE_USER_{providerName.ToUpperInvariant()}_USERNAME");
string? password = Environment.GetEnvironmentVariable($"WEBSITE_USER_{providerName.ToUpperInvariant()}_PASSWORD");

Skip.If(string.IsNullOrWhiteSpace(userName), $"No {providerName} username is configured.");
Skip.If(string.IsNullOrWhiteSpace(password), $"No {providerName} password is configured.");
Assert.SkipWhen(string.IsNullOrWhiteSpace(userName), $"No {providerName} username is configured.");
Assert.SkipWhen(string.IsNullOrWhiteSpace(password), $"No {providerName} password is configured.");

// Arrange
await AtPageAsync<HomePage>(
Expand Down
2 changes: 1 addition & 1 deletion tests/LondonTravel.Site.Tests/EndToEnd/WebsiteFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public Uri ServerAddress
{
get
{
Skip.If(_serverAddress is null, $"The {WebsiteUrl} environment variable is not set or is not a valid absolute URI.");
Assert.SkipWhen(_serverAddress is null, $"The {WebsiteUrl} environment variable is not set or is not a valid absolute URI.");
return _serverAddress!;
}
}
Expand Down
18 changes: 9 additions & 9 deletions tests/LondonTravel.Site.Tests/Integration/AccountTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace MartinCostello.LondonTravel.Site.Integration;
/// </remarks>
/// <param name="fixture">The fixture to use.</param>
/// <param name="outputHelper">The <see cref="ITestOutputHelper"/> to use.</param>
[Collection(TestServerCollection.Name)]
[Collection<TestServerCollection>]
public class AccountTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper)
{
[Fact]
Expand Down Expand Up @@ -51,7 +51,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide
using var store = GetUserStore(scope.ServiceProvider);

// Act
var createResult = await store.CreateAsync(user, default);
var createResult = await store.CreateAsync(user, CancellationToken);

// Assert
Assert.NotNull(createResult);
Expand All @@ -63,7 +63,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide
userId = user.Id!;

// Act
var actual = await store.FindByIdAsync(userId, default);
var actual = await store.FindByIdAsync(userId, CancellationToken);

// Assert
Assert.NotNull(actual);
Expand All @@ -87,14 +87,14 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide
actual.FavoriteLines = favoriteLines;

// Act
var updateResult = await store.UpdateAsync(actual, default);
var updateResult = await store.UpdateAsync(actual, CancellationToken);

// Assert
Assert.NotNull(updateResult);
Assert.True(updateResult.Succeeded);

// Act
actual = await store.FindByNameAsync(emailAddress, default);
actual = await store.FindByNameAsync(emailAddress, CancellationToken);

// Assert
Assert.NotNull(actual);
Expand All @@ -112,7 +112,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide

// Act
using var client = Fixture.CreateClient();
using var response = await client.SendAsync(message);
using var response = await client.SendAsync(message, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.OK);
Expand All @@ -121,7 +121,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide
response.Content!.Headers!.ContentType.ShouldNotBeNull();
response.Content.Headers.ContentType!.MediaType.ShouldBe(MediaTypeNames.Application.Json);

string json = await response.Content.ReadAsStringAsync();
string json = await response.Content.ReadAsStringAsync(CancellationToken);
using var preferences = JsonDocument.Parse(json);

Assert.Equal(userId, preferences.RootElement.GetString("userId"));
Expand All @@ -134,7 +134,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide
using var store = GetUserStore(scope.ServiceProvider);

// Act
var updateResult = await store.DeleteAsync(new LondonTravelUser() { Id = userId }, default);
var updateResult = await store.DeleteAsync(new LondonTravelUser() { Id = userId }, CancellationToken);

// Assert
Assert.NotNull(updateResult);
Expand All @@ -148,7 +148,7 @@ static IUserStore<LondonTravelUser> GetUserStore(IServiceProvider serviceProvide

// Act
using var client = Fixture.CreateClient();
using var response = await client.SendAsync(message);
using var response = await client.SendAsync(message, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand Down
5 changes: 2 additions & 3 deletions tests/LondonTravel.Site.Tests/Integration/AlexaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using MartinCostello.LondonTravel.Site.Pages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection;
using xRetry;

namespace MartinCostello.LondonTravel.Site.Integration;

Expand All @@ -27,7 +26,7 @@ public AlexaTests(HttpServerFixture fixture, ITestOutputHelper outputHelper)
Fixture.Services!.GetRequiredService<InMemoryDocumentStore>().Clear();
}

[RetryTheory]
[Theory]
[ClassData(typeof(BrowsersTestData))]
public async Task Can_Authorize_Alexa(string browserType, string? browserChannel)
{
Expand All @@ -52,7 +51,7 @@ await WithNavigatorAsync(
});
}

[RetryTheory]
[Theory]
[ClassData(typeof(BrowsersTestData))]
public async Task Can_Get_Preferences_From_Api(string browserType, string? browserChannel)
{
Expand Down
16 changes: 8 additions & 8 deletions tests/LondonTravel.Site.Tests/Integration/ApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace MartinCostello.LondonTravel.Site.Integration;
/// </remarks>
/// <param name="fixture">The fixture to use.</param>
/// <param name="outputHelper">The <see cref="ITestOutputHelper"/> to use.</param>
[Collection(TestServerCollection.Name)]
[Collection<TestServerCollection>]
public class ApiTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper)
{
private const string Scheme = "bearer";
Expand All @@ -38,7 +38,7 @@ public async Task Cannot_Get_Preferences_Unauthenticated(string? value)
}

// Act
using var response = await client.GetAsync(RequestUri);
using var response = await client.GetAsync(RequestUri, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand All @@ -61,7 +61,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Token(string value)
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", value);

// Act
using var response = await client.GetAsync(RequestUri);
using var response = await client.GetAsync(RequestUri, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand All @@ -85,7 +85,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Scheme_Value(string value)
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(value, "token");

// Act
using var response = await client.GetAsync(RequestUri);
using var response = await client.GetAsync(RequestUri, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand All @@ -111,7 +111,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Parameter_Value(string val
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(Scheme, value);

// Act
using var response = await client.GetAsync(RequestUri);
using var response = await client.GetAsync(RequestUri, CancellationToken);

// Assert
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
Expand All @@ -137,11 +137,11 @@ public async Task Schema_Has_No_Validation_Warnings()
using var client = Fixture.CreateClient();

// Act
using var schema = await client.GetStreamAsync("/openapi/api.json");
using var schema = await client.GetStreamAsync("/openapi/api.json", CancellationToken);

// Assert
var reader = new OpenApiStreamReader();
var actual = await reader.ReadAsync(schema);
var actual = await reader.ReadAsync(schema, CancellationToken);

actual.OpenApiDiagnostic.Errors.ShouldBeEmpty();

Expand All @@ -159,7 +159,7 @@ public async Task Schema_Is_Correct()
using var client = Fixture.CreateClient();

// Act
string actual = await client.GetStringAsync("/openapi/api.json");
string actual = await client.GetStringAsync("/openapi/api.json", CancellationToken);

// Assert
await VerifyJson(actual, settings);
Expand Down
Loading
Loading