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

refactor: upgrade to xunit v3 #728

Merged
merged 11 commits into from
Jan 25, 2025
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
42 changes: 0 additions & 42 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,48 +67,6 @@ jobs:
./Artifacts/*
./TestResults/*.trx

mutation-tests-linux:
name: "Mutation tests (Linux)"
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
DOTNET_NOLOGO: true
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDKs
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Run mutation tests
run: ./build.sh MutationTestsLinux

mutation-tests-windows:
name: "Mutation tests (Windows)"
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: windows-latest
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
DOTNET_NOLOGO: true
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDKs
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Run mutation tests
run: ./build.ps1 MutationTestsWindows

static-code-analysis:
name: "Static code analysis"
runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"CodeAnalysisEnd",
"CodeCoverage",
"Compile",
"DotNetFrameworkUnitTests",
"DotNetUnitTests",
"MutationComment",
"MutationTestPreparation",
Expand Down
9 changes: 4 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1"/>
</ItemGroup>
<ItemGroup>
<PackageVersion Include="AutoFixture.AutoNSubstitute" Version="4.18.1"/>
<PackageVersion Include="AutoFixture.Xunit2" Version="4.18.1"/>
<PackageVersion Include="AutoFixture.AutoNSubstitute" Version="5.0.0-preview0012"/>
<PackageVersion Include="AutoFixture.Xunit3" Version="5.0.0-preview0012"/>
<PackageVersion Include="aweXpect" Version="0.17.0"/>
<PackageVersion Include="aweXpect.Testably" Version="0.3.0"/>
<PackageVersion Include="FluentAssertions" Version="7.0.0"/>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23"/>
<PackageVersion Include="xunit" Version="2.9.3"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2"/>
<PackageVersion Include="xunit.v3" Version="1.0.1"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1"/>
<PackageVersion Include="coverlet.collector" Version="6.0.4"/>
<PackageVersion Include="PublicApiGenerator" Version="11.3.0"/>
<PackageVersion Include="NUnit" Version="4.3.2"/>
Expand Down
2 changes: 1 addition & 1 deletion Pipeline/Build.Compile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ partial class Build
{
SemVer = GitVersion?.SemVer;

if (GitHubActions.IsPullRequest && GitVersion != null)
if (GitHubActions?.IsPullRequest == true && GitVersion != null)
{
string buildNumber = GitHubActions.RunNumber.ToString();
Console.WriteLine(
Expand Down
50 changes: 5 additions & 45 deletions Pipeline/Build.UnitTest.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using Nuke.Common;
using Nuke.Common.IO;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tooling;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.Xunit;
using Serilog;
using System;
using System.Linq;
using static Nuke.Common.Tools.Xunit.XunitTasks;
using static Nuke.Common.Tools.DotNet.DotNetTasks;

// ReSharper disable AllUnderscoreLocalParameterName
Expand All @@ -18,51 +15,15 @@ partial class Build
{
const int MaxRetries = 1;

Target DotNetFrameworkUnitTests => _ => _
.Unlisted()
.DependsOn(Compile)
.OnlyWhenDynamic(() => EnvironmentInfo.IsWin)
.Executes(() =>
{
string[] testAssemblies = UnitTestProjects
.SelectMany(project =>
project.Directory.GlobFiles(
$"bin/{(Configuration == Configuration.Debug ? "Debug" : "Release")}/net48/*.Tests.dll"))
.Select(p => p.ToString())
.ToArray();

Assert.NotEmpty(testAssemblies.ToList());

string net48 = "net48";
for (int retry = MaxRetries; retry >= 0; retry--)
{
try
{
Xunit2(s => s
.SetFramework(net48)
.AddTargetAssemblies(testAssemblies)
);
}
catch (Exception ex)
{
if (retry == 0)
{
Log.Error($"All {MaxRetries + 1} tries failed: {ex}");
throw;
}

Log.Error($"Error during unit tests: {ex}");
Log.Information($"Retry {MaxRetries - retry + 1} of {MaxRetries} times:");
}
}
});

Target DotNetUnitTests => _ => _
.Unlisted()
.DependsOn(Compile)
.Executes(() =>
{
string net48 = "net48";
string[] excludedFrameworks =
EnvironmentInfo.IsWin
? []
: ["net48"];
for (int retry = MaxRetries; retry >= 0; retry--)
{
try
Expand All @@ -78,7 +39,7 @@ partial class Build
(settings, project) => settings
.SetProjectFile(project)
.CombineWith(
project.GetTargetFrameworks()?.Except([net48]),
project.GetTargetFrameworks()?.Except(excludedFrameworks),
(frameworkSettings, framework) => frameworkSettings
.SetFramework(framework)
.AddLoggers(
Expand Down Expand Up @@ -111,6 +72,5 @@ partial class Build
];

Target UnitTests => _ => _
.DependsOn(DotNetFrameworkUnitTests)
.DependsOn(DotNetUnitTests);
}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
[![Build](https://github.com/Testably/Testably.Abstractions/actions/workflows/build.yml/badge.svg)](https://github.com/Testably/Testably.Abstractions/actions/workflows/build.yml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Testably_Testably.Abstractions&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Testably_Testably.Abstractions)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Testably_Testably.Abstractions&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Testably_Testably.Abstractions)
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.jparrowsec.cn%2FTestably%2FTestably.Abstractions%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/Testably/Testably.Abstractions/main)

This library is a feature complete testing helper for the [IFileSystem abstractions for I/O-related functionality](https://github.com/TestableIO/System.IO.Abstractions) from the `System.IO` namespace. It uses an in-memory file system that behaves exactly like the real file system and can be used in unit tests for dependency injection.
The testing helper also supports advanced scenarios like
Expand Down
6 changes: 3 additions & 3 deletions Tests/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<NoWarn>$(NoWarn);701;1702;CA1845;MA0003;MA0004;MA0018;MA0020;MA0042;MA0076;xUnit1044;xUnit1045;NU1603</NoWarn>
</PropertyGroup>

Expand All @@ -25,10 +26,9 @@
<ItemGroup>
<PackageReference Include="aweXpect" />
<PackageReference Include="aweXpect.Testably" />
<PackageReference Include="AutoFixture.Xunit2" />
<PackageReference Include="AutoFixture.Xunit3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Xunit.SkippableFact" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using AutoFixture;
using AutoFixture.Xunit2;
using AutoFixture.Xunit3;
using AutoFixture.AutoNSubstitute;
using System;
using System.Linq;
Expand All @@ -13,16 +13,16 @@ namespace Testably.Abstractions.TestHelpers;
public class AutoDomainDataAttribute : AutoDataAttribute
{
private Type? _customizeWith;
private readonly FixtureFactory _fixtureFactory;
private readonly DomainFixtureFactory _fixtureFactory;

/// <summary>
/// Extension of <see cref="AutoDataAttribute"/> that uses applies domain-specific customizations.
/// </summary>
public AutoDomainDataAttribute() : this(new FixtureFactory())
public AutoDomainDataAttribute() : this(new DomainFixtureFactory())
{
}

private AutoDomainDataAttribute(FixtureFactory fixtureFactory)
private AutoDomainDataAttribute(DomainFixtureFactory fixtureFactory)
: base(fixtureFactory.GetFixtureFactory)
{
_fixtureFactory = fixtureFactory;
Expand All @@ -44,7 +44,7 @@ public Type? CustomizeWith
}
}

private sealed class FixtureFactory
private sealed class DomainFixtureFactory
{
private ICustomization? _customizeWith;
private static Lazy<ICustomization[]> _domainCustomisation { get; } = new(Initialize);
Expand Down
53 changes: 53 additions & 0 deletions Tests/Helpers/Testably.Abstractions.TestHelpers/Skip.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Runtime.CompilerServices;

namespace Testably.Abstractions.TestHelpers
{

public static class Skip
{
public static void IfNot(bool condition,
[CallerArgumentExpression("condition")] string reason = "")
{
aweXpect.Skip.Unless(condition, reason);
}

public static void If(bool condition,
[CallerArgumentExpression("condition")] string reason = "")
{
aweXpect.Skip.When(condition, reason);
}
}
}

#if !NET6_0_OR_GREATER

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices
{
/// <summary>
/// Indicates that a parameter captures the expression passed for another parameter as a string.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="CallerArgumentExpressionAttribute" /> class.
/// </summary>
/// <param name="parameterName">The name of the parameter whose expression should be captured as a string.</param>
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}

/// <summary>
/// Gets the name of the parameter whose expression should be captured as a string.
/// </summary>
public string ParameterName { get; }
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<PropertyGroup>
<TargetFrameworks>$(TargetFrameworks);netstandard2.0</TargetFrameworks>
<IsTestProject>false</IsTestProject>
<OutputType>Library</OutputType>
</PropertyGroup>

<ItemGroup>
Expand All @@ -18,7 +19,7 @@
<PackageReference Include="FluentAssertions" />
<PackageReference Include="AutoFixture.AutoNSubstitute" />
<PackageReference Remove="Microsoft.NET.Test.Sdk" />
<PackageReference Remove="xunit" />
<PackageReference Remove="xunit.v3" />
<PackageReference Remove="xunit.runner.visualstudio" />
<PackageReference Remove="coverlet.collector" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public static string GenerateFileSystemTestClasses(ClassModel model)
using Testably.Abstractions.Testing.Initializer;
using Testably.Abstractions.TestHelpers;
using Testably.Abstractions.TestHelpers.Settings;
using Xunit.Abstractions;

namespace {{model.Namespace}}
{
Expand Down Expand Up @@ -116,12 +115,12 @@ public RealFileSystemTests(ITestOutputHelper testOutputHelper, TestSettingsFixtu
#if DEBUG
if (fixture.RealFileSystemTests != TestSettingStatus.AlwaysEnabled)
{
throw new Xunit.SkipException($"Tests against the real file system are {fixture.RealFileSystemTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.RealFileSystemTests.");
aweXpect.Skip.Test($"Tests against the real file system are {fixture.RealFileSystemTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.RealFileSystemTests.");
}
#else
if (fixture.RealFileSystemTests == TestSettingStatus.AlwaysDisabled)
{
throw new Xunit.SkipException($"Tests against the real file system are {fixture.RealFileSystemTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.RealFileSystemTests.");
aweXpect.Skip.Test($"Tests against the real file system are {fixture.RealFileSystemTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.RealFileSystemTests.");
}
#endif
_fixture = fixture;
Expand All @@ -136,24 +135,24 @@ public void Dispose()
#if DEBUG
/// <inheritdoc cref="{{model.Name}}.SkipIfBrittleTestsShouldBeSkipped(bool)" />
public override void SkipIfBrittleTestsShouldBeSkipped(bool condition = true)
=> Xunit.Skip.If(condition && _fixture.BrittleTests != TestSettingStatus.AlwaysEnabled,
=> aweXpect.Skip.When(condition && _fixture.BrittleTests != TestSettingStatus.AlwaysEnabled,
$"Brittle tests are {_fixture.BrittleTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.BrittleTests.");
#else
/// <inheritdoc cref="{{model.Name}}.SkipIfBrittleTestsShouldBeSkipped(bool)" />
public override void SkipIfBrittleTestsShouldBeSkipped(bool condition = true)
=> Xunit.Skip.If(condition && _fixture.BrittleTests == TestSettingStatus.AlwaysDisabled,
=> aweXpect.Skip.When(condition && _fixture.BrittleTests == TestSettingStatus.AlwaysDisabled,
$"Brittle tests are {_fixture.BrittleTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.BrittleTests.");
#endif

#if DEBUG
/// <inheritdoc cref="{{model.Name}}.LongRunningTestsShouldBeSkipped()" />
public override void SkipIfLongRunningTestsShouldBeSkipped()
=> Xunit.Skip.If(_fixture.LongRunningTests != TestSettingStatus.AlwaysEnabled,
=> aweXpect.Skip.When(_fixture.LongRunningTests != TestSettingStatus.AlwaysEnabled,
$"Long-running tests are {_fixture.LongRunningTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.LongRunningTests.");
#else
/// <inheritdoc cref="{{model.Name}}.LongRunningTestsShouldBeSkipped()" />
public override void SkipIfLongRunningTestsShouldBeSkipped()
=> Xunit.Skip.If(_fixture.LongRunningTests == TestSettingStatus.AlwaysDisabled,
=> aweXpect.Skip.When(_fixture.LongRunningTests == TestSettingStatus.AlwaysDisabled,
$"Long-running tests are {_fixture.LongRunningTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.LongRunningTests.");
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public static string GenerateRandomSystemTestClasses(ClassModel model)
StringBuilder? sb = GetSourceBuilder();
sb.AppendLine($$"""
using Testably.Abstractions.TestHelpers;
using Xunit.Abstractions;

namespace {{model.Namespace}}
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public static string GenerateTimeSystemTestClasses(ClassModel model)
sb.AppendLine($$"""
using Testably.Abstractions.TestHelpers;
using Testably.Abstractions.TestHelpers.Settings;
using Xunit.Abstractions;

namespace {{model.Namespace}}
{
Expand Down Expand Up @@ -77,12 +76,12 @@ public RealTimeSystemTests(TestSettingsFixture fixture) : base(new RealTimeSyste
#if DEBUG
/// <inheritdoc cref="{{model.Name}}.SkipIfBrittleTestsShouldBeSkipped(bool)" />
public override void SkipIfBrittleTestsShouldBeSkipped(bool condition = true)
=> Xunit.Skip.If(condition && _fixture.BrittleTests != TestSettingStatus.AlwaysEnabled,
=> aweXpect.Skip.When(condition && _fixture.BrittleTests != TestSettingStatus.AlwaysEnabled,
$"Brittle tests are {_fixture.BrittleTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.BrittleTests.");
#else
/// <inheritdoc cref="{{model.Name}}.SkipIfBrittleTestsShouldBeSkipped(bool)" />
public override void SkipIfBrittleTestsShouldBeSkipped(bool condition = true)
=> Xunit.Skip.If(condition && _fixture.BrittleTests == TestSettingStatus.AlwaysDisabled,
=> aweXpect.Skip.When(condition && _fixture.BrittleTests == TestSettingStatus.AlwaysDisabled,
$"Brittle tests are {_fixture.BrittleTests}. You can enable them by executing the corresponding tests in Testably.Abstractions.TestSettings.BrittleTests.");
#endif
}
Expand Down
Loading
Loading