diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 9288b0ed..b1388c01 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-reportgenerator-globaltool": {
- "version": "5.5.10",
+ "version": "5.5.11",
"commands": [
"reportgenerator"
]
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 714fc385..d3f95295 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -71,9 +71,10 @@ jobs:
run: dotnet pack -c Release -p:PackageVersion=${{ env.APP_BUILD_VERSION }}
- name: Unit test
run: |
- dotnet test -p:PackageVersion=${{ env.APP_BUILD_VERSION }} test/TestLogger.UnitTests/TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
- dotnet test -p:PackageVersion=${{ env.APP_BUILD_VERSION }} test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
- dotnet test -p:PackageVersion=${{ env.APP_BUILD_VERSION }} test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
+ dotnet run -p:PackageVersion=${{ env.APP_BUILD_VERSION }} --project test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*"
+ dotnet run -p:PackageVersion=${{ env.APP_BUILD_VERSION }} --project test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*"
+ dotnet run -p:PackageVersion=${{ env.APP_BUILD_VERSION }} --project test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*"
+ dotnet run -p:PackageVersion=${{ env.APP_BUILD_VERSION }} --project test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*"
- name: Acceptance test
run: |
echo "Running acceptance tests with verbose output..."
@@ -93,16 +94,16 @@ jobs:
**/test-results-*.xml
**/test-results-*.json
**/*.log
- test/assets/**/bin/Debug/net8.0/
- test/assets/**/bin/Debug/net10.0/
+ test/assets/**/bin/Debug/mtp/
+ test/assets/**/bin/Debug/vstest/
- name: Codecov
uses: codecov/codecov-action@v3.1.0
with:
- files: test/TestLogger.UnitTests/coverage.opencover.xml
+ files: test/TestLogger.VSTest.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml,test/TestLogger.Mtp.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml,test/NUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml,test/JUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml
- name: Publish packages
if: ${{ github.event_name == 'push' && matrix.os != 'windows-latest' }}
run: |
- dotnet nuget push 'src/TestLogger/bin/Release/*.nupkg' --api-key ${{ secrets.SPEKT_MYGET_KEY }} --source https://www.myget.org/F/spekt/api/v3/index.json
+ dotnet nuget push 'src/TestLogger/bin/Release/*/*.nupkg' --api-key ${{ secrets.SPEKT_MYGET_KEY }} --source https://www.myget.org/F/spekt/api/v3/index.json
dotnet nuget push 'src/Xunit.Xml.Package/bin/Release/*.nupkg' --api-key ${{ secrets.SPEKT_MYGET_KEY }} --source https://www.myget.org/F/spekt/api/v3/index.json
dotnet nuget push 'src/NUnit.Xml.Package/bin/Release/*.nupkg' --api-key ${{ secrets.SPEKT_MYGET_KEY }} --source https://www.myget.org/F/spekt/api/v3/index.json
dotnet nuget push 'src/JUnit.Xml.Package/bin/Release/*.nupkg' --api-key ${{ secrets.SPEKT_MYGET_KEY }} --source https://www.myget.org/F/spekt/api/v3/index.json
diff --git a/.gitignore b/.gitignore
index 21bdf5b8..32436ce9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,6 +141,7 @@ _TeamCity*
*.coveragexml
coverage.json
coverage.opencover.xml
+coveragereport/
# NCrunch
_NCrunch_*
@@ -344,4 +345,4 @@ site
.vscode/settings.json
*.received.txt
-global.json
\ No newline at end of file
+global.json
diff --git a/Directory.Build.props b/Directory.Build.props
index 67622614..269709e4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,7 +1,7 @@
$(MSBuildThisFileDirectory)
- 8.0.0
+ 8.1.0
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 4699c54c..1d8fbb15 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -18,6 +18,7 @@
-
+
+
diff --git a/build.ps1 b/build.ps1
index 27d9d8fa..afefb00a 100644
--- a/build.ps1
+++ b/build.ps1
@@ -1,20 +1,15 @@
-$locals = dotnet nuget locals all -l
-ForEach ($local in $($locals -split "`r`n"))
-{
- $local = $local.Substring($local.IndexOf(":") + 2)
- "Deleting from $local"
- dotnet nuget delete Json.TestLogger 4.0.0-dev --force-english-output --non-interactive -s $local
-}
-
-Remove-Item .\test\package\bin\ -Recurse
-Remove-Item .\test\package\obj\ -Recurse
-
dotnet pack
if ($?) {
- dotnet test test/TestLogger.UnitTests/TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
- dotnet test test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
- dotnet test test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover
+ dotnet run --project test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*"
+ dotnet run --project test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*"
+ dotnet run --project test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*"
+ dotnet run --project test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*"
+}
+if ($?) {
+ dotnet tool restore
+ dotnet reportgenerator -reports:"test/TestLogger.VSTest.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/TestLogger.Mtp.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/NUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/JUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml" -targetdir:coveragereport -reporttypes:"TextSummary;Html"
+ Get-Content coveragereport/Summary.txt
}
if ($?) {
dotnet test test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj
diff --git a/build.sh b/build.sh
index 54692235..9fc4cb34 100755
--- a/build.sh
+++ b/build.sh
@@ -2,9 +2,13 @@
# vi: set tw=0
dotnet pack &&\
-dotnet test test/TestLogger.UnitTests/TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover &&\
-dotnet test test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover &&\
-dotnet test test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -p:CollectCoverage=true -p:CoverletOutputFormat=opencover &&\
+dotnet run --project test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" &&\
+dotnet run --project test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" &&\
+dotnet run --project test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*" &&\
+dotnet run --project test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj -- --coverlet --coverlet-output-format cobertura --coverlet-include "[Spekt*]*" --coverlet-include "[Microsoft.VisualStudio.TestPlatform.Extension*]*" &&\
+dotnet tool restore &&\
+dotnet reportgenerator -reports:"test/TestLogger.VSTest.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/TestLogger.Mtp.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/NUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml;test/JUnit.Xml.TestLogger.UnitTests/bin/Debug/net10.0/TestResults/coverage.cobertura.xml" -targetdir:coveragereport -reporttypes:"TextSummary;Html" &&\
+cat coveragereport/Summary.txt &&\
dotnet test test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj &&\
dotnet test test/TestLogger.PackageTests/TestLogger.PackageTests.csproj &&\
dotnet test test/Xunit.Xml.TestLogger.AcceptanceTests/Xunit.Xml.TestLogger.AcceptanceTests.csproj &&\
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index c11b75d4..86f000b2 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,4 +1,30 @@
+
+
+
+ Debug
+
+
+
+
+ bin\$(Configuration)\mtp\
+ obj\mtp\
+ true
+ false
+ $(DefaultItemExcludes);obj\vstest\**
+
+
+
+
+ bin\$(Configuration)\vstest\
+ obj\vstest\
+ $(DefaultItemExcludes);obj\mtp\**
+
-
\ No newline at end of file
+
diff --git a/src/JUnit.Xml.Package/JUnit.Xml.Package.csproj b/src/JUnit.Xml.Package/JUnit.Xml.Package.csproj
index b8357e29..bfb16965 100644
--- a/src/JUnit.Xml.Package/JUnit.Xml.Package.csproj
+++ b/src/JUnit.Xml.Package/JUnit.Xml.Package.csproj
@@ -38,9 +38,13 @@
false
-
-
-
+
+
+
+
+
+
+
@@ -63,10 +67,14 @@
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/JUnit.Xml.Package/JUnitXml.TestLogger.nuspec b/src/JUnit.Xml.Package/JUnitXml.TestLogger.nuspec
index f9265f4a..19bcd13a 100644
--- a/src/JUnit.Xml.Package/JUnitXml.TestLogger.nuspec
+++ b/src/JUnit.Xml.Package/JUnitXml.TestLogger.nuspec
@@ -13,10 +13,12 @@
packageIcon.png
-
-
+
+
+
+
-
+
diff --git a/src/JUnit.Xml.Package/JUnitXml.TestLogger.props b/src/JUnit.Xml.Package/JUnitXml.TestLogger.props
index 9c0f3389..925b3eb8 100644
--- a/src/JUnit.Xml.Package/JUnitXml.TestLogger.props
+++ b/src/JUnit.Xml.Package/JUnitXml.TestLogger.props
@@ -1,20 +1,20 @@
-
- Microsoft.VisualStudio.TestPlatform.Extension.JUnit.Xml.TestLogger.dll
+
+ Spekt.TestLogger.VSTest.dll
PreserveNewest
False
-
- Spekt.TestLogger.dll
+
+ Microsoft.VisualStudio.TestPlatform.Extension.JUnit.Xml.TestLogger.dll
PreserveNewest
False
-
-
+
+
JUnitXml.TestLogger
diff --git a/src/JUnit.Xml.TestLogger/Assembly.cs b/src/JUnit.Xml.TestLogger/Assembly.cs
index 045acdab..de2310f7 100644
--- a/src/JUnit.Xml.TestLogger/Assembly.cs
+++ b/src/JUnit.Xml.TestLogger/Assembly.cs
@@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
+#if !DEBUG
[assembly: ExcludeFromCodeCoverage]
namespace System.Diagnostics.CodeAnalysis;
@@ -15,4 +16,5 @@ namespace System.Diagnostics.CodeAnalysis;
internal sealed class ExcludeFromCodeCoverageAttribute : Attribute
{
public ExcludeFromCodeCoverageAttribute() { }
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.MTP.csproj b/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.MTP.csproj
new file mode 100644
index 00000000..fdef8139
--- /dev/null
+++ b/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.MTP.csproj
@@ -0,0 +1,28 @@
+
+
+
+ netstandard2.0
+ Microsoft.VisualStudio.TestPlatform.Extension.JUnit.Xml.TestLogger
+ false
+ false
+ true
+ false
+
+
+
+ Microsoft.VisualStudio.TestPlatform.Extension.JUnit.Xml.TestLogger
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.csproj b/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.VSTest.csproj
similarity index 58%
rename from src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.csproj
rename to src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.VSTest.csproj
index 70c8749b..f30c871f 100644
--- a/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.csproj
+++ b/src/JUnit.Xml.TestLogger/JUnit.Xml.TestLogger.VSTest.csproj
@@ -4,6 +4,7 @@
netstandard2.0
Microsoft.VisualStudio.TestPlatform.Extension.JUnit.Xml.TestLogger
false
+ false
@@ -11,10 +12,17 @@
-
+
+
+
+
-
+
+
+
+
+
diff --git a/src/JUnit.Xml.TestLogger/JUnitTestReporter.cs b/src/JUnit.Xml.TestLogger/JUnitTestReporter.cs
index 48b13803..98ef20e1 100644
--- a/src/JUnit.Xml.TestLogger/JUnitTestReporter.cs
+++ b/src/JUnit.Xml.TestLogger/JUnitTestReporter.cs
@@ -6,6 +6,7 @@ namespace Spekt.TestReporter.JUnit
using System;
using Microsoft.VisualStudio.TestPlatform.Extension.Junit.Xml.TestLogger;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp;
internal sealed class JUnitTestReporter : TestReporter
{
diff --git a/src/JUnit.Xml.TestLogger/JUnitTestReporterExtensions.cs b/src/JUnit.Xml.TestLogger/JUnitTestReporterExtensions.cs
index c47c0b99..d69f6eb0 100644
--- a/src/JUnit.Xml.TestLogger/JUnitTestReporterExtensions.cs
+++ b/src/JUnit.Xml.TestLogger/JUnitTestReporterExtensions.cs
@@ -5,6 +5,7 @@ namespace Spekt.TestReporter.JUnit
{
using Microsoft.Testing.Platform.Builder;
using Microsoft.Testing.Platform.Extensions;
+ using Spekt.TestLogger.Mtp;
public static class JUnitTestReporterExtensions
{
diff --git a/src/JUnit.Xml.TestLogger/JUnitXmlTestLogger.cs b/src/JUnit.Xml.TestLogger/JUnitXmlTestLogger.cs
index b04c00b5..c71ed98f 100644
--- a/src/JUnit.Xml.TestLogger/JUnitXmlTestLogger.cs
+++ b/src/JUnit.Xml.TestLogger/JUnitXmlTestLogger.cs
@@ -4,7 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.Extension.Junit.Xml.TestLogger
{
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Spekt.TestLogger;
+ using Spekt.TestLogger.VSTest;
[FriendlyName(FriendlyName)]
[ExtensionUri(ExtensionUri)]
diff --git a/src/JUnit.Xml.TestLogger/JunitXmlSerializer.cs b/src/JUnit.Xml.TestLogger/JunitXmlSerializer.cs
index 4389b3a5..44d01b21 100644
--- a/src/JUnit.Xml.TestLogger/JunitXmlSerializer.cs
+++ b/src/JUnit.Xml.TestLogger/JunitXmlSerializer.cs
@@ -10,8 +10,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Extension.Junit.Xml.TestLogger
using System.Linq;
using System.Text;
using System.Xml.Linq;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.Utilities;
diff --git a/src/NUnit.Xml.Package/NUnit.Xml.Package.csproj b/src/NUnit.Xml.Package/NUnit.Xml.Package.csproj
index 04ee3816..e5086d40 100644
--- a/src/NUnit.Xml.Package/NUnit.Xml.Package.csproj
+++ b/src/NUnit.Xml.Package/NUnit.Xml.Package.csproj
@@ -35,9 +35,13 @@
packageIcon.png
-
-
-
+
+
+
+
+
+
+
@@ -60,6 +64,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/NUnit.Xml.Package/NUnitXml.TestLogger.nuspec b/src/NUnit.Xml.Package/NUnitXml.TestLogger.nuspec
index 00467fd2..29712e46 100644
--- a/src/NUnit.Xml.Package/NUnitXml.TestLogger.nuspec
+++ b/src/NUnit.Xml.Package/NUnitXml.TestLogger.nuspec
@@ -13,12 +13,14 @@
packageIcon.png
-
-
+
+
+
+
-
+
diff --git a/src/NUnit.Xml.Package/NUnitXml.TestLogger.props b/src/NUnit.Xml.Package/NUnitXml.TestLogger.props
index c8a0844a..2f6a5cfe 100644
--- a/src/NUnit.Xml.Package/NUnitXml.TestLogger.props
+++ b/src/NUnit.Xml.Package/NUnitXml.TestLogger.props
@@ -1,20 +1,20 @@
-
- Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger.dll
+
+ Spekt.TestLogger.VSTest.dll
PreserveNewest
False
-
- Spekt.TestLogger.dll
+
+ Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger.dll
PreserveNewest
False
-
-
+
+
NUnitXml.TestLogger
diff --git a/src/NUnit.Xml.TestLogger/Assembly.cs b/src/NUnit.Xml.TestLogger/Assembly.cs
index 9f5b1d02..114fad9f 100644
--- a/src/NUnit.Xml.TestLogger/Assembly.cs
+++ b/src/NUnit.Xml.TestLogger/Assembly.cs
@@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
+#if !DEBUG
[assembly: ExcludeFromCodeCoverage]
namespace System.Diagnostics.CodeAnalysis;
@@ -15,4 +16,5 @@ namespace System.Diagnostics.CodeAnalysis;
internal sealed class ExcludeFromCodeCoverageAttribute : Attribute
{
public ExcludeFromCodeCoverageAttribute() { }
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.MTP.csproj b/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.MTP.csproj
new file mode 100644
index 00000000..912f4c24
--- /dev/null
+++ b/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.MTP.csproj
@@ -0,0 +1,28 @@
+
+
+
+ netstandard2.0
+ Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger
+ false
+ false
+ true
+ false
+
+
+
+ Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.csproj b/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.VSTest.csproj
similarity index 58%
rename from src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.csproj
rename to src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.VSTest.csproj
index 53f7fe2d..41624715 100644
--- a/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.csproj
+++ b/src/NUnit.Xml.TestLogger/NUnit.Xml.TestLogger.VSTest.csproj
@@ -4,6 +4,7 @@
netstandard2.0
Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger
false
+ false
@@ -11,11 +12,18 @@
-
+
-
+
+
+
+
+
+
+
+
diff --git a/src/NUnit.Xml.TestLogger/NUnitTestReporter.cs b/src/NUnit.Xml.TestLogger/NUnitTestReporter.cs
index 36b29f24..6b3a608b 100644
--- a/src/NUnit.Xml.TestLogger/NUnitTestReporter.cs
+++ b/src/NUnit.Xml.TestLogger/NUnitTestReporter.cs
@@ -6,6 +6,7 @@ namespace Spekt.TestReporter.NUnit
using System;
using Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp;
internal sealed class NUnitTestReporter : TestReporter
{
diff --git a/src/NUnit.Xml.TestLogger/NUnitTestReporterExtensions.cs b/src/NUnit.Xml.TestLogger/NUnitTestReporterExtensions.cs
index 9e98467d..c27ec209 100644
--- a/src/NUnit.Xml.TestLogger/NUnitTestReporterExtensions.cs
+++ b/src/NUnit.Xml.TestLogger/NUnitTestReporterExtensions.cs
@@ -5,6 +5,7 @@ namespace Spekt.TestReporter.NUnit
{
using Microsoft.Testing.Platform.Builder;
using Microsoft.Testing.Platform.Extensions;
+ using Spekt.TestLogger.Mtp;
public static class NUnitTestReporterExtensions
{
diff --git a/src/NUnit.Xml.TestLogger/NUnitXmlSerializer.cs b/src/NUnit.Xml.TestLogger/NUnitXmlSerializer.cs
index fe4e4992..6d6cdaf9 100644
--- a/src/NUnit.Xml.TestLogger/NUnitXmlSerializer.cs
+++ b/src/NUnit.Xml.TestLogger/NUnitXmlSerializer.cs
@@ -10,7 +10,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger
using System.Linq;
using System.Text;
using System.Xml.Linq;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.Utilities;
diff --git a/src/NUnit.Xml.TestLogger/NUnitXmlTestLogger.cs b/src/NUnit.Xml.TestLogger/NUnitXmlTestLogger.cs
index 6bacf043..2248c804 100644
--- a/src/NUnit.Xml.TestLogger/NUnitXmlTestLogger.cs
+++ b/src/NUnit.Xml.TestLogger/NUnitXmlTestLogger.cs
@@ -4,7 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.Extension.NUnit.Xml.TestLogger
{
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Spekt.TestLogger;
+ using Spekt.TestLogger.VSTest;
[FriendlyName(FriendlyName)]
[ExtensionUri(ExtensionUri)]
diff --git a/src/TestLogger.MTPv1/TestLogger.MTPv1.csproj b/src/TestLogger.MTPv1/TestLogger.MTPv1.csproj
index 4178efef..bb6d2098 100644
--- a/src/TestLogger.MTPv1/TestLogger.MTPv1.csproj
+++ b/src/TestLogger.MTPv1/TestLogger.MTPv1.csproj
@@ -16,11 +16,10 @@
-
+
-
diff --git a/src/TestLogger/Assembly.cs b/src/TestLogger/Assembly.cs
index 7dae9107..17a26c52 100644
--- a/src/TestLogger/Assembly.cs
+++ b/src/TestLogger/Assembly.cs
@@ -10,7 +10,9 @@
[assembly: InternalsVisibleTo("Json.TestLogger, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e5cffe1b79f1b3f91edadf0ed6fc7fd90592aa75f11277304acf23944d793e8ee57cfc38d0d16008fa2ffed1b09ccdde1c4291ca385c8234a85f08298fe4af491e57643200680d5a3a964d67882c8b03abd7d31c6978b59cb26217134b852ddd114e8b3f4da9ee5ad18a7be202af99529dfb34cd9dcde0a5923c65ca4e6aafa5")]
[assembly: InternalsVisibleTo("Json.TestAdapter, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e5cffe1b79f1b3f91edadf0ed6fc7fd90592aa75f11277304acf23944d793e8ee57cfc38d0d16008fa2ffed1b09ccdde1c4291ca385c8234a85f08298fe4af491e57643200680d5a3a964d67882c8b03abd7d31c6978b59cb26217134b852ddd114e8b3f4da9ee5ad18a7be202af99529dfb34cd9dcde0a5923c65ca4e6aafa5")]
-[assembly: InternalsVisibleTo("TestLogger.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e5cffe1b79f1b3f91edadf0ed6fc7fd90592aa75f11277304acf23944d793e8ee57cfc38d0d16008fa2ffed1b09ccdde1c4291ca385c8234a85f08298fe4af491e57643200680d5a3a964d67882c8b03abd7d31c6978b59cb26217134b852ddd114e8b3f4da9ee5ad18a7be202af99529dfb34cd9dcde0a5923c65ca4e6aafa5")]
+[assembly: InternalsVisibleTo("TestLogger.VSTest.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e5cffe1b79f1b3f91edadf0ed6fc7fd90592aa75f11277304acf23944d793e8ee57cfc38d0d16008fa2ffed1b09ccdde1c4291ca385c8234a85f08298fe4af491e57643200680d5a3a964d67882c8b03abd7d31c6978b59cb26217134b852ddd114e8b3f4da9ee5ad18a7be202af99529dfb34cd9dcde0a5923c65ca4e6aafa5")]
+[assembly: InternalsVisibleTo("TestLogger.Mtp.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e5cffe1b79f1b3f91edadf0ed6fc7fd90592aa75f11277304acf23944d793e8ee57cfc38d0d16008fa2ffed1b09ccdde1c4291ca385c8234a85f08298fe4af491e57643200680d5a3a964d67882c8b03abd7d31c6978b59cb26217134b852ddd114e8b3f4da9ee5ad18a7be202af99529dfb34cd9dcde0a5923c65ca4e6aafa5")]
+#if !DEBUG
[assembly: ExcludeFromCodeCoverage]
namespace System.Diagnostics.CodeAnalysis;
@@ -19,4 +21,5 @@ namespace System.Diagnostics.CodeAnalysis;
internal sealed class ExcludeFromCodeCoverageAttribute : Attribute
{
public ExcludeFromCodeCoverageAttribute() { }
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/TestLogger/Core/DefaultLoggerParameterNames.cs b/src/TestLogger/Core/DefaultLoggerParameterNames.cs
new file mode 100644
index 00000000..bd56b369
--- /dev/null
+++ b/src/TestLogger/Core/DefaultLoggerParameterNames.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Core
+{
+ ///
+ /// Default logger parameter names.
+ ///
+ public static class DefaultLoggerParameterNames
+ {
+ ///
+ /// Test run directory parameter name.
+ ///
+ public const string TestRunDirectory = "TestRunDirectory";
+ }
+}
diff --git a/src/TestLogger/Core/ITestRun.cs b/src/TestLogger/Core/ITestRun.cs
index d0372d2c..a1b629a1 100644
--- a/src/TestLogger/Core/ITestRun.cs
+++ b/src/TestLogger/Core/ITestRun.cs
@@ -3,16 +3,13 @@
namespace Spekt.TestLogger.Core
{
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.Platform;
public interface ITestRun
{
- LoggerConfiguration LoggerConfiguration { get; }
+ LoggerConfiguration LoggerConfiguration { get; set; }
- TestRunConfiguration RunConfiguration { get; }
-
- ITestAdapterFactory AdapterFactory { get; }
+ TestRunConfiguration RunConfiguration { get; set; }
ITestResultStore Store { get; }
diff --git a/src/TestLogger/Core/ITestRunBuilder.cs b/src/TestLogger/Core/ITestRunBuilder.cs
index 53df7105..5174eac1 100644
--- a/src/TestLogger/Core/ITestRunBuilder.cs
+++ b/src/TestLogger/Core/ITestRunBuilder.cs
@@ -3,7 +3,6 @@
namespace Spekt.TestLogger.Core
{
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Spekt.TestLogger.Platform;
public interface ITestRunBuilder
@@ -14,11 +13,6 @@ public interface ITestRunBuilder
ITestRunBuilder WithSerializer(ITestResultSerializer serializer);
- // TODO: Should ITestRunBuilder be platform-agnostic?
- // TestLoggerEvents is VSTest-specific.
- // It may be good to refactor this so that ITestRunBuilder is platform-agnostic, and move this somewhere else.
- ITestRunBuilder Subscribe(TestLoggerEvents loggerEvents);
-
ITestRunBuilder WithFileSystem(IFileSystem fileSystem);
ITestRunBuilder WithConsoleOutput(IConsoleOutput consoleOutput);
diff --git a/src/TestLogger/Core/LoggerConfiguration.cs b/src/TestLogger/Core/LoggerConfiguration.cs
index d24c1729..f8ad68c0 100644
--- a/src/TestLogger/Core/LoggerConfiguration.cs
+++ b/src/TestLogger/Core/LoggerConfiguration.cs
@@ -6,7 +6,6 @@ namespace Spekt.TestLogger.Core
using System;
using System.Collections.Generic;
using System.IO;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
///
/// Logger configuration provided by the test platform and command line
diff --git a/src/TestLogger/Core/TestCaseNameParser.cs b/src/TestLogger/Core/TestCaseNameParser.cs
index d9d60cb6..f3652773 100644
--- a/src/TestLogger/Core/TestCaseNameParser.cs
+++ b/src/TestLogger/Core/TestCaseNameParser.cs
@@ -5,10 +5,12 @@ namespace Spekt.TestLogger.Core
{
using System;
using System.Text.RegularExpressions;
- using Microsoft.Testing.Platform.Extensions.Messages;
using Spekt.TestLogger.Platform;
- public class TestCaseNameParser
+ ///
+ /// Parses test case names.
+ ///
+ public partial class TestCaseNameParser
{
public const string TestCaseParserUnknownNamespace = "UnknownNamespace";
public const string TestCaseParserUnknownType = "UnknownType";
@@ -43,104 +45,6 @@ public TestCaseNameParser(IConsoleOutput consoleOutput)
this.consoleOutput = consoleOutput ?? throw new ArgumentNullException(nameof(consoleOutput));
}
- ///
- /// This method parses the TestMethodIdentifierProperty from MTP to extract Namespace, Type and Method name.
- /// MTP sometimes provides the full type name in the Namespace property, so this method handles that case.
- ///
- /// The TestMethodIdentifierProperty from MTP.
- ///
- /// An instance of ParsedName containing the parsed results.
- ///
- public ParsedName Parse(TestMethodIdentifierProperty methodIdentifier)
- {
- if (methodIdentifier == null)
- {
- return new ParsedName(
- TestCaseParserUnknownNamespace,
- TestCaseParserUnknownType,
- string.Empty);
- }
-
- string @namespace = methodIdentifier.Namespace;
- string type = methodIdentifier.TypeName;
- string method = methodIdentifier.MethodName;
-
- // Check if the namespace contains the type name (the problematic case e.g. XUnit)
- // This happens when MTP's Namespace property contains the full type name
- if (!string.IsNullOrEmpty(@namespace) && !string.IsNullOrEmpty(type))
- {
- // NEW CASE: Type contains the full namespace + class name
- // If type contains the namespace, extract the actual class name
- if (type.StartsWith(@namespace + "."))
- {
- type = type.Substring(@namespace.Length + 1);
- }
-
- // If namespace ends with the type name, extract the actual namespace
- else if (@namespace.EndsWith("." + type))
- {
- @namespace = @namespace.Substring(0, @namespace.Length - type.Length - 1);
- }
-
- // If namespace equals the type name, it's a global namespace
- else if (@namespace == type)
- {
- @namespace = string.Empty;
- }
- }
-
- return new ParsedName(
- @namespace ?? string.Empty,
- type ?? string.Empty,
- method ?? string.Empty);
- }
-
- ///
- /// This method parses test information from either a TestMethodIdentifierProperty or TestNode.
- /// When TestMethodIdentifierProperty is provided, it handles MTP-specific parsing where the Type field
- /// may contain the full namespace + class name. When TestMethodIdentifierProperty is null, it falls back
- /// to parsing the TestNode's UID for test frameworks like NUnit that don't emit TestMethodIdentifierProperty.
- ///
- /// The TestMethodIdentifierProperty from MTP (can be null).
- /// The TestNode to use for fallback parsing (can be null).
- ///
- /// A tuple containing the parsed namespace, type, method, and fully qualified name.
- ///
- public (string Namespace, string Type, string Method, string FullyQualifiedName) Parse(TestMethodIdentifierProperty methodIdentifier, TestNode testNode)
- {
- if (methodIdentifier != null)
- {
- var parsedName = this.Parse(methodIdentifier);
- var fqn = string.IsNullOrEmpty(parsedName.Namespace)
- ? $"{parsedName.Type}.{parsedName.Method}"
- : $"{parsedName.Namespace}.{parsedName.Type}.{parsedName.Method}";
-
- return (parsedName.Namespace, parsedName.Type, parsedName.Method, fqn);
- }
- else if (testNode != null)
- {
- // Fallback to parsing the TestNode's UID (e.g. for NUnit since it doesn't emit TestMethodIdentifierProperty)
- var displayName = testNode.Uid;
- var parsedName = this.Parse(displayName);
-
- if (parsedName.Namespace != TestCaseParserUnknownNamespace)
- {
- // Successfully parsed the display name
- return (parsedName.Namespace, parsedName.Type, parsedName.Method, displayName);
- }
- else
- {
- // Could not parse the display name, use Unknown values
- return ("UnknownNamespace", "UnknownType", "UnknownMethod", "UnknownFullyQualifiedName");
- }
- }
- else
- {
- // Neither methodIdentifier nor testNode provided
- return ("UnknownNamespace", "UnknownType", "UnknownMethod", "UnknownFullyQualifiedName");
- }
- }
-
///
/// This method attempts to parse out a Namespace, Type and Method name from a given string.
/// When a clearly invalid output is encountered, a message is written to the console.
diff --git a/src/TestLogger/Core/TestMessageInfo.cs b/src/TestLogger/Core/TestMessageInfo.cs
index 344fd981..83233d4f 100644
--- a/src/TestLogger/Core/TestMessageInfo.cs
+++ b/src/TestLogger/Core/TestMessageInfo.cs
@@ -4,7 +4,6 @@
namespace Spekt.TestLogger.Core
{
using System;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
///
/// A message generated during the test run.
diff --git a/src/TestLogger/Core/TestMessageLevel.cs b/src/TestLogger/Core/TestMessageLevel.cs
new file mode 100644
index 00000000..1f91cd6a
--- /dev/null
+++ b/src/TestLogger/Core/TestMessageLevel.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Core
+{
+ ///
+ /// Represents the level of a test message.
+ ///
+ public enum TestMessageLevel
+ {
+ ///
+ /// Informational message.
+ ///
+ Informational = 0,
+
+ ///
+ /// Warning message.
+ ///
+ Warning = 1,
+
+ ///
+ /// Error message.
+ ///
+ Error = 2
+ }
+}
diff --git a/src/TestLogger/Core/TestOutcome.cs b/src/TestLogger/Core/TestOutcome.cs
new file mode 100644
index 00000000..73b9509f
--- /dev/null
+++ b/src/TestLogger/Core/TestOutcome.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Core
+{
+ ///
+ /// Represents the outcome of a test.
+ ///
+ public enum TestOutcome
+ {
+ ///
+ /// Test outcome is none.
+ ///
+ None = 0,
+
+ ///
+ /// Test passed.
+ ///
+ Passed = 1,
+
+ ///
+ /// Test failed.
+ ///
+ Failed = 2,
+
+ ///
+ /// Test was skipped.
+ ///
+ Skipped = 3,
+
+ ///
+ /// Test was not found.
+ ///
+ NotFound = 4
+ }
+}
diff --git a/src/TestLogger/Core/TestResultInfo.cs b/src/TestLogger/Core/TestResultInfo.cs
index 0585f1c0..742bf9f3 100644
--- a/src/TestLogger/Core/TestResultInfo.cs
+++ b/src/TestLogger/Core/TestResultInfo.cs
@@ -5,7 +5,6 @@ namespace Spekt.TestLogger.Core
{
using System;
using System.Collections.Generic;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
public sealed class TestResultInfo
{
@@ -28,8 +27,7 @@ public TestResultInfo(
List messages,
List attachments,
IReadOnlyCollection traits,
- string executorUri,
- TestCase testCase)
+ string executorUri)
{
this.Namespace = @namespace;
this.Type = type;
@@ -50,7 +48,6 @@ public TestResultInfo(
this.Attachments = attachments;
this.Traits = traits;
this.ExecutorUri = executorUri;
- this.TestCase = testCase;
// Use TestCaseDisplayName by default for reporting.
this.DisplayName = this.TestCaseDisplayName;
@@ -137,14 +134,14 @@ public IReadOnlyCollection> Properties
public string FullTypeName => this.Namespace + "." + this.Type;
///
- /// Gets value that originated at . Intended for use within
+ /// Gets value that originated at test result display name. Intended for use within
/// this library by framework specific adapters, to ensure that has the
/// proper value.
///
internal string TestResultDisplayName { get; }
///
- /// Gets value that originated at . Intended for use within
+ /// Gets value that originated at test case display name. Intended for use within
/// this library by framework specific adapters, to ensure that has the
/// proper value.
///
@@ -152,17 +149,6 @@ public IReadOnlyCollection> Properties
internal string FullyQualifiedName { get; }
- ///
- /// Gets the TestCase instance associated with this result.
- ///
- ///
- /// TestProperty store is maintained in TestCase, required for adapter
- /// extensions to retrieve values.
- /// Intended for internal usage only. Do not expose for consumer
- /// loggers.
- ///
- internal TestCase TestCase { get; }
-
public override bool Equals(object obj)
{
return obj is TestResultInfo info &&
diff --git a/src/TestLogger/Core/TestResultMessage.cs b/src/TestLogger/Core/TestResultMessage.cs
new file mode 100644
index 00000000..2d430e92
--- /dev/null
+++ b/src/TestLogger/Core/TestResultMessage.cs
@@ -0,0 +1,42 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Core
+{
+ ///
+ /// Represents a test result message.
+ ///
+ public sealed class TestResultMessage
+ {
+ ///
+ /// Standard output category.
+ ///
+ public const string StandardOutCategory = "StdOutMsgs";
+
+ ///
+ /// Standard error category.
+ ///
+ public const string StandardErrorCategory = "StdErrMsgs";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message category.
+ /// The message text.
+ public TestResultMessage(string category, string text)
+ {
+ this.Category = category;
+ this.Text = text;
+ }
+
+ ///
+ /// Gets the category.
+ ///
+ public string Category { get; }
+
+ ///
+ /// Gets the text.
+ ///
+ public string Text { get; }
+ }
+}
diff --git a/src/TestLogger/Core/TestRun.cs b/src/TestLogger/Core/TestRun.cs
index 05e990c0..d88fb1c0 100644
--- a/src/TestLogger/Core/TestRun.cs
+++ b/src/TestLogger/Core/TestRun.cs
@@ -3,23 +3,20 @@
namespace Spekt.TestLogger.Core
{
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.Platform;
public class TestRun : ITestRun
{
- public LoggerConfiguration LoggerConfiguration { get; internal set; }
+ public LoggerConfiguration LoggerConfiguration { get; set; }
- public TestRunConfiguration RunConfiguration { get; internal set; }
+ public TestRunConfiguration RunConfiguration { get; set; }
- public ITestAdapterFactory AdapterFactory { get; internal set; }
+ public ITestResultStore Store { get; set; }
- public ITestResultStore Store { get; internal set; }
+ public ITestResultSerializer Serializer { get; set; }
- public ITestResultSerializer Serializer { get; internal set; }
+ public IConsoleOutput ConsoleOutput { get; set; }
- public IConsoleOutput ConsoleOutput { get; internal set; }
-
- public IFileSystem FileSystem { get; internal set; }
+ public IFileSystem FileSystem { get; set; }
}
}
\ No newline at end of file
diff --git a/src/TestLogger/Core/TestRunBuilder.cs b/src/TestLogger/Core/TestRunBuilder.cs
index 57dce13d..eaf5e5c6 100644
--- a/src/TestLogger/Core/TestRunBuilder.cs
+++ b/src/TestLogger/Core/TestRunBuilder.cs
@@ -4,8 +4,6 @@
namespace Spekt.TestLogger.Core
{
using System;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.Platform;
public class TestRunBuilder : ITestRunBuilder
@@ -17,7 +15,6 @@ public TestRunBuilder()
this.testRun = new TestRun
{
RunConfiguration = new TestRunConfiguration(),
- AdapterFactory = new TestAdapterFactory(),
};
}
@@ -39,24 +36,6 @@ public ITestRunBuilder WithSerializer(ITestResultSerializer serializer)
return this;
}
- public ITestRunBuilder Subscribe(TestLoggerEvents loggerEvents)
- {
- if (loggerEvents == null)
- {
- throw new ArgumentNullException(nameof(loggerEvents));
- }
-
- loggerEvents.TestRunStart += (_, eventArgs) =>
- {
- this.testRun.RunConfiguration = this.testRun.Start(eventArgs);
- };
- loggerEvents.TestRunMessage += (_, eventArgs) => this.TraceAndThrow(() => this.testRun.Message(eventArgs), "TestRunMessage");
- loggerEvents.TestResult += (_, eventArgs) => this.TraceAndThrow(() => this.testRun.Result(eventArgs.Result), "TestResult");
- loggerEvents.TestRunComplete += (_, eventArgs) => this.TraceAndThrow(() => this.testRun.Complete(eventArgs), "TestRunComplete");
-
- return this;
- }
-
public ITestRunBuilder WithFileSystem(IFileSystem fileSystem)
{
this.testRun.FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
diff --git a/src/TestLogger/Core/TestRunCompleteWorkflow.cs b/src/TestLogger/Core/TestRunCompleteWorkflow.cs
index 33d1c31b..edae8019 100644
--- a/src/TestLogger/Core/TestRunCompleteWorkflow.cs
+++ b/src/TestLogger/Core/TestRunCompleteWorkflow.cs
@@ -7,41 +7,20 @@ namespace Spekt.TestLogger.Core
using System.Collections.Generic;
using System.Globalization;
using System.IO;
- using System.Linq;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Spekt.TestLogger.Platform;
- using Spekt.TestLogger.Utilities;
public static class TestRunCompleteWorkflow
{
- public static void Complete(this ITestRun testRun, TestRunCompleteEventArgs completeEvent)
- {
- var logFilePath = testRun.LoggerConfiguration
- .GetFormattedLogFilePath(testRun.RunConfiguration);
- var resultsDirectory = Path.GetDirectoryName(logFilePath);
- var attachments = completeEvent.AttachmentSets.SelectMany(x => x.ToAttachments(baseDirectory: resultsDirectory, makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths)).ToList();
-
- Complete(testRun, attachments);
- }
-
- public static void Complete(this ITestRun testRun, IReadOnlyCollection testAttachmentInfos)
+ public static void Complete(
+ this ITestRun testRun,
+ IReadOnlyCollection testAttachmentInfos,
+ List results,
+ List messages)
{
// Update the test run complete timestamp and run level attachments
testRun.RunConfiguration.EndTime = DateTime.UtcNow;
testRun.RunConfiguration.Attachments = testAttachmentInfos;
- // Freeze and reset the test result store
- testRun.Store.Pop(out var results, out var messages);
-
- // Transform the results with adapter specific hooks
- var transformedResults = results;
- if (transformedResults.Any())
- {
- var executorUri = transformedResults[0].ExecutorUri;
- var adapter = testRun.AdapterFactory.CreateTestAdapter(executorUri);
- transformedResults = adapter.TransformResults(results, messages);
- }
-
// Prepare test results file from logger configuration
var logFilePath = testRun.LoggerConfiguration
.GetFormattedLogFilePath(testRun.RunConfiguration);
@@ -50,7 +29,7 @@ public static void Complete(this ITestRun testRun, IReadOnlyCollection
- /// (MTP) Processes a and logs any standard output or error messages to the test run.
- ///
- /// The test run to log messages to.
- /// The test node update message containing properties to log.
- public static void Message(this ITestRun testRun, TestNodeUpdateMessage testNodeUpdateMessage)
- {
- foreach (var property in testNodeUpdateMessage.TestNode.Properties)
- {
-#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
- if (property is StandardErrorProperty stdErr)
- {
- testRun.Message(TestMessageLevel.Error, stdErr.StandardError);
- }
- else if (property is StandardOutputProperty stdOut)
- {
- testRun.Message(TestMessageLevel.Informational, stdOut.StandardOutput);
- }
-#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
- }
- }
-
- public static void Message(this ITestRun testRun, TestRunMessageEventArgs messageEvent)
- => Message(testRun, messageEvent.Level, messageEvent.Message);
-
public static void Message(this ITestRun testRun, TestMessageLevel messageLevel, string message)
{
testRun.Store.Add(
diff --git a/src/TestLogger/Core/TestRunResultWorkflow.cs b/src/TestLogger/Core/TestRunResultWorkflow.cs
index a25a6aca..b1dc8a54 100644
--- a/src/TestLogger/Core/TestRunResultWorkflow.cs
+++ b/src/TestLogger/Core/TestRunResultWorkflow.cs
@@ -3,211 +3,15 @@
namespace Spekt.TestLogger.Core
{
- using System;
- using System.Collections.Generic;
using System.IO;
- using System.Linq;
- using System.Reflection;
- using Microsoft.Testing.Platform.Extensions.Messages;
- using Microsoft.Testing.Platform.Extensions.TestFramework;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Spekt.TestLogger.Utilities;
public static class TestRunResultWorkflow
{
- // Parser instances are created per run so we can throttle error notifications to once per run.
- private static TestCaseNameParser parser;
- private static LegacyTestCaseNameParser legacyParser;
-
- // This is only reachable for MTP.
- public static void Result(this ITestRun testRun, TestNodeUpdateMessage testNodeUpdateMessage, ITestFramework testFramework)
- {
- if (testNodeUpdateMessage.TestNode.Properties.SingleOrDefault() is not { } state ||
- state is InProgressTestNodeStateProperty)
- {
- return;
- }
-
- // Initialize parsers with console output if not already done
- parser ??= new TestCaseNameParser(testRun.ConsoleOutput);
- legacyParser ??= new LegacyTestCaseNameParser(testRun.ConsoleOutput);
-
- testRun.LoggerConfiguration.Values.TryGetValue(LoggerConfiguration.ParserKey, out string parserVal);
-
- Func sanitize = testRun.Serializer.InputSanitizer.Sanitize;
-
- var attachments = testNodeUpdateMessage.TestNode.Properties.OfType().ToAttachments(baseDirectory: GetTestResultDirectory(testRun), makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths).ToList();
-
- var (errorMessage, errorStackTrace) = state switch
- {
- FailedTestNodeStateProperty failed => (failed.Exception.Message ?? failed.Explanation, failed.Exception.StackTrace),
- ErrorTestNodeStateProperty error => (error.Exception.Message ?? error.Explanation, error.Exception.StackTrace),
- _ => (string.Empty, string.Empty),
- };
-
- string filePath = null;
- int lineNumber = -1;
- var traits = new List();
- var messages = new List();
- DateTime startTime = default;
- DateTime endTime = default;
- TimeSpan duration = default;
-
- string @namespace = string.Empty;
- string type = string.Empty;
- string method = string.Empty;
- string fqn = string.Empty;
-
- // Find TestMethodIdentifierProperty if it exists
- TestMethodIdentifierProperty methodIdentifier = null;
- foreach (var property in testNodeUpdateMessage.TestNode.Properties)
- {
- if (property is TestFileLocationProperty testFileLocation)
- {
- filePath = testFileLocation.FilePath;
- lineNumber = testFileLocation.LineSpan.Start.Line;
- }
-#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
- else if (property is StandardErrorProperty stdErr)
- {
- messages.Add(new TestResultMessage(TestResultMessage.StandardErrorCategory, stdErr.StandardError));
- }
- else if (property is StandardOutputProperty stdOut)
- {
- messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, stdOut.StandardOutput));
- }
-#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
- else if (property is TestMetadataProperty metadata)
- {
- traits.Add(new Trait(metadata.Key, metadata.Value));
- }
- else if (property is TestMethodIdentifierProperty methodIdProp)
- {
- methodIdentifier = methodIdProp;
- }
- else if (property is TimingProperty timing)
- {
- startTime = timing.GlobalTiming.StartTime.UtcDateTime;
- endTime = timing.GlobalTiming.EndTime.UtcDateTime;
- duration = timing.GlobalTiming.Duration;
- }
- }
-
- // Parse test information using the unified method
- var parseResult = parser.Parse(methodIdentifier, testNodeUpdateMessage.TestNode);
- @namespace = parseResult.Namespace;
- type = parseResult.Type;
- method = parseResult.Method;
- fqn = parseResult.FullyQualifiedName;
-
- var assemblyPath = Assembly.GetEntryAssembly()?.Location;
- if (string.IsNullOrEmpty(assemblyPath))
- {
- assemblyPath = "UnknownAssembly";
- }
-
- testRun.Store.Add(new TestResultInfo(
- sanitize(@namespace),
- sanitize(type),
- sanitize(method),
- sanitize(fqn),
- GetOutcome(state),
- sanitize(testNodeUpdateMessage.TestNode.DisplayName),
- sanitize(testNodeUpdateMessage.TestNode.DisplayName),
- sanitize(assemblyPath),
- sanitize(filePath),
- lineNumber: lineNumber,
- startTime,
- endTime,
- duration,
- sanitize(errorMessage),
- sanitize(errorStackTrace),
- messages,
- attachments,
- traits,
- testFramework.DisplayName,
- null)); // TODO: This ends up being used in ITestAdapter implementations. The usage should be revised to better understand how to fix it.
-
- static TestOutcome GetOutcome(TestNodeStateProperty state)
- {
- return state switch
- {
- PassedTestNodeStateProperty => TestOutcome.Passed,
- FailedTestNodeStateProperty or ErrorTestNodeStateProperty or TimeoutTestNodeStateProperty or CancelledTestNodeStateProperty => TestOutcome.Failed,
- SkippedTestNodeStateProperty => TestOutcome.Skipped,
- _ => TestOutcome.None, // TODO: Should this throw?
- };
- }
- }
-
- // This is reachable only for VSTest.
- public static void Result(this ITestRun testRun, TestResult result)
- {
- // Initialize parsers with console output if not already done
- parser ??= new TestCaseNameParser(testRun.ConsoleOutput);
- legacyParser ??= new LegacyTestCaseNameParser(testRun.ConsoleOutput);
-
- var fqn = result.TestCase.FullyQualifiedName;
- testRun.LoggerConfiguration.Values.TryGetValue(LoggerConfiguration.ParserKey, out string parserVal);
- var parsedName = parserVal switch
- {
- string x when x.Equals("Legacy", StringComparison.OrdinalIgnoreCase) => legacyParser.Parse(fqn),
- _ => parser.Parse(fqn),
- };
-
- // Prepare attachments with relative paths if configured
- var attachments = result.Attachments.SelectMany(x => x.ToAttachments(baseDirectory: GetTestResultDirectory(testRun), makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths)).ToList();
-
- Func sanitize = testRun.Serializer.InputSanitizer.Sanitize;
-
- var traits = GetTraits(result.TestCase, sanitize);
- testRun.Store.Add(new TestResultInfo(
- sanitize(parsedName.Namespace),
- sanitize(parsedName.Type),
- sanitize(parsedName.Method),
- sanitize(fqn),
- result.Outcome,
- sanitize(result.DisplayName),
- sanitize(result.TestCase.DisplayName),
- sanitize(result.TestCase.Source),
- sanitize(result.TestCase.CodeFilePath),
- result.TestCase.LineNumber,
- result.StartTime.UtcDateTime,
- result.EndTime.UtcDateTime,
- result.Duration,
- sanitize(result.ErrorMessage),
- sanitize(result.ErrorStackTrace),
- result.Messages.Select(x => new TestResultMessage(sanitize(x.Category), sanitize(x.Text))).ToList(),
- attachments,
- traits,
- result.TestCase.ExecutorUri?.ToString(),
- result.TestCase));
- }
-
- private static string GetTestResultDirectory(ITestRun testRun)
+ public static string GetTestResultDirectory(ITestRun testRun)
{
var logFilePath = testRun.LoggerConfiguration
.GetFormattedLogFilePath(testRun.RunConfiguration);
return Path.GetDirectoryName(logFilePath);
}
-
- private static List GetTraits(TestCase testCase, Func sanitize)
- {
- // Workaround for test platform regression in .NET 10 SDK
- // var traits = result.TestCase.Traits.Select(x => new Trait(sanitize(x.Name), sanitize(x.Value))).ToList();
- var traits = new List();
- var traitProperty = testCase.Properties.FirstOrDefault(p => p.Id == "TestObject.Traits");
- if (traitProperty != null)
- {
- var traitValues = testCase.GetPropertyValue(traitProperty, Enumerable.Empty>());
-
- foreach (var kvp in traitValues)
- {
- traits.Add(new Trait(sanitize(kvp.Key), sanitize(kvp.Value)));
- }
- }
-
- return traits;
- }
}
}
\ No newline at end of file
diff --git a/src/TestLogger/Core/TestRunStartWorkflow.cs b/src/TestLogger/Core/TestRunStartWorkflow.cs
index ce89f0da..a12101e0 100644
--- a/src/TestLogger/Core/TestRunStartWorkflow.cs
+++ b/src/TestLogger/Core/TestRunStartWorkflow.cs
@@ -4,28 +4,9 @@
namespace Spekt.TestLogger.Core
{
using System;
- using System.Linq;
- using System.Xml;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
public static class TestRunStartWorkflow
{
- public static TestRunConfiguration Start(this ITestRun testRun, TestRunStartEventArgs startedEvent)
- {
- // Extract assembly path and adapter from test run criteria
- // TODO validate if the testcase filter or running specific tests is going to break this!
- var assemblyPath = startedEvent.TestRunCriteria.Sources.First();
-
- // Extract target framework from run settings
- var runSettings = new XmlDocument();
- runSettings.LoadXml(startedEvent.TestRunCriteria.TestRunSettings);
- var framework = runSettings
- .GetElementsByTagName("TargetFrameworkVersion")[0]
- .InnerText;
-
- return Start(testRun, assemblyPath, framework);
- }
-
public static TestRunConfiguration Start(this ITestRun testRun, string assemblyPath, string targetFramework)
{
return new TestRunConfiguration
diff --git a/src/TestLogger/Core/Trait.cs b/src/TestLogger/Core/Trait.cs
new file mode 100644
index 00000000..ded0fded
--- /dev/null
+++ b/src/TestLogger/Core/Trait.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Core
+{
+ ///
+ /// Represents a trait (category) for a test.
+ ///
+ public sealed class Trait
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The trait name.
+ /// The trait value.
+ public Trait(string name, string value)
+ {
+ this.Name = name;
+ this.Value = value;
+ }
+
+ ///
+ /// Gets the trait name.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Gets the trait value.
+ ///
+ public string Value { get; }
+ }
+}
diff --git a/src/TestLogger/Mtp/Core/MtpTestCaseNameParserExtensions.cs b/src/TestLogger/Mtp/Core/MtpTestCaseNameParserExtensions.cs
new file mode 100644
index 00000000..355c64ba
--- /dev/null
+++ b/src/TestLogger/Mtp/Core/MtpTestCaseNameParserExtensions.cs
@@ -0,0 +1,78 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Mtp.Core
+{
+ using Microsoft.Testing.Platform.Extensions.Messages;
+ using Spekt.TestLogger.Core;
+
+ public static class MtpTestCaseNameParserExtensions
+ {
+ public static ParsedName Parse(this TestCaseNameParser parser, TestMethodIdentifierProperty methodIdentifier)
+ {
+ if (methodIdentifier == null)
+ {
+ return new ParsedName(
+ TestCaseNameParser.TestCaseParserUnknownNamespace,
+ TestCaseNameParser.TestCaseParserUnknownType,
+ string.Empty);
+ }
+
+ string @namespace = methodIdentifier.Namespace;
+ string type = methodIdentifier.TypeName;
+ string method = methodIdentifier.MethodName;
+
+ if (!string.IsNullOrEmpty(@namespace) && !string.IsNullOrEmpty(type))
+ {
+ if (type.StartsWith(@namespace + "."))
+ {
+ type = type.Substring(@namespace.Length + 1);
+ }
+ else if (@namespace.EndsWith("." + type))
+ {
+ @namespace = @namespace.Substring(0, @namespace.Length - type.Length - 1);
+ }
+ else if (@namespace == type)
+ {
+ @namespace = string.Empty;
+ }
+ }
+
+ return new ParsedName(
+ @namespace ?? string.Empty,
+ type ?? string.Empty,
+ method ?? string.Empty);
+ }
+
+ public static (string Namespace, string Type, string Method, string FullyQualifiedName) Parse(this TestCaseNameParser parser, TestMethodIdentifierProperty methodIdentifier, TestNode testNode)
+ {
+ if (methodIdentifier != null)
+ {
+ var parsedName = parser.Parse(methodIdentifier);
+ var fqn = string.IsNullOrEmpty(parsedName.Namespace)
+ ? $"{parsedName.Type}.{parsedName.Method}"
+ : $"{parsedName.Namespace}.{parsedName.Type}.{parsedName.Method}";
+
+ return (parsedName.Namespace, parsedName.Type, parsedName.Method, fqn);
+ }
+ else if (testNode != null)
+ {
+ var displayName = testNode.Uid;
+ var parsedName = parser.Parse(displayName);
+
+ if (parsedName.Namespace != TestCaseNameParser.TestCaseParserUnknownNamespace)
+ {
+ return (parsedName.Namespace, parsedName.Type, parsedName.Method, displayName);
+ }
+ else
+ {
+ return ("UnknownNamespace", "UnknownType", "UnknownMethod", "UnknownFullyQualifiedName");
+ }
+ }
+ else
+ {
+ return ("UnknownNamespace", "UnknownType", "UnknownMethod", "UnknownFullyQualifiedName");
+ }
+ }
+ }
+}
diff --git a/src/TestLogger/Mtp/Core/MtpTestRunMessageWorkflow.cs b/src/TestLogger/Mtp/Core/MtpTestRunMessageWorkflow.cs
new file mode 100644
index 00000000..6eb99e9f
--- /dev/null
+++ b/src/TestLogger/Mtp/Core/MtpTestRunMessageWorkflow.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Mtp.Core
+{
+ using Microsoft.Testing.Platform.Extensions.Messages;
+ using Spekt.TestLogger.Core;
+
+ public static class MtpTestRunMessageWorkflow
+ {
+ public static void Message(this ITestRun testRun, TestNodeUpdateMessage testNodeUpdateMessage)
+ {
+ foreach (var property in testNodeUpdateMessage.TestNode.Properties)
+ {
+#pragma warning disable TPEXP
+ if (property is StandardErrorProperty stdErr)
+ {
+ testRun.Message(TestMessageLevel.Error, stdErr.StandardError);
+ }
+ else if (property is StandardOutputProperty stdOut)
+ {
+ testRun.Message(TestMessageLevel.Informational, stdOut.StandardOutput);
+ }
+#pragma warning restore TPEXP
+ }
+ }
+ }
+}
diff --git a/src/TestLogger/Mtp/Core/MtpTestRunResultWorkflow.cs b/src/TestLogger/Mtp/Core/MtpTestRunResultWorkflow.cs
new file mode 100644
index 00000000..18f86113
--- /dev/null
+++ b/src/TestLogger/Mtp/Core/MtpTestRunResultWorkflow.cs
@@ -0,0 +1,137 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.Mtp.Core
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+ using Microsoft.Testing.Platform.Extensions.Messages;
+ using Microsoft.Testing.Platform.Extensions.TestFramework;
+ using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp.Utilities;
+
+ public static class MtpTestRunResultWorkflow
+ {
+ private static TestCaseNameParser parser;
+ private static LegacyTestCaseNameParser legacyParser;
+
+ public static void Result(this ITestRun testRun, TestNodeUpdateMessage testNodeUpdateMessage, ITestFramework testFramework)
+ {
+ if (testNodeUpdateMessage.TestNode.Properties.SingleOrDefault() is not { } state ||
+ state is InProgressTestNodeStateProperty)
+ {
+ return;
+ }
+
+ parser ??= new TestCaseNameParser(testRun.ConsoleOutput);
+ legacyParser ??= new LegacyTestCaseNameParser(testRun.ConsoleOutput);
+
+ testRun.LoggerConfiguration.Values.TryGetValue(LoggerConfiguration.ParserKey, out string parserVal);
+
+ Func sanitize = testRun.Serializer.InputSanitizer.Sanitize;
+
+ var attachments = testNodeUpdateMessage.TestNode.Properties.OfType().ToAttachments(baseDirectory: TestRunResultWorkflow.GetTestResultDirectory(testRun), makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths).ToList();
+
+ var (errorMessage, errorStackTrace) = state switch
+ {
+ FailedTestNodeStateProperty failed => (failed.Exception.Message ?? failed.Explanation, failed.Exception.StackTrace),
+ ErrorTestNodeStateProperty error => (error.Exception.Message ?? error.Explanation, error.Exception.StackTrace),
+ _ => (string.Empty, string.Empty),
+ };
+
+ string filePath = null;
+ int lineNumber = -1;
+ var traits = new List();
+ var messages = new List();
+ DateTime startTime = default;
+ DateTime endTime = default;
+ TimeSpan duration = default;
+
+ string @namespace = string.Empty;
+ string type = string.Empty;
+ string method = string.Empty;
+ string fqn = string.Empty;
+
+ TestMethodIdentifierProperty methodIdentifier = null;
+ foreach (var property in testNodeUpdateMessage.TestNode.Properties)
+ {
+ if (property is TestFileLocationProperty testFileLocation)
+ {
+ filePath = testFileLocation.FilePath;
+ lineNumber = testFileLocation.LineSpan.Start.Line;
+ }
+#pragma warning disable TPEXP
+ else if (property is StandardErrorProperty stdErr)
+ {
+ messages.Add(new TestResultMessage(TestResultMessage.StandardErrorCategory, stdErr.StandardError));
+ }
+ else if (property is StandardOutputProperty stdOut)
+ {
+ messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, stdOut.StandardOutput));
+ }
+#pragma warning restore TPEXP
+ else if (property is TestMetadataProperty metadata)
+ {
+ traits.Add(new Trait(metadata.Key, metadata.Value));
+ }
+ else if (property is TestMethodIdentifierProperty methodIdProp)
+ {
+ methodIdentifier = methodIdProp;
+ }
+ else if (property is TimingProperty timing)
+ {
+ startTime = timing.GlobalTiming.StartTime.UtcDateTime;
+ endTime = timing.GlobalTiming.EndTime.UtcDateTime;
+ duration = timing.GlobalTiming.Duration;
+ }
+ }
+
+ var parseResult = parser.Parse(methodIdentifier, testNodeUpdateMessage.TestNode);
+ @namespace = parseResult.Namespace;
+ type = parseResult.Type;
+ method = parseResult.Method;
+ fqn = parseResult.FullyQualifiedName;
+
+ var assemblyPath = Assembly.GetEntryAssembly()?.Location;
+ if (string.IsNullOrEmpty(assemblyPath))
+ {
+ assemblyPath = "UnknownAssembly";
+ }
+
+ testRun.Store.Add(new TestResultInfo(
+ sanitize(@namespace),
+ sanitize(type),
+ sanitize(method),
+ sanitize(fqn),
+ GetOutcome(state),
+ sanitize(testNodeUpdateMessage.TestNode.DisplayName),
+ sanitize(testNodeUpdateMessage.TestNode.DisplayName),
+ sanitize(assemblyPath),
+ sanitize(filePath),
+ lineNumber: lineNumber,
+ startTime,
+ endTime,
+ duration,
+ sanitize(errorMessage),
+ sanitize(errorStackTrace),
+ messages,
+ attachments,
+ traits,
+ testFramework.DisplayName));
+
+ static TestOutcome GetOutcome(TestNodeStateProperty state)
+ {
+ return state switch
+ {
+ PassedTestNodeStateProperty => TestOutcome.Passed,
+ FailedTestNodeStateProperty or ErrorTestNodeStateProperty or TimeoutTestNodeStateProperty or CancelledTestNodeStateProperty => TestOutcome.Failed,
+ SkippedTestNodeStateProperty => TestOutcome.Skipped,
+ _ => TestOutcome.None,
+ };
+ }
+ }
+ }
+}
diff --git a/src/TestLogger/TestReporter.cs b/src/TestLogger/Mtp/TestReporter.cs
similarity index 96%
rename from src/TestLogger/TestReporter.cs
rename to src/TestLogger/Mtp/TestReporter.cs
index 5a97531d..f3b7f3bb 100644
--- a/src/TestLogger/TestReporter.cs
+++ b/src/TestLogger/Mtp/TestReporter.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestReporter
+namespace Spekt.TestLogger.Mtp
{
using System;
using System.Collections.Generic;
@@ -16,10 +16,10 @@ namespace Spekt.TestReporter
using Microsoft.Testing.Platform.Extensions.TestHost;
using Microsoft.Testing.Platform.Services;
using Microsoft.Testing.Platform.TestHost;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp.Core;
+ using Spekt.TestLogger.Mtp.Utilities;
using Spekt.TestLogger.Platform;
- using Spekt.TestLogger.Utilities;
///
/// Base test reporter implementation for Microsoft.Testing.Platform.
@@ -104,7 +104,8 @@ public Task OnTestSessionFinishingAsync(SessionUid sessionUid, CancellationToken
public Task OnTestSessionFinishingAsync(ITestSessionContext testSessionContext)
#endif
{
- this.testRun.Complete(this.testAttachmentInfos);
+ this.testRun.Store.Pop(out var results, out var messages);
+ this.testRun.Complete(this.testAttachmentInfos, results, messages);
return Task.CompletedTask;
}
diff --git a/src/TestLogger/TestReporterCommandLineProvider.cs b/src/TestLogger/Mtp/TestReporterCommandLineProvider.cs
similarity index 99%
rename from src/TestLogger/TestReporterCommandLineProvider.cs
rename to src/TestLogger/Mtp/TestReporterCommandLineProvider.cs
index a9a33faf..a689be75 100644
--- a/src/TestLogger/TestReporterCommandLineProvider.cs
+++ b/src/TestLogger/Mtp/TestReporterCommandLineProvider.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestReporter
+namespace Spekt.TestLogger.Mtp
{
using System.Collections.Generic;
using System.Linq;
diff --git a/src/TestLogger/Utilities/ArtifactExtensions.cs b/src/TestLogger/Mtp/Utilities/ArtifactExtensions.cs
similarity index 98%
rename from src/TestLogger/Utilities/ArtifactExtensions.cs
rename to src/TestLogger/Mtp/Utilities/ArtifactExtensions.cs
index d39cb07b..cbab22c7 100644
--- a/src/TestLogger/Utilities/ArtifactExtensions.cs
+++ b/src/TestLogger/Mtp/Utilities/ArtifactExtensions.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Utilities
+namespace Spekt.TestLogger.Mtp.Utilities
{
using System;
using System.Collections.Generic;
diff --git a/src/TestLogger/TestLogger.MTP.csproj b/src/TestLogger/TestLogger.MTP.csproj
new file mode 100644
index 00000000..b6ac2b8e
--- /dev/null
+++ b/src/TestLogger/TestLogger.MTP.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netstandard2.0
+ Spekt.TestLogger.Mtp
+ $(PackageVersion)
+ true
+ embedded
+ true
+ $(DefaultItemExcludes);VSTest/**
+
+
+
+ Spekt.TestLogger
+
+
+
+
+
+
+
diff --git a/src/TestLogger/TestLogger.csproj b/src/TestLogger/TestLogger.VSTest.csproj
similarity index 70%
rename from src/TestLogger/TestLogger.csproj
rename to src/TestLogger/TestLogger.VSTest.csproj
index 77a1dc4f..01ab66b0 100644
--- a/src/TestLogger/TestLogger.csproj
+++ b/src/TestLogger/TestLogger.VSTest.csproj
@@ -1,12 +1,13 @@
-
+
netstandard2.0
- Spekt.TestLogger
+ Spekt.TestLogger.VSTest
$(PackageVersion)
true
embedded
true
+ $(DefaultItemExcludes);Mtp/**
@@ -14,8 +15,7 @@
-
-
+
diff --git a/src/TestLogger/Utilities/AttachmentSetExtensions.cs b/src/TestLogger/Utilities/AttachmentSetExtensions.cs
deleted file mode 100644
index 34c583dc..00000000
--- a/src/TestLogger/Utilities/AttachmentSetExtensions.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) Spekt Contributors. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-namespace Spekt.TestLogger.Utilities
-{
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Spekt.TestLogger.Core;
-
- public static class AttachmentSetExtensions
- {
- public static IEnumerable ToAttachments(this AttachmentSet attachmentSet, string baseDirectory, bool makeRelativePaths)
- {
- if (makeRelativePaths && !string.IsNullOrEmpty(baseDirectory))
- {
- return attachmentSet.Attachments.Select(a =>
- {
- var attachmentPath = GetPathFromUri(a.Uri);
- var relativePath = ArtifactExtensions.MakeRelativePath(baseDirectory, attachmentPath);
- return new TestAttachmentInfo(relativePath, a.Description);
- });
- }
-
- return attachmentSet.Attachments.Select(a => new
- TestAttachmentInfo(GetPathFromUri(a.Uri), a.Description));
- }
-
- private static string GetPathFromUri(Uri uri)
- {
- try
- {
- return uri.LocalPath;
- }
- catch (InvalidOperationException)
- {
- return uri.OriginalString;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/TestLogger/VSTest/Core/VSTestTestRunBuilderExtensions.cs b/src/TestLogger/VSTest/Core/VSTestTestRunBuilderExtensions.cs
new file mode 100644
index 00000000..d220c96c
--- /dev/null
+++ b/src/TestLogger/VSTest/Core/VSTestTestRunBuilderExtensions.cs
@@ -0,0 +1,46 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Core
+{
+ using System;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
+ using Spekt.TestLogger.Core;
+
+ public static class VSTestTestRunBuilderExtensions
+ {
+ public static void Subscribe(this ITestRun testRun, TestLoggerEvents loggerEvents)
+ {
+ if (testRun == null)
+ {
+ throw new ArgumentNullException(nameof(testRun));
+ }
+
+ if (loggerEvents == null)
+ {
+ throw new ArgumentNullException(nameof(loggerEvents));
+ }
+
+ loggerEvents.TestRunStart += (_, eventArgs) =>
+ {
+ testRun.RunConfiguration = testRun.Start(eventArgs);
+ };
+ loggerEvents.TestRunMessage += (_, eventArgs) => TraceAndThrow(testRun, () => testRun.Message(eventArgs), "TestRunMessage");
+ loggerEvents.TestResult += (_, eventArgs) => TraceAndThrow(testRun, () => testRun.Result(eventArgs.Result), "TestResult");
+ loggerEvents.TestRunComplete += (_, eventArgs) => TraceAndThrow(testRun, () => testRun.Complete(eventArgs), "TestRunComplete");
+ }
+
+ private static void TraceAndThrow(ITestRun testRun, Action action, string source)
+ {
+ try
+ {
+ action();
+ }
+ catch (Exception)
+ {
+ testRun.ConsoleOutput?.WriteError($"Test Logger: Unexpected error in {source} workflow. Please rerun with `dotnet test --diag:log.txt` to see the stacktrace and report the issue at https://github.com/spekt/testlogger/issues/new.");
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/TestLogger/VSTest/Core/VSTestTestRunCompleteWorkflow.cs b/src/TestLogger/VSTest/Core/VSTestTestRunCompleteWorkflow.cs
new file mode 100644
index 00000000..6a0d8964
--- /dev/null
+++ b/src/TestLogger/VSTest/Core/VSTestTestRunCompleteWorkflow.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Core
+{
+ using System.IO;
+ using System.Linq;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
+ using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.VSTest.Utilities;
+
+ public static class VSTestTestRunCompleteWorkflow
+ {
+ public static void Complete(this ITestRun testRun, TestRunCompleteEventArgs completeEvent)
+ {
+ var logFilePath = testRun.LoggerConfiguration
+ .GetFormattedLogFilePath(testRun.RunConfiguration);
+ var resultsDirectory = Path.GetDirectoryName(logFilePath);
+ var attachments = completeEvent.AttachmentSets.SelectMany(x => x.ToAttachments(baseDirectory: resultsDirectory, makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths)).ToList();
+
+ testRun.Store.Pop(out var results, out var messages);
+
+ // Results were already transformed per-result in VSTestTestRunResultWorkflow.Result
+ // using the real VSTest TestCase. No batch transformation needed here.
+ TestRunCompleteWorkflow.Complete(testRun, attachments, results, messages);
+ }
+ }
+}
diff --git a/src/TestLogger/VSTest/Core/VSTestTestRunMessageWorkflow.cs b/src/TestLogger/VSTest/Core/VSTestTestRunMessageWorkflow.cs
new file mode 100644
index 00000000..00453452
--- /dev/null
+++ b/src/TestLogger/VSTest/Core/VSTestTestRunMessageWorkflow.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Core
+{
+ using Spekt.TestLogger.Core;
+
+ public static class VSTestTestRunMessageWorkflow
+ {
+ public static void Message(this ITestRun testRun, Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestRunMessageEventArgs messageEvent)
+ {
+ var level = (TestMessageLevel)(int)messageEvent.Level;
+ testRun.Message(level, messageEvent.Message);
+ }
+ }
+}
diff --git a/src/TestLogger/VSTest/Core/VSTestTestRunResultWorkflow.cs b/src/TestLogger/VSTest/Core/VSTestTestRunResultWorkflow.cs
new file mode 100644
index 00000000..da85df22
--- /dev/null
+++ b/src/TestLogger/VSTest/Core/VSTestTestRunResultWorkflow.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Core
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.VSTest.Utilities;
+ using VSTestOutcome = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome;
+ using VSTestTestCase = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestCase;
+ using VSTestTestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult;
+
+ public static class VSTestTestRunResultWorkflow
+ {
+ private static TestCaseNameParser parser;
+ private static LegacyTestCaseNameParser legacyParser;
+
+ public static void Result(this ITestRun testRun, VSTestTestResult result)
+ {
+ parser ??= new TestCaseNameParser(testRun.ConsoleOutput);
+ legacyParser ??= new LegacyTestCaseNameParser(testRun.ConsoleOutput);
+
+ var fqn = result.TestCase.FullyQualifiedName;
+ testRun.LoggerConfiguration.Values.TryGetValue(LoggerConfiguration.ParserKey, out string parserVal);
+ var parsedName = parserVal switch
+ {
+ string x when x.Equals("Legacy", StringComparison.OrdinalIgnoreCase) => legacyParser.Parse(fqn),
+ _ => parser.Parse(fqn),
+ };
+
+ var attachments = result.Attachments.SelectMany(x => x.ToAttachments(baseDirectory: TestRunResultWorkflow.GetTestResultDirectory(testRun), makeRelativePaths: testRun.LoggerConfiguration.UseRelativeAttachmentPaths)).ToList();
+
+ Func sanitize = testRun.Serializer.InputSanitizer.Sanitize;
+
+ var traits = GetTraits(result.TestCase, sanitize);
+ var coreOutcome = (TestOutcome)(int)result.Outcome;
+ var resultInfo = new TestResultInfo(
+ sanitize(parsedName.Namespace),
+ sanitize(parsedName.Type),
+ sanitize(parsedName.Method),
+ sanitize(fqn),
+ coreOutcome,
+ sanitize(result.DisplayName),
+ sanitize(result.TestCase.DisplayName),
+ sanitize(result.TestCase.Source),
+ sanitize(result.TestCase.CodeFilePath),
+ result.TestCase.LineNumber,
+ result.StartTime.UtcDateTime,
+ result.EndTime.UtcDateTime,
+ result.Duration,
+ sanitize(result.ErrorMessage),
+ sanitize(result.ErrorStackTrace),
+ result.Messages.Select(x => new TestResultMessage(sanitize(x.Category), sanitize(x.Text))).ToList(),
+ attachments,
+ traits,
+ result.TestCase.ExecutorUri?.ToString());
+
+ // Apply framework-specific transformations using the real VSTest TestCase.
+ // Use per-result inline transformation so properties are extracted from the real ObjectModel TestCase.
+ var executorUri = result.TestCase.ExecutorUri?.ToString();
+ var adapter = new Spekt.TestLogger.VSTest.Extensions.TestAdapterFactory().CreateTestAdapter(executorUri);
+ var transformed = adapter.TransformResults(new List { resultInfo }, new List(), result.TestCase);
+ testRun.Store.Add(transformed[0]);
+ }
+
+ private static List GetTraits(VSTestTestCase testCase, Func sanitize)
+ {
+ var traits = new List();
+ var traitProperty = testCase.Properties.FirstOrDefault(p => p.Id == "TestObject.Traits");
+ if (traitProperty != null)
+ {
+ var traitValues = testCase.GetPropertyValue(traitProperty, Enumerable.Empty>());
+
+ foreach (var kvp in traitValues)
+ {
+ traits.Add(new Trait(sanitize(kvp.Key), sanitize(kvp.Value)));
+ }
+ }
+
+ return traits;
+ }
+ }
+}
diff --git a/src/TestLogger/VSTest/Core/VSTestTestRunStartWorkflow.cs b/src/TestLogger/VSTest/Core/VSTestTestRunStartWorkflow.cs
new file mode 100644
index 00000000..a7f5edf7
--- /dev/null
+++ b/src/TestLogger/VSTest/Core/VSTestTestRunStartWorkflow.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Core
+{
+ using System.Linq;
+ using System.Xml;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
+ using Spekt.TestLogger.Core;
+
+ public static class VSTestTestRunStartWorkflow
+ {
+ public static TestRunConfiguration Start(this ITestRun testRun, TestRunStartEventArgs startedEvent)
+ {
+ var assemblyPath = startedEvent.TestRunCriteria.Sources.First();
+ var runSettings = new XmlDocument();
+ runSettings.LoadXml(startedEvent.TestRunCriteria.TestRunSettings);
+ var framework = runSettings
+ .GetElementsByTagName("TargetFrameworkVersion")[0]
+ .InnerText;
+
+ return testRun.Start(assemblyPath, framework);
+ }
+ }
+}
diff --git a/src/TestLogger/Extensions/DefaultTestAdapter.cs b/src/TestLogger/VSTest/Extensions/DefaultTestAdapter.cs
similarity index 77%
rename from src/TestLogger/Extensions/DefaultTestAdapter.cs
rename to src/TestLogger/VSTest/Extensions/DefaultTestAdapter.cs
index 760a8ea8..a3c250d8 100644
--- a/src/TestLogger/Extensions/DefaultTestAdapter.cs
+++ b/src/TestLogger/VSTest/Extensions/DefaultTestAdapter.cs
@@ -1,14 +1,14 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
using System.Collections.Generic;
using Spekt.TestLogger.Core;
public class DefaultTestAdapter : ITestAdapter
{
- public List TransformResults(List results, List messages)
+ public List TransformResults(List results, List messages, object testCase = null)
{
return results;
}
diff --git a/src/TestLogger/Extensions/ITestAdapter.cs b/src/TestLogger/VSTest/Extensions/ITestAdapter.cs
similarity index 74%
rename from src/TestLogger/Extensions/ITestAdapter.cs
rename to src/TestLogger/VSTest/Extensions/ITestAdapter.cs
index 2c920259..8718ffd9 100644
--- a/src/TestLogger/Extensions/ITestAdapter.cs
+++ b/src/TestLogger/VSTest/Extensions/ITestAdapter.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
using System.Collections.Generic;
using Spekt.TestLogger.Core;
@@ -10,6 +10,7 @@ public interface ITestAdapter
{
List TransformResults(
List results,
- List messages);
+ List messages,
+ object testCase = null);
}
}
\ No newline at end of file
diff --git a/src/TestLogger/Extensions/ITestAdapterFactory.cs b/src/TestLogger/VSTest/Extensions/ITestAdapterFactory.cs
similarity index 86%
rename from src/TestLogger/Extensions/ITestAdapterFactory.cs
rename to src/TestLogger/VSTest/Extensions/ITestAdapterFactory.cs
index cfdc83b6..2a9b94f8 100644
--- a/src/TestLogger/Extensions/ITestAdapterFactory.cs
+++ b/src/TestLogger/VSTest/Extensions/ITestAdapterFactory.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
public interface ITestAdapterFactory
{
diff --git a/src/TestLogger/Extensions/MSTestAdapter.cs b/src/TestLogger/VSTest/Extensions/MSTestAdapter.cs
similarity index 56%
rename from src/TestLogger/Extensions/MSTestAdapter.cs
rename to src/TestLogger/VSTest/Extensions/MSTestAdapter.cs
index 09bd2e53..34f69442 100644
--- a/src/TestLogger/Extensions/MSTestAdapter.cs
+++ b/src/TestLogger/VSTest/Extensions/MSTestAdapter.cs
@@ -1,14 +1,14 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
using System.Collections.Generic;
using Spekt.TestLogger.Core;
public class MSTestAdapter : ITestAdapter
{
- public List TransformResults(List results, List messages)
+ public List TransformResults(List results, List messages, object testCase = null)
{
// MS Test puts test parameters in the DisplayName and not in the FullyQualifiedName.
// So we use the DisplayName whenever it is available.
@@ -26,27 +26,36 @@ public List TransformResults(List results, List<
result.Method = displayName;
}
- CreateProperties(result);
+ CreateProperties(result, testCase);
}
return results;
}
- private static void CreateProperties(TestResultInfo result)
+ private static void CreateProperties(TestResultInfo result, object testCaseObj)
{
- if (result.TestCase is not { } testCase)
+ if (testCaseObj == null)
+ {
+ return;
+ }
+
+ // Use reflection to avoid hard reference to Microsoft.TestPlatform.ObjectModel in Core assembly.
+ var testCaseType = testCaseObj.GetType();
+ var propertiesProp = testCaseType.GetProperty("Properties");
+ var propertiesValue = propertiesProp?.GetValue(testCaseObj) as System.Collections.IEnumerable;
+ if (propertiesValue == null)
{
return;
}
- // Parse property traits
var properties = new List>();
- foreach (var property in testCase.Properties)
+ foreach (var property in propertiesValue)
{
- switch (property.Id)
+ var id = property.GetType().GetProperty("Id")?.GetValue(property) as string;
+ switch (id)
{
case "Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestProperty":
- var propertyValue = testCase.GetPropertyValue(property) as string[];
+ var propertyValue = InvokeGetPropertyValue(testCaseObj, property) as string[];
properties.Add(new KeyValuePair("CustomProperty", propertyValue));
break;
}
@@ -54,5 +63,11 @@ private static void CreateProperties(TestResultInfo result)
result.Properties = properties;
}
+
+ private static object InvokeGetPropertyValue(object testCase, object property)
+ {
+ var method = testCase.GetType().GetMethod("GetPropertyValue", new[] { property.GetType() });
+ return method?.Invoke(testCase, new[] { property });
+ }
}
}
diff --git a/src/TestLogger/Extensions/NUnitTestAdapter.cs b/src/TestLogger/VSTest/Extensions/NUnitTestAdapter.cs
similarity index 53%
rename from src/TestLogger/Extensions/NUnitTestAdapter.cs
rename to src/TestLogger/VSTest/Extensions/NUnitTestAdapter.cs
index f484b6ce..e3247c98 100644
--- a/src/TestLogger/Extensions/NUnitTestAdapter.cs
+++ b/src/TestLogger/VSTest/Extensions/NUnitTestAdapter.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
using System;
using System.Collections.Generic;
@@ -12,50 +12,64 @@ public class NUnitTestAdapter : ITestAdapter
{
private const string ExplicitLabel = "Explicit";
- public List TransformResults(List results, List messages)
+ public List TransformResults(List results, List messages, object testCase = null)
{
foreach (var result in results)
{
// Mark tests with Explicit attribute as Skipped instead of Inconclusive. Explicit
// is passed as a trait in the test platform. NUnit explicit attribute spec:
// https://docs.nunit.org/articles/nunit/writing-tests/attributes/explicit.html
- if (result.Outcome == Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome.None &&
+ if (result.Outcome == TestOutcome.None &&
result.Traits.Any(trait => trait.Name.Equals(ExplicitLabel, StringComparison.OrdinalIgnoreCase)))
{
- result.Outcome = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome.Skipped;
+ result.Outcome = TestOutcome.Skipped;
}
- CreateProperties(result);
+ CreateProperties(result, testCase);
}
return results;
}
- private static void CreateProperties(TestResultInfo result)
+ private static void CreateProperties(TestResultInfo result, object testCaseObj)
{
- if (result.TestCase is not { } testCase)
+ if (testCaseObj == null)
+ {
+ return;
+ }
+
+ // Use reflection to avoid hard reference to Microsoft.TestPlatform.ObjectModel in Core assembly.
+ var testCaseType = testCaseObj.GetType();
+ var propertiesProp = testCaseType.GetProperty("Properties");
+ var propertiesValue = propertiesProp?.GetValue(testCaseObj) as System.Collections.IEnumerable;
+ if (propertiesValue == null)
{
return;
}
- // NUnit adapter uses Seed and TestCategory in TestCase Properties.
- // Populate these properties if available.
var properties = new List>();
- foreach (var property in testCase.Properties)
+ foreach (var property in propertiesValue)
{
- switch (property.Id)
+ var id = property.GetType().GetProperty("Id")?.GetValue(property) as string;
+ switch (id)
{
case "NUnit.Seed":
case "NUnit.TestCategory":
- properties.Add(new KeyValuePair(property.Id, testCase.GetPropertyValue(property)));
+ properties.Add(new KeyValuePair(id, InvokeGetPropertyValue(testCaseObj, property)));
break;
case "NUnit.Category":
- properties.Add(new KeyValuePair("CustomProperty", testCase.GetPropertyValue(property)));
+ properties.Add(new KeyValuePair("CustomProperty", InvokeGetPropertyValue(testCaseObj, property)));
break;
}
}
result.Properties = properties;
}
+
+ private static object InvokeGetPropertyValue(object testCase, object property)
+ {
+ var method = testCase.GetType().GetMethod("GetPropertyValue", new[] { property.GetType() });
+ return method?.Invoke(testCase, new[] { property });
+ }
}
}
diff --git a/src/TestLogger/Extensions/TestAdapterFactory.cs b/src/TestLogger/VSTest/Extensions/TestAdapterFactory.cs
similarity index 95%
rename from src/TestLogger/Extensions/TestAdapterFactory.cs
rename to src/TestLogger/VSTest/Extensions/TestAdapterFactory.cs
index 6153f3dc..3d8a2342 100644
--- a/src/TestLogger/Extensions/TestAdapterFactory.cs
+++ b/src/TestLogger/VSTest/Extensions/TestAdapterFactory.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
public class TestAdapterFactory : ITestAdapterFactory
{
diff --git a/src/TestLogger/Extensions/XunitTestAdapter.cs b/src/TestLogger/VSTest/Extensions/XunitTestAdapter.cs
similarity index 53%
rename from src/TestLogger/Extensions/XunitTestAdapter.cs
rename to src/TestLogger/VSTest/Extensions/XunitTestAdapter.cs
index 58547308..41999eaf 100644
--- a/src/TestLogger/Extensions/XunitTestAdapter.cs
+++ b/src/TestLogger/VSTest/Extensions/XunitTestAdapter.cs
@@ -1,17 +1,21 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger.Extensions
+namespace Spekt.TestLogger.VSTest.Extensions
{
+ using System;
using System.Collections.Generic;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using System.Linq;
using Spekt.TestLogger.Core;
public class XunitTestAdapter : ITestAdapter
{
+ private const string SkipReasonCategory = "skipReason";
+
public List TransformResults(
List results,
- List messages)
+ List messages,
+ object testCase = null)
{
var transformedResults = new List();
@@ -43,7 +47,21 @@ public List TransformResults(
if (skippedTestNamesWithReason.TryGetValue(result.TestCaseDisplayName, out var skipReason))
{
// TODO: Defining a new category for now...
- result.Messages.Add(new TestResultMessage("skipReason", skipReason));
+ result.Messages.Add(new TestResultMessage(SkipReasonCategory, skipReason));
+ }
+ else if (result.Outcome == TestOutcome.Skipped)
+ {
+ // Fallback: run level skip messages are not available when transforming
+ // per result, so derive the reason from the result's own StandardOut
+ // message, if any. Skipped tests never execute, so their StandardOut
+ // carries only runner-generated text (the skip reason).
+ var reason = result.Messages
+ .FirstOrDefault(m => TestResultMessage.StandardOutCategory.Equals(m.Category, StringComparison.OrdinalIgnoreCase)
+ && !string.IsNullOrWhiteSpace(m.Text))?.Text.Trim();
+ if (!string.IsNullOrEmpty(reason))
+ {
+ result.Messages.Add(new TestResultMessage(SkipReasonCategory, reason));
+ }
}
string displayName = result.TestResultDisplayName;
@@ -56,7 +74,7 @@ public List TransformResults(
result.Method += displayName.Substring(i);
}
- CreateProperties(result);
+ CreateProperties(result, testCase);
transformedResults.Add(result);
}
@@ -64,9 +82,18 @@ public List TransformResults(
return transformedResults;
}
- private static void CreateProperties(TestResultInfo result)
+ private static void CreateProperties(TestResultInfo result, object testCaseObj)
{
- if (result.TestCase is not { } testCase)
+ if (testCaseObj == null)
+ {
+ return;
+ }
+
+ // Use reflection to avoid hard reference to Microsoft.TestPlatform.ObjectModel in Core assembly.
+ var testCaseType = testCaseObj.GetType();
+ var propertiesProp = testCaseType.GetProperty("Properties");
+ var propertiesValue = propertiesProp?.GetValue(testCaseObj) as System.Collections.IEnumerable;
+ if (propertiesValue == null)
{
return;
}
@@ -74,13 +101,13 @@ private static void CreateProperties(TestResultInfo result)
var properties = new List>();
// Parse test traits via Trait decorator
- foreach (var property in result.TestCase.Properties)
+ foreach (var property in propertiesValue)
{
- switch (property.Id)
+ var id = property.GetType().GetProperty("Id")?.GetValue(property) as string;
+ switch (id)
{
case "Xunit.Trait":
- var propertyValue = result.TestCase.GetPropertyValue(property) as string[];
-
+ var propertyValue = InvokeGetPropertyValue(testCaseObj, property) as string[];
properties.Add(new KeyValuePair("CustomProperty", propertyValue));
break;
}
@@ -88,5 +115,11 @@ private static void CreateProperties(TestResultInfo result)
result.Properties = properties;
}
+
+ private static object InvokeGetPropertyValue(object testCase, object property)
+ {
+ var method = testCase.GetType().GetMethod("GetPropertyValue", new[] { property.GetType() });
+ return method?.Invoke(testCase, new[] { property });
+ }
}
}
\ No newline at end of file
diff --git a/src/TestLogger/TestLogger.cs b/src/TestLogger/VSTest/TestLogger.cs
similarity index 94%
rename from src/TestLogger/TestLogger.cs
rename to src/TestLogger/VSTest/TestLogger.cs
index 69789999..12e5a5fc 100644
--- a/src/TestLogger/TestLogger.cs
+++ b/src/TestLogger/VSTest/TestLogger.cs
@@ -1,7 +1,7 @@
// Copyright (c) Spekt Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-namespace Spekt.TestLogger
+namespace Spekt.TestLogger.VSTest
{
using System;
using System.Collections.Generic;
@@ -10,11 +10,11 @@ namespace Spekt.TestLogger
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.Platform;
+ using Spekt.TestLogger.VSTest.Core;
///
/// Base test logger implementation.
/// This implementation is VSTest-specific.
- /// The Microsoft.Testing.Platform implementation is .
///
public abstract class TestLogger : ITestLoggerWithParameters
{
@@ -59,7 +59,7 @@ public void Initialize(TestLoggerEvents events, string testResultsDirPath)
var config = new Dictionary
{
- { DefaultLoggerParameterNames.TestRunDirectory, testResultsDirPath },
+ { Spekt.TestLogger.Core.DefaultLoggerParameterNames.TestRunDirectory, testResultsDirPath },
{ LoggerConfiguration.LogFilePathKey, Path.Combine(testResultsDirPath, this.DefaultTestResultFile) }
};
@@ -102,8 +102,9 @@ private void CreateTestRun(TestLoggerEvents events, LoggerConfiguration config)
.WithConsoleOutput(this.consoleOutput)
.WithStore(this.resultStore)
.WithSerializer(this.resultSerializer)
- .Subscribe(events)
.Build();
+
+ this.testRun.Subscribe(events);
}
}
}
diff --git a/src/TestLogger/VSTest/Utilities/AttachmentSetExtensions.cs b/src/TestLogger/VSTest/Utilities/AttachmentSetExtensions.cs
new file mode 100644
index 00000000..09d5e23b
--- /dev/null
+++ b/src/TestLogger/VSTest/Utilities/AttachmentSetExtensions.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.VSTest.Utilities
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using Spekt.TestLogger.Core;
+
+ public static class AttachmentSetExtensions
+ {
+ public static IEnumerable ToAttachments(this Microsoft.VisualStudio.TestPlatform.ObjectModel.AttachmentSet attachmentSet, string baseDirectory, bool makeRelativePaths)
+ {
+ if (makeRelativePaths && !string.IsNullOrEmpty(baseDirectory))
+ {
+ return attachmentSet.Attachments.Select(a =>
+ {
+ var attachmentPath = GetPathFromUri(a.Uri);
+ var relativePath = MakeRelativePath(baseDirectory, attachmentPath);
+ return new TestAttachmentInfo(relativePath, a.Description);
+ });
+ }
+
+ return attachmentSet.Attachments.Select(a => new
+ TestAttachmentInfo(GetPathFromUri(a.Uri), a.Description));
+ }
+
+ private static string MakeRelativePath(string baseDirectoryPath, string targetPath)
+ {
+ if (!baseDirectoryPath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) &&
+ !baseDirectoryPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar.ToString()))
+ {
+ baseDirectoryPath += System.IO.Path.DirectorySeparatorChar;
+ }
+
+ if (!System.IO.Path.IsPathRooted(targetPath) ||
+ !string.Equals(System.IO.Path.GetPathRoot(baseDirectoryPath), System.IO.Path.GetPathRoot(targetPath), System.StringComparison.OrdinalIgnoreCase))
+ {
+ return targetPath;
+ }
+
+ var baseUri = new System.Uri(baseDirectoryPath);
+ var targetUri = new System.Uri(targetPath);
+
+ var relativeUri = baseUri.MakeRelativeUri(targetUri);
+ var relativePath = System.Uri.UnescapeDataString(relativeUri.ToString());
+
+ return relativePath.Replace('/', System.IO.Path.DirectorySeparatorChar);
+ }
+
+ private static string GetPathFromUri(Uri uri)
+ {
+ try
+ {
+ return uri.LocalPath;
+ }
+ catch (InvalidOperationException)
+ {
+ return uri.OriginalString;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Xunit.Xml.Package/Xunit.Xml.Package.csproj b/src/Xunit.Xml.Package/Xunit.Xml.Package.csproj
index 626708cb..22a00e0a 100644
--- a/src/Xunit.Xml.Package/Xunit.Xml.Package.csproj
+++ b/src/Xunit.Xml.Package/Xunit.Xml.Package.csproj
@@ -35,9 +35,13 @@
packageIcon.png
-
-
-
+
+
+
+
+
+
+
@@ -65,6 +69,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Xunit.Xml.Package/XunitXml.TestLogger.nuspec b/src/Xunit.Xml.Package/XunitXml.TestLogger.nuspec
index 9d292371..4f13073a 100644
--- a/src/Xunit.Xml.Package/XunitXml.TestLogger.nuspec
+++ b/src/Xunit.Xml.Package/XunitXml.TestLogger.nuspec
@@ -13,12 +13,14 @@
packageIcon.png
-
-
+
+
+
+
-
+
diff --git a/src/Xunit.Xml.Package/XunitXml.TestLogger.props b/src/Xunit.Xml.Package/XunitXml.TestLogger.props
index d0c0978d..db018857 100644
--- a/src/Xunit.Xml.Package/XunitXml.TestLogger.props
+++ b/src/Xunit.Xml.Package/XunitXml.TestLogger.props
@@ -1,20 +1,20 @@
-
- Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger.dll
+
+ Spekt.TestLogger.VSTest.dll
PreserveNewest
False
-
- Spekt.TestLogger.dll
+
+ Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger.dll
PreserveNewest
False
-
-
+
+
XunitXml.TestLogger
diff --git a/src/Xunit.Xml.TestLogger/Assembly.cs b/src/Xunit.Xml.TestLogger/Assembly.cs
index fc946f36..e8eeabf0 100644
--- a/src/Xunit.Xml.TestLogger/Assembly.cs
+++ b/src/Xunit.Xml.TestLogger/Assembly.cs
@@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
+#if !DEBUG
[assembly: ExcludeFromCodeCoverage]
namespace System.Diagnostics.CodeAnalysis;
@@ -16,3 +17,4 @@ internal sealed class ExcludeFromCodeCoverageAttribute : Attribute
{
public ExcludeFromCodeCoverageAttribute() { }
}
+#endif
diff --git a/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.MTP.csproj b/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.MTP.csproj
new file mode 100644
index 00000000..4c5a4930
--- /dev/null
+++ b/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.MTP.csproj
@@ -0,0 +1,29 @@
+
+
+
+ netstandard2.0
+ Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger
+ $(PackageVersion)
+ false
+ false
+ true
+ false
+
+
+
+ Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.csproj b/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.VSTest.csproj
similarity index 60%
rename from src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.csproj
rename to src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.VSTest.csproj
index 51a96e00..32297884 100644
--- a/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.csproj
+++ b/src/Xunit.Xml.TestLogger/Xunit.Xml.TestLogger.VSTest.csproj
@@ -5,6 +5,7 @@
Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger
$(PackageVersion)
false
+ false
@@ -12,11 +13,18 @@
-
+
-
+
+
+
+
+
+
+
+
diff --git a/src/Xunit.Xml.TestLogger/XunitTestReporter.cs b/src/Xunit.Xml.TestLogger/XunitTestReporter.cs
index bc96585d..ad617f6e 100644
--- a/src/Xunit.Xml.TestLogger/XunitTestReporter.cs
+++ b/src/Xunit.Xml.TestLogger/XunitTestReporter.cs
@@ -6,6 +6,7 @@ namespace Spekt.TestReporter.Xunit
using System;
using Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp;
internal sealed class XunitTestReporter : TestReporter
{
diff --git a/src/Xunit.Xml.TestLogger/XunitTestReporterExtensions.cs b/src/Xunit.Xml.TestLogger/XunitTestReporterExtensions.cs
index 98d42765..e89cfdd0 100644
--- a/src/Xunit.Xml.TestLogger/XunitTestReporterExtensions.cs
+++ b/src/Xunit.Xml.TestLogger/XunitTestReporterExtensions.cs
@@ -5,6 +5,7 @@ namespace Spekt.TestReporter.Xunit
{
using Microsoft.Testing.Platform.Builder;
using Microsoft.Testing.Platform.Extensions;
+ using Spekt.TestLogger.Mtp;
public static class XunitTestReporterExtensions
{
diff --git a/src/Xunit.Xml.TestLogger/XunitXmlSerializer.cs b/src/Xunit.Xml.TestLogger/XunitXmlSerializer.cs
index 5a850361..2583fc52 100644
--- a/src/Xunit.Xml.TestLogger/XunitXmlSerializer.cs
+++ b/src/Xunit.Xml.TestLogger/XunitXmlSerializer.cs
@@ -10,7 +10,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger
using System.Linq;
using System.Text;
using System.Xml.Linq;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Spekt.TestLogger.Core;
public class XunitXmlSerializer : ITestResultSerializer
diff --git a/src/Xunit.Xml.TestLogger/XunitXmlTestLogger.cs b/src/Xunit.Xml.TestLogger/XunitXmlTestLogger.cs
index 299e6c3f..e69a157d 100644
--- a/src/Xunit.Xml.TestLogger/XunitXmlTestLogger.cs
+++ b/src/Xunit.Xml.TestLogger/XunitXmlTestLogger.cs
@@ -4,7 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.Extension.Xunit.Xml.TestLogger
{
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
- using Spekt.TestLogger;
+ using Spekt.TestLogger.VSTest;
[FriendlyName(FriendlyName)]
[ExtensionUri(ExtensionUri)]
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnit.Xml.TestLogger.AcceptanceTests.csproj b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnit.Xml.TestLogger.AcceptanceTests.csproj
index 4299bab8..4b40d54e 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnit.Xml.TestLogger.AcceptanceTests.csproj
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnit.Xml.TestLogger.AcceptanceTests.csproj
@@ -10,7 +10,7 @@
-
+
@@ -28,15 +28,22 @@
+
+
+
+
+
-
+
+
+
-
+
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerAcceptanceTests.cs
index c7f790e6..4f886d8f 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerAcceptanceTests.cs
@@ -31,14 +31,13 @@ public static void SuiteInitialize(TestContext context)
var vstestLoggerArgs = $"junit;LogFilePath={VstestResultsFile}";
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute(AssetName, vstestLoggerArgs, collectCoverage: false, VstestResultsFile, isMTP: false);
// Run MTP tests
var mtpLoggerArgs = $"--report-spekt-junit --report-spekt-junit-filename {MtpResultsFile}";
_ = DotnetTestFixture
.Create()
- .WithBuild()
+ .WithNoBuild()
.Execute(AssetName, mtpLoggerArgs, collectCoverage: false, MtpResultsFile, isMTP: true);
}
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerFormatOptionsAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerFormatOptionsAcceptanceTests.cs
index 977d5636..88390e64 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerFormatOptionsAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerFormatOptionsAcceptanceTests.cs
@@ -33,7 +33,6 @@ public void FailureBodyFormat_Default_ShouldntStartWithMessage()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "failure-default-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -61,7 +60,6 @@ public void FailureBodyFormat_Verbose_ShouldNotContainConsoleOut()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "failure-verbose-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -81,7 +79,6 @@ public void FailureBodyFormat_Verbose_ShouldStartWithMessage()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "failure-verbose-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -110,7 +107,6 @@ public void FailureBodyFormat_Verbose_ShouldContainConsoleOut()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "failure-verbose-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -130,7 +126,6 @@ public void MethodFormat_Default_ShouldBeOnlyTheMethod()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "method-default-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -156,7 +151,6 @@ public void MethodFormat_Class_ShouldIncludeClass()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "method-class-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -184,7 +178,6 @@ public void MethodFormat_Full_ShouldIncludeNamespaceAndClass()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "method-full-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerNetFullAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerNetFullAcceptanceTests.cs
index 3b82b12b..a680434d 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerNetFullAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerNetFullAcceptanceTests.cs
@@ -42,7 +42,6 @@ public static void SuiteInitialize(TestContext context)
// Enable reporting of internal properties in the adapter using runsettings
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute(AssetName, loggerArgs, collectCoverage: false, "test-results.xml");
}
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerPathTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerPathTests.cs
index 1687b8d7..2da0b88d 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerPathTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerPathTests.cs
@@ -36,7 +36,6 @@ public void TestRunWithLoggerAndFilePathShouldCreateResultsFile()
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetMulti.Tests", loggerArgs, collectCoverage: false, "test-results.xml");
foreach (string resultFile in testResultFiles)
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerResultDirectoryAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerResultDirectoryAcceptanceTests.cs
index 06a4e570..c0a84ba0 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerResultDirectoryAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerResultDirectoryAcceptanceTests.cs
@@ -23,7 +23,6 @@ public void TestRunWithResultDirectoryAndFileNameShouldCreateResultsFile()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.WithResultsDirectory("artifacts")
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "test-results.xml");
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerStoreConsoleOutputOptionsAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerStoreConsoleOutputOptionsAcceptanceTests.cs
index c29c4206..6a2a5dbd 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerStoreConsoleOutputOptionsAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerStoreConsoleOutputOptionsAcceptanceTests.cs
@@ -26,7 +26,6 @@ public void StoreConsoleOutput_Default_ContainsConsoleOut()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-default-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -51,7 +50,6 @@ public void StoreConsoleOutput_Default_ContainsConsoleErr()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-default-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -72,7 +70,6 @@ public void StoreConsoleOutput_True_ContainsConsoleOut()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-true-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -97,7 +94,6 @@ public void StoreConsoleOutput_True_ContainsConsoleErr()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-true-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -118,7 +114,6 @@ public void StoreConsoleOutput_False_DoesNotContainConsoleOut()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-false-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -140,7 +135,6 @@ public void StoreConsoleOutput_False_DoesNotContainConsoleErr()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-false-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -159,7 +153,6 @@ public void StoreConsoleOutput_TestSuite_ContainsConsoleOutOnlyForTestSuite()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-testsuite-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -184,7 +177,6 @@ public void StoreConsoleOutput_TestSuite_ContainsConsoleErrOnlyForTestSuite()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-testsuite-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -204,7 +196,6 @@ public void StoreConsoleOutput_TestCase_ContainsConsoleOutOnlyForTestCase()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-testcase-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
@@ -226,7 +217,6 @@ public void StoreConsoleOutput_TestCase_ContainsConsoleErrOnlyForTestCase()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("JUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "output-testcase-test-results.xml");
XDocument resultsXml = XDocument.Load(resultsFile);
diff --git a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerXUnitAcceptanceTests.cs b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerXUnitAcceptanceTests.cs
index 1e91a85c..c569c3b8 100644
--- a/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerXUnitAcceptanceTests.cs
+++ b/test/JUnit.Xml.TestLogger.AcceptanceTests/JUnitTestLoggerXUnitAcceptanceTests.cs
@@ -33,14 +33,13 @@ public static void SuiteInitialize(TestContext context)
var vstestLoggerArgs = $"junit;LogFilePath={VstestResultsFile}";
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute(AssetName, vstestLoggerArgs, collectCoverage: false, VstestResultsFile, isMTP: false);
// Run MTP tests
var mtpLoggerArgs = $"--report-spekt-junit --report-spekt-junit-filename {MtpResultsFile}";
_ = DotnetTestFixture
.Create()
- .WithBuild()
+ .WithNoBuild()
.Execute(AssetName, mtpLoggerArgs, collectCoverage: false, MtpResultsFile, isMTP: true);
}
diff --git a/test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj b/test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj
index 58162069..7608818e 100644
--- a/test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj
+++ b/test/JUnit.Xml.TestLogger.UnitTests/JUnit.Xml.TestLogger.UnitTests.csproj
@@ -6,6 +6,9 @@
true
false
true
+ Exe
+ true
+ true
@@ -13,12 +16,17 @@
+
+
+
+
+
-
-
+
+
diff --git a/test/JUnit.Xml.TestLogger.UnitTests/JUnitXmlTestSerializerTests.cs b/test/JUnit.Xml.TestLogger.UnitTests/JUnitXmlTestSerializerTests.cs
index 9bc6e252..7ae46bd6 100644
--- a/test/JUnit.Xml.TestLogger.UnitTests/JUnitXmlTestSerializerTests.cs
+++ b/test/JUnit.Xml.TestLogger.UnitTests/JUnitXmlTestSerializerTests.cs
@@ -16,7 +16,11 @@ namespace JUnit.Xml.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.Utilities;
+ using TestMessageLevel = Spekt.TestLogger.Core.TestMessageLevel;
+ using TestOutcome = Spekt.TestLogger.Core.TestOutcome;
+ using TestResultMessage = Spekt.TestLogger.Core.TestResultMessage;
using TestSuite = Microsoft.VisualStudio.TestPlatform.Extension.Junit.Xml.TestLogger.JunitXmlSerializer.TestSuite;
+ using Trait = Spekt.TestLogger.Core.Trait;
[TestClass]
public class JUnitXmlTestSerializerTests
@@ -296,8 +300,7 @@ private static TestResultInfo CreateTestResultInfo(
messages ?? new List(),
new List(),
new List(),
- "executor://dummy",
- null);
+ "executor://dummy");
}
private static XElement SerializeAndGetTestCaseElement(JunitXmlSerializer serializer, TestResultInfo result)
diff --git a/test/Json.TestLogger.Package/Json.TestLogger.nuspec b/test/Json.TestLogger.Package/Json.TestLogger.nuspec
index 84439ff5..b088b523 100644
--- a/test/Json.TestLogger.Package/Json.TestLogger.nuspec
+++ b/test/Json.TestLogger.Package/Json.TestLogger.nuspec
@@ -13,7 +13,7 @@
-
+
diff --git a/test/Json.TestLogger.Package/Json.TestLogger.props b/test/Json.TestLogger.Package/Json.TestLogger.props
index 66c37f09..c5a5e203 100644
--- a/test/Json.TestLogger.Package/Json.TestLogger.props
+++ b/test/Json.TestLogger.Package/Json.TestLogger.props
@@ -11,8 +11,8 @@
PreserveNewest
False
-
- Spekt.TestLogger.dll
+
+ Spekt.TestLogger.VSTest.dll
PreserveNewest
False
diff --git a/test/Json.TestLogger.TestAdapter/Json.TestLogger.TestAdapter.csproj b/test/Json.TestLogger.TestAdapter/Json.TestLogger.TestAdapter.csproj
index 781a7ced..9693d7b8 100644
--- a/test/Json.TestLogger.TestAdapter/Json.TestLogger.TestAdapter.csproj
+++ b/test/Json.TestLogger.TestAdapter/Json.TestLogger.TestAdapter.csproj
@@ -14,16 +14,16 @@
JsonTestLogger.cs
-
+
JsonTestResultSerializer.cs
-
+
InputSanitizerJson.cs
-
+
diff --git a/test/Json.TestLogger/Json.TestLogger.csproj b/test/Json.TestLogger/Json.TestLogger.csproj
index 13fda1a8..dceedcde 100644
--- a/test/Json.TestLogger/Json.TestLogger.csproj
+++ b/test/Json.TestLogger/Json.TestLogger.csproj
@@ -12,16 +12,16 @@
-
+
JsonTestResultSerializer.cs
-
+
InputSanitizerJson.cs
-
+
diff --git a/test/Json.TestLogger/JsonTestLogger.cs b/test/Json.TestLogger/JsonTestLogger.cs
index 086c6fba..c8c32582 100644
--- a/test/Json.TestLogger/JsonTestLogger.cs
+++ b/test/Json.TestLogger/JsonTestLogger.cs
@@ -8,7 +8,7 @@ namespace Json.TestLogger
[FriendlyName(FriendlyName)]
[ExtensionUri(ExtensionUri)]
- public class JsonTestLogger : Spekt.TestLogger.TestLogger
+ public class JsonTestLogger : Spekt.TestLogger.VSTest.TestLogger
{
///
/// Uri used to uniquely identify the logger.
diff --git a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnit.Xml.TestLogger.AcceptanceTests.csproj b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnit.Xml.TestLogger.AcceptanceTests.csproj
index b613546c..f816d7a2 100644
--- a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnit.Xml.TestLogger.AcceptanceTests.csproj
+++ b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnit.Xml.TestLogger.AcceptanceTests.csproj
@@ -10,7 +10,7 @@
-
+
@@ -27,10 +27,16 @@
+
+
+
+
-
+
+
+
diff --git a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerAcceptanceTests.cs b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerAcceptanceTests.cs
index a3ce239a..65f55886 100644
--- a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerAcceptanceTests.cs
+++ b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerAcceptanceTests.cs
@@ -26,7 +26,6 @@ public static void SuiteInitialize(TestContext context)
var vstestLoggerArgs = "nunit;LogFilePath=test-results-vstest.xml";
_ = DotnetTestFixture
.Create()
- .WithBuild()
.WithRunSettings("-- NUnit.ShowInternalProperties=true")
.Execute(AssetName, vstestLoggerArgs, collectCoverage: false, "test-results-vstest.xml", isMTP: false);
@@ -34,8 +33,7 @@ public static void SuiteInitialize(TestContext context)
var mtpLoggerArgs = "--report-spekt-nunit --report-spekt-nunit-filename test-results-mtp.xml";
_ = DotnetTestFixture
.Create()
- .WithBuild()
- .WithRunSettings("NUnit.ShowInternalProperties=true")
+ .WithNoBuild()
.Execute(AssetName, mtpLoggerArgs, collectCoverage: false, "test-results-mtp.xml", isMTP: true);
}
@@ -109,7 +107,7 @@ public void TestResultFileShouldContainAssemblyTestSuite(string resultFileName)
Assert.AreEqual("Failed", node.Attribute(XName.Get("result")).Value);
Assert.AreEqual("NUnit.Xml.TestLogger.NetCore.Tests.dll", node.Attribute(XName.Get("name")).Value);
- Assert.AreEqual(AssetName.ToAssetAssemblyPath("net8.0"), node.Attribute(XName.Get("fullname")).Value);
+ Assert.AreEqual(AssetName.ToAssetAssemblyPath("net8.0", resultFileName.Contains("mtp")), node.Attribute(XName.Get("fullname")).Value);
var startTimeStr = node.Attribute(XName.Get("start-time"))?.Value;
var endTimeStr = node.Attribute(XName.Get("end-time"))?.Value;
diff --git a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerNetFullAcceptanceTests.cs b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerNetFullAcceptanceTests.cs
index 3bc4b801..3ed74e87 100644
--- a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerNetFullAcceptanceTests.cs
+++ b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerNetFullAcceptanceTests.cs
@@ -42,7 +42,6 @@ public static void SuiteInitialize(TestContext context)
// Enable reporting of internal properties in the adapter using runsettings
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute(AssetName, loggerArgs, collectCoverage: false, "test-results.xml");
}
diff --git a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerPathTests.cs b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerPathTests.cs
index d2e6a074..e28a4458 100644
--- a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerPathTests.cs
+++ b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerPathTests.cs
@@ -31,7 +31,6 @@ public void TestRunWithLoggerAndFilePathShouldCreateResultsFile()
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute("NUnit.Xml.TestLogger.NetMulti.Tests", loggerArgs, collectCoverage: false, "test-results.xml");
foreach (string resultFile in testResultFiles)
diff --git a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerResultDirectoryAcceptanceTests.cs b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerResultDirectoryAcceptanceTests.cs
index 6617c250..974f2b79 100644
--- a/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerResultDirectoryAcceptanceTests.cs
+++ b/test/NUnit.Xml.TestLogger.AcceptanceTests/NUnitTestLoggerResultDirectoryAcceptanceTests.cs
@@ -17,7 +17,6 @@ public void TestRunWithResultDirectoryAndFileNameShouldCreateResultsFile()
var resultsFile = DotnetTestFixture
.Create()
- .WithBuild()
.WithResultsDirectory("artifacts")
.Execute("NUnit.Xml.TestLogger.NetCore.Tests", loggerArgs, collectCoverage: false, "test-results.xml");
diff --git a/test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj b/test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj
index a28ce267..fc1fad39 100644
--- a/test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj
+++ b/test/NUnit.Xml.TestLogger.UnitTests/NUnit.Xml.TestLogger.UnitTests.csproj
@@ -6,6 +6,9 @@
true
false
true
+ Exe
+ true
+ true
@@ -13,12 +16,17 @@
+
+
+
+
+
-
-
+
+
diff --git a/test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj b/test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj
index 78df04f8..6f1ba13f 100644
--- a/test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj
+++ b/test/TestLogger.AcceptanceTests/TestLogger.AcceptanceTests.csproj
@@ -28,6 +28,19 @@
Always
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestLogger.AcceptanceTests/TestLoggerAcceptanceTests.cs b/test/TestLogger.AcceptanceTests/TestLoggerAcceptanceTests.cs
index 0c65d8b7..d6b6e985 100644
--- a/test/TestLogger.AcceptanceTests/TestLoggerAcceptanceTests.cs
+++ b/test/TestLogger.AcceptanceTests/TestLoggerAcceptanceTests.cs
@@ -57,6 +57,11 @@ private Task VerifyAssembly(string testAssembly, string loggerArgs, string addit
var pathForwardSlashes = m.Groups[1].Captures[0].Value.Replace('\\', '/');
x = pathForwardSlashes;
x = x.Replace("//", "/");
+
+ // Test runner flavor (vstest/mtp) is an implementation detail of the
+ // build layout; normalize it away so snapshots stay stable.
+ x = x.Replace("bin/Debug/vstest/", "bin/Debug/");
+ x = x.Replace("bin/Debug/mtp/", "bin/Debug/");
}
else if (prefixedMatch.IsMatch(x))
{
@@ -78,7 +83,7 @@ private Task VerifyAssembly(string testAssembly, string loggerArgs, string addit
// Collect coverage will attach a runlevel attachment.
var collectCoverage = testAssembly.Contains("XUnit.NetCore");
- var resultsFile = DotnetTestFixture.Create().WithBuild().Execute(testAssembly, loggerArgs, collectCoverage, "test-results.json");
+ var resultsFile = DotnetTestFixture.Create().Execute(testAssembly, loggerArgs, collectCoverage, "test-results.json");
var testReport = JsonConvert.DeserializeObject(File.ReadAllText(resultsFile));
// Using VerifyJson with serialized JSON to avoid incompatibility in object serialization
diff --git a/test/TestLogger.Fixtures/DotnetTestFixture.cs b/test/TestLogger.Fixtures/DotnetTestFixture.cs
index f06827b9..ecf71c4b 100644
--- a/test/TestLogger.Fixtures/DotnetTestFixture.cs
+++ b/test/TestLogger.Fixtures/DotnetTestFixture.cs
@@ -6,12 +6,13 @@ namespace TestLogger.Fixtures
using System;
using System.Diagnostics;
using System.IO;
+ using System.Text;
public class DotnetTestFixture
{
private const string NetcoreVersion = "net8.0";
- private bool buildProject = false;
private bool cleanProject = false;
+ private bool noBuild = false;
private string relativeResultsDirectory = string.Empty;
private string runSettingsSuffix = string.Empty;
@@ -20,7 +21,20 @@ public class DotnetTestFixture
public DotnetTestFixture WithBuild(bool cleanProject = true)
{
this.cleanProject = cleanProject;
- this.buildProject = true;
+ this.noBuild = false;
+ return this;
+ }
+
+ ///
+ /// Runs the test leg with --no-build against pre-built outputs.
+ /// Only use where --no-build is known to work (MTP legs); VSTest legs
+ /// must build (incrementally) because vstest.console rejects --no-build runs.
+ ///
+ /// The current fixture instance.
+ public DotnetTestFixture WithNoBuild()
+ {
+ this.cleanProject = false;
+ this.noBuild = true;
return this;
}
@@ -49,7 +63,7 @@ public string Execute(string assemblyName, string loggerArgs, bool collectCovera
UseShellExecute = false,
RedirectStandardOutput = true,
FileName = "dotnet",
- Arguments = $"clean \"{assemblyName.ToAssetDirectoryPath()}\\{assemblyName}.csproj\""
+ Arguments = $"clean \"{assemblyName.ToAssetDirectoryPath()}\\{assemblyName}.csproj\"{(isMTP ? " -p:IsMTP=true" : string.Empty)}"
}
};
cleanProcess.Start();
@@ -72,8 +86,9 @@ public string Execute(string assemblyName, string loggerArgs, bool collectCovera
File.Delete(resultsFile);
}
- // Run dotnet test with logger
- var buildArgs = this.buildProject ? string.Empty : "--no-build";
+ // Run dotnet test with logger. --no-build is opt-in (WithNoBuild) because
+ // vstest.console rejects --no-build runs; default is an incremental build.
+ var buildArgs = this.noBuild ? "--no-build" : string.Empty;
var resultDirectoryArgs = string.IsNullOrEmpty(this.relativeResultsDirectory) ? string.Empty : $"--results-directory \"{resultsDirectory}\"";
if (isMTP)
@@ -120,17 +135,36 @@ public string Execute(string assemblyName, string loggerArgs, bool collectCovera
dotnet.StartInfo.Arguments += $" --collect:\"XPlat Code Coverage\" --settings \"{coverletRunSettingsPath}\"";
}
- this.LogTestAssetOutDir(assemblyName);
+ this.LogTestAssetOutDir(assemblyName, isMTP);
Console.WriteLine("\n\n## Test run arguments: dotnet " + dotnet.StartInfo.Arguments);
- // To avoid deadlocks, always read the output stream first and then wait.
+ // Use async reads to avoid deadlock when child process writes heavily to stderr
+ // while parent blocks on stdout ReadToEnd().
+ var outputBuilder = new StringBuilder();
+ var errorBuilder = new StringBuilder();
+ dotnet.OutputDataReceived += (sender, e) =>
+ {
+ if (e.Data != null)
+ {
+ outputBuilder.AppendLine(e.Data);
+ }
+ };
+ dotnet.ErrorDataReceived += (sender, e) =>
+ {
+ if (e.Data != null)
+ {
+ errorBuilder.AppendLine(e.Data);
+ }
+ };
dotnet.Start();
-
- var output = dotnet.StandardOutput.ReadToEnd();
- var error = dotnet.StandardError.ReadToEnd();
+ dotnet.BeginOutputReadLine();
+ dotnet.BeginErrorReadLine();
dotnet.WaitForExit();
+ var output = outputBuilder.ToString();
+ var error = errorBuilder.ToString();
+
Console.WriteLine("\n\n ## Test run output\n" + output);
if (!string.IsNullOrEmpty(error))
{
@@ -140,14 +174,16 @@ public string Execute(string assemblyName, string loggerArgs, bool collectCovera
return resultsFile;
}
- private void LogTestAssetOutDir(string assemblyName)
+ private void LogTestAssetOutDir(string assemblyName, bool isMTP)
{
// Log the contents of test output directory. Useful to verify if the logger is copied
Console.WriteLine("\n\n## Contents of test output directory:");
+ var flavor = isMTP ? "mtp" : "vstest";
+
// Create directory so test does not fail under windows.
- Directory.CreateDirectory(Path.Combine(assemblyName, $"bin/Debug/{NetcoreVersion}"));
- foreach (var f in Directory.GetFiles(Path.Combine(assemblyName, $"bin/Debug/{NetcoreVersion}")))
+ Directory.CreateDirectory(Path.Combine(assemblyName, $"bin/Debug/{flavor}/{NetcoreVersion}"));
+ foreach (var f in Directory.GetFiles(Path.Combine(assemblyName, $"bin/Debug/{flavor}/{NetcoreVersion}")))
{
Console.WriteLine(" " + f);
}
diff --git a/test/TestLogger.Fixtures/TestAssetExtensions.cs b/test/TestLogger.Fixtures/TestAssetExtensions.cs
index d2f6face..e7a9e496 100644
--- a/test/TestLogger.Fixtures/TestAssetExtensions.cs
+++ b/test/TestLogger.Fixtures/TestAssetExtensions.cs
@@ -30,15 +30,18 @@ public static string ToAssetDirectoryPath(this string assetName)
/// Gets the full path to test asset assembly file.
///
/// Name of the test asset.
+ /// Target framework moniker, e.g. net8.0.
+ /// Whether the MTP-flavored (rather than VSTest-flavored) output is wanted.
/// Full path to test assembly.
- public static string ToAssetAssemblyPath(this string assetName, string targetFrameworkVersion)
+ public static string ToAssetAssemblyPath(this string assetName, string targetFrameworkVersion, bool isMTP)
{
#if DEBUG
var config = "Debug";
#else
var config = "Release";
#endif
- return Path.Combine(assetName.ToAssetDirectoryPath(), "bin", config, targetFrameworkVersion, $"{assetName}.dll");
+ var flavor = isMTP ? "mtp" : "vstest";
+ return Path.Combine(assetName.ToAssetDirectoryPath(), "bin", config, flavor, targetFrameworkVersion, $"{assetName}.dll");
}
public static bool IsMTP(this TestContext context, Type type)
diff --git a/test/TestLogger.UnitTests/InputSanitizerXmlTests.cs b/test/TestLogger.Mtp.UnitTests/InputSanitizerXmlTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/InputSanitizerXmlTests.cs
rename to test/TestLogger.Mtp.UnitTests/InputSanitizerXmlTests.cs
diff --git a/test/TestLogger.UnitTests/LegacyTestCaseNameParserTests.cs b/test/TestLogger.Mtp.UnitTests/LegacyTestCaseNameParserTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/LegacyTestCaseNameParserTests.cs
rename to test/TestLogger.Mtp.UnitTests/LegacyTestCaseNameParserTests.cs
diff --git a/test/TestLogger.UnitTests/Platform/BaseFileSystemTests.cs b/test/TestLogger.Mtp.UnitTests/Platform/BaseFileSystemTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/Platform/BaseFileSystemTests.cs
rename to test/TestLogger.Mtp.UnitTests/Platform/BaseFileSystemTests.cs
diff --git a/test/TestLogger.UnitTests/Platform/ConsoleOutputTests.cs b/test/TestLogger.Mtp.UnitTests/Platform/ConsoleOutputTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/Platform/ConsoleOutputTests.cs
rename to test/TestLogger.Mtp.UnitTests/Platform/ConsoleOutputTests.cs
diff --git a/test/TestLogger.UnitTests/Platform/FakeFileSystemTests.cs b/test/TestLogger.Mtp.UnitTests/Platform/FakeFileSystemTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/Platform/FakeFileSystemTests.cs
rename to test/TestLogger.Mtp.UnitTests/Platform/FakeFileSystemTests.cs
diff --git a/test/TestLogger.UnitTests/Platform/FileSystemTests.cs b/test/TestLogger.Mtp.UnitTests/Platform/FileSystemTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/Platform/FileSystemTests.cs
rename to test/TestLogger.Mtp.UnitTests/Platform/FileSystemTests.cs
diff --git a/test/TestLogger.UnitTests/TestAttachmentInfoTests.cs b/test/TestLogger.Mtp.UnitTests/TestAttachmentInfoTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestAttachmentInfoTests.cs
rename to test/TestLogger.Mtp.UnitTests/TestAttachmentInfoTests.cs
diff --git a/test/TestLogger.UnitTests/TestCaseNameParserTests.cs b/test/TestLogger.Mtp.UnitTests/TestCaseNameParserTests.cs
similarity index 99%
rename from test/TestLogger.UnitTests/TestCaseNameParserTests.cs
rename to test/TestLogger.Mtp.UnitTests/TestCaseNameParserTests.cs
index 605e3b25..8ade4d80 100644
--- a/test/TestLogger.UnitTests/TestCaseNameParserTests.cs
+++ b/test/TestLogger.Mtp.UnitTests/TestCaseNameParserTests.cs
@@ -11,6 +11,7 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
[TestClass]
diff --git a/test/TestLogger.UnitTests/TestDoubles/FakeConsoleOutput.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/FakeConsoleOutput.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/FakeConsoleOutput.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/FakeConsoleOutput.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/FakeFileSystem.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/FakeFileSystem.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/FakeFileSystem.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/FakeFileSystem.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/InputSanitizerJson.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/InputSanitizerJson.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/InputSanitizerJson.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/InputSanitizerJson.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/JsonTestResultSerializer.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/JsonTestResultSerializer.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/JsonTestResultSerializer.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/JsonTestResultSerializer.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/MockCommandLineOptions.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/MockCommandLineOptions.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/MockCommandLineOptions.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/MockCommandLineOptions.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/MockExtensions.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/MockExtensions.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/MockExtensions.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/MockExtensions.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/TestableTestReporter.cs b/test/TestLogger.Mtp.UnitTests/TestDoubles/TestableTestReporter.cs
similarity index 93%
rename from test/TestLogger.UnitTests/TestDoubles/TestableTestReporter.cs
rename to test/TestLogger.Mtp.UnitTests/TestDoubles/TestableTestReporter.cs
index fa4bba95..d7ac4437 100644
--- a/test/TestLogger.UnitTests/TestDoubles/TestableTestReporter.cs
+++ b/test/TestLogger.Mtp.UnitTests/TestDoubles/TestableTestReporter.cs
@@ -11,7 +11,7 @@ namespace Spekt.TestLogger.UnitTests.TestDoubles
///
/// Testable implementation of TestReporter for unit testing.
///
- public class TestableTestReporter : Spekt.TestReporter.TestReporter
+ public class TestableTestReporter : Spekt.TestLogger.Mtp.TestReporter
{
public TestableTestReporter(IServiceProvider serviceProvider, IExtension extension)
: base(serviceProvider, extension, "junit")
diff --git a/test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj b/test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj
new file mode 100644
index 00000000..75bc172c
--- /dev/null
+++ b/test/TestLogger.Mtp.UnitTests/TestLogger.Mtp.UnitTests.csproj
@@ -0,0 +1,36 @@
+
+
+
+ net10.0
+ true
+ true
+ false
+ true
+ Exe
+ true
+ true
+
+
+
+ Spekt.TestLogger.UnitTests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestLogger.UnitTests/TestReporterCommandLineProviderTests.cs b/test/TestLogger.Mtp.UnitTests/TestReporterCommandLineProviderTests.cs
similarity index 99%
rename from test/TestLogger.UnitTests/TestReporterCommandLineProviderTests.cs
rename to test/TestLogger.Mtp.UnitTests/TestReporterCommandLineProviderTests.cs
index 5aabcde0..49725f3c 100644
--- a/test/TestLogger.UnitTests/TestReporterCommandLineProviderTests.cs
+++ b/test/TestLogger.Mtp.UnitTests/TestReporterCommandLineProviderTests.cs
@@ -11,7 +11,7 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Extensions.CommandLine;
using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Spekt.TestReporter;
+ using Spekt.TestLogger.Mtp;
[TestClass]
public class TestReporterCommandLineProviderTests
diff --git a/test/TestLogger.UnitTests/TestReporterTests.cs b/test/TestLogger.Mtp.UnitTests/TestReporterTests.cs
similarity index 99%
rename from test/TestLogger.UnitTests/TestReporterTests.cs
rename to test/TestLogger.Mtp.UnitTests/TestReporterTests.cs
index db2a747e..08f33195 100644
--- a/test/TestLogger.UnitTests/TestReporterTests.cs
+++ b/test/TestLogger.Mtp.UnitTests/TestReporterTests.cs
@@ -9,8 +9,8 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.Mtp;
using Spekt.TestLogger.UnitTests.TestDoubles;
- using Spekt.TestReporter;
[TestClass]
public class TestReporterTests
diff --git a/test/TestLogger.UnitTests/Utilities/ArtifactExtensionsTests.cs b/test/TestLogger.Mtp.UnitTests/Utilities/ArtifactExtensionsTests.cs
similarity index 99%
rename from test/TestLogger.UnitTests/Utilities/ArtifactExtensionsTests.cs
rename to test/TestLogger.Mtp.UnitTests/Utilities/ArtifactExtensionsTests.cs
index 3a0096ab..62b165be 100644
--- a/test/TestLogger.UnitTests/Utilities/ArtifactExtensionsTests.cs
+++ b/test/TestLogger.Mtp.UnitTests/Utilities/ArtifactExtensionsTests.cs
@@ -9,6 +9,7 @@ namespace Spekt.TestLogger.UnitTests.Utilities
using Microsoft.Testing.Platform.Extensions.Messages;
using Microsoft.Testing.Platform.TestHost;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Spekt.TestLogger.Mtp.Utilities;
using Spekt.TestLogger.Utilities;
[TestClass]
diff --git a/test/TestLogger.UnitTests/Utilities/StringExtensionsTests.cs b/test/TestLogger.Mtp.UnitTests/Utilities/StringExtensionsTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/Utilities/StringExtensionsTests.cs
rename to test/TestLogger.Mtp.UnitTests/Utilities/StringExtensionsTests.cs
diff --git a/test/TestLogger.PackageTests/TestLogger.PackageTests.csproj b/test/TestLogger.PackageTests/TestLogger.PackageTests.csproj
index b09c6416..192cef00 100644
--- a/test/TestLogger.PackageTests/TestLogger.PackageTests.csproj
+++ b/test/TestLogger.PackageTests/TestLogger.PackageTests.csproj
@@ -37,7 +37,9 @@
-
+
+
+
diff --git a/test/TestLogger.PackageTests/TestLoggerPackageTests.cs b/test/TestLogger.PackageTests/TestLoggerPackageTests.cs
index e05187f4..3c95fb2a 100644
--- a/test/TestLogger.PackageTests/TestLoggerPackageTests.cs
+++ b/test/TestLogger.PackageTests/TestLoggerPackageTests.cs
@@ -28,7 +28,7 @@ public void VerifyTestRunOutput(string testAssembly, string loggerName, string c
// Collect coverage will attach a runlevel attachment.
var collectCoverage = testAssembly.Contains("XUnit.NetCore");
- var resultsFile = DotnetTestFixture.Create().WithBuild().Execute(testAssembly, loggerArgs, collectCoverage, "test-results.xml");
+ var resultsFile = DotnetTestFixture.Create().Execute(testAssembly, loggerArgs, collectCoverage, "test-results.xml");
var testReport = File.ReadAllText(resultsFile);
Assert.IsNotNull(testReport);
diff --git a/test/TestLogger.UnitTests/TestLogger.UnitTests.csproj b/test/TestLogger.UnitTests/TestLogger.UnitTests.csproj
deleted file mode 100644
index 838bb1b3..00000000
--- a/test/TestLogger.UnitTests/TestLogger.UnitTests.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- net10.0
- true
- true
- false
- true
-
-
-
- Spekt.TestLogger.UnitTests
-
-
-
-
-
-
-
-
-
-
-
-
- runtime; build; native; contentfiles; analyzers
- all
-
-
-
-
-
diff --git a/test/TestLogger.UnitTests/Builders/TestResultInfoBuilder.cs b/test/TestLogger.VSTest.UnitTests/Builders/TestResultInfoBuilder.cs
similarity index 91%
rename from test/TestLogger.UnitTests/Builders/TestResultInfoBuilder.cs
rename to test/TestLogger.VSTest.UnitTests/Builders/TestResultInfoBuilder.cs
index 8e2f278f..cb8e1a70 100644
--- a/test/TestLogger.UnitTests/Builders/TestResultInfoBuilder.cs
+++ b/test/TestLogger.VSTest.UnitTests/Builders/TestResultInfoBuilder.cs
@@ -7,6 +7,8 @@ namespace Spekt.TestLogger.UnitTests.Builders
using System.Collections.Generic;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Spekt.TestLogger.Core;
+ using TestOutcome = Spekt.TestLogger.Core.TestOutcome;
+ using Trait = Spekt.TestLogger.Core.Trait;
internal class TestResultInfoBuilder
{
@@ -34,6 +36,8 @@ internal TestResultInfoBuilder(
this.method = method;
}
+ internal TestCase TestCase => this.testCase;
+
internal TestResultInfoBuilder WithOutcome(TestOutcome outcome)
{
this.outcome = outcome;
@@ -73,7 +77,7 @@ internal TestResultInfoBuilder WithAttachment(TestAttachmentInfo attachment)
internal TestResultInfo Build()
{
- return new TestResultInfo(
+ var result = new TestResultInfo(
this.@namespace,
this.type,
this.method,
@@ -92,8 +96,9 @@ internal TestResultInfo Build()
new(),
this.attachments,
this.traits,
- "executor://dummy",
- this.testCase);
+ "executor://dummy");
+
+ return result;
}
}
}
diff --git a/test/TestLogger.UnitTests/Extensions/MSTestAdapterTests.cs b/test/TestLogger.VSTest.UnitTests/Extensions/MSTestAdapterTests.cs
similarity index 87%
rename from test/TestLogger.UnitTests/Extensions/MSTestAdapterTests.cs
rename to test/TestLogger.VSTest.UnitTests/Extensions/MSTestAdapterTests.cs
index 41607865..5780741b 100644
--- a/test/TestLogger.UnitTests/Extensions/MSTestAdapterTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/Extensions/MSTestAdapterTests.cs
@@ -10,8 +10,8 @@ namespace Spekt.TestLogger.UnitTests.Extensions
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.UnitTests.Builders;
+ using Spekt.TestLogger.VSTest.Extensions;
using TestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult;
[TestClass]
@@ -59,16 +59,14 @@ public void TransformShouldNoitOverwriteMethodEmptyValues(string displayName)
[TestMethod]
public void TransformResultShouldAddProperties()
{
- var testResults = new List
- {
- new TestResultInfoBuilder("namespace", "type", Method)
- .WithProperty("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestProperty", new[] { "c1", "c2" })
- .Build(),
- };
+ var builder = new TestResultInfoBuilder("namespace", "type", Method)
+ .WithProperty("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestProperty", new[] { "c1", "c2" });
+
+ var testResults = new List { builder.Build() };
var sut = new MSTestAdapter();
- var transformedResults = sut.TransformResults(testResults, new List());
+ var transformedResults = sut.TransformResults(testResults, new List(), builder.TestCase);
Assert.AreEqual(1, transformedResults.Count);
Assert.AreEqual(1, transformedResults[0].Properties.Count);
diff --git a/test/TestLogger.UnitTests/Extensions/NUnitTestAdapterTests.cs b/test/TestLogger.VSTest.UnitTests/Extensions/NUnitTestAdapterTests.cs
similarity index 81%
rename from test/TestLogger.UnitTests/Extensions/NUnitTestAdapterTests.cs
rename to test/TestLogger.VSTest.UnitTests/Extensions/NUnitTestAdapterTests.cs
index 6c1b2f5f..603472a7 100644
--- a/test/TestLogger.UnitTests/Extensions/NUnitTestAdapterTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/Extensions/NUnitTestAdapterTests.cs
@@ -8,8 +8,10 @@ namespace Spekt.TestLogger.UnitTests.Extensions
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.UnitTests.Builders;
+ using Spekt.TestLogger.VSTest.Extensions;
+ using TestOutcome = Spekt.TestLogger.Core.TestOutcome;
+ using Trait = Spekt.TestLogger.Core.Trait;
[TestClass]
public class NUnitTestAdapterTests
@@ -80,17 +82,15 @@ public void TransformResultShouldModifyTestWithExplicitAttributeAndNoOutcome()
[TestMethod]
public void TransformResultShouldAddPropertiesIfAvailable()
{
- var results = new List
- {
- new TestResultInfoBuilder(DummyNamespace, DummyType, DummyMethod)
- .WithOutcome(TestOutcome.Passed)
- .WithProperty("NUnit.Seed", 1)
- .WithProperty("NUnit.TestCategory", new[] { "c1", "c2" })
- .WithProperty("NUnit.Unsupported", true)
- .Build()
- };
+ var builder = new TestResultInfoBuilder(DummyNamespace, DummyType, DummyMethod)
+ .WithOutcome(TestOutcome.Passed)
+ .WithProperty("NUnit.Seed", 1)
+ .WithProperty("NUnit.TestCategory", new[] { "c1", "c2" })
+ .WithProperty("NUnit.Unsupported", true);
- var modifiedResults = this.adapter.TransformResults(results, new());
+ var results = new List { builder.Build() };
+
+ var modifiedResults = this.adapter.TransformResults(results, new(), builder.TestCase);
Assert.AreEqual(1, modifiedResults.Count);
Assert.AreEqual(2, modifiedResults[0].Properties.Count);
@@ -101,15 +101,13 @@ public void TransformResultShouldAddPropertiesIfAvailable()
[TestMethod]
public void TransformResultShouldAddProperties()
{
- var results = new List
- {
- new TestResultInfoBuilder(DummyNamespace, DummyType, DummyMethod)
- .WithOutcome(TestOutcome.Passed)
- .WithProperty("NUnit.Category", new[] { "c1", "c2" })
- .Build()
- };
+ var builder = new TestResultInfoBuilder(DummyNamespace, DummyType, DummyMethod)
+ .WithOutcome(TestOutcome.Passed)
+ .WithProperty("NUnit.Category", new[] { "c1", "c2" });
- var modifiedResults = this.adapter.TransformResults(results, new());
+ var results = new List { builder.Build() };
+
+ var modifiedResults = this.adapter.TransformResults(results, new(), builder.TestCase);
Assert.AreEqual(1, modifiedResults.Count);
Assert.AreEqual(1, modifiedResults[0].Properties.Count);
diff --git a/test/TestLogger.UnitTests/Extensions/TestAdapterFactoryTests.cs b/test/TestLogger.VSTest.UnitTests/Extensions/TestAdapterFactoryTests.cs
similarity index 97%
rename from test/TestLogger.UnitTests/Extensions/TestAdapterFactoryTests.cs
rename to test/TestLogger.VSTest.UnitTests/Extensions/TestAdapterFactoryTests.cs
index f707193a..069962a9 100644
--- a/test/TestLogger.UnitTests/Extensions/TestAdapterFactoryTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/Extensions/TestAdapterFactoryTests.cs
@@ -4,7 +4,7 @@
namespace Spekt.TestLogger.UnitTests.Extensions
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Spekt.TestLogger.Extensions;
+ using Spekt.TestLogger.VSTest.Extensions;
[TestClass]
public class TestAdapterFactoryTests
diff --git a/test/TestLogger.UnitTests/Extensions/XunitTestAdapterTests.cs b/test/TestLogger.VSTest.UnitTests/Extensions/XunitTestAdapterTests.cs
similarity index 56%
rename from test/TestLogger.UnitTests/Extensions/XunitTestAdapterTests.cs
rename to test/TestLogger.VSTest.UnitTests/Extensions/XunitTestAdapterTests.cs
index a87a6a3e..4101c379 100644
--- a/test/TestLogger.UnitTests/Extensions/XunitTestAdapterTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/Extensions/XunitTestAdapterTests.cs
@@ -10,9 +10,13 @@ namespace Spekt.TestLogger.UnitTests.Extensions
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
- using Spekt.TestLogger.Extensions;
using Spekt.TestLogger.UnitTests.Builders;
+ using Spekt.TestLogger.VSTest.Extensions;
+ using TestMessageLevel = Spekt.TestLogger.Core.TestMessageLevel;
+ using TestOutcome = Spekt.TestLogger.Core.TestOutcome;
using TestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult;
+ using TestResultMessage = Spekt.TestLogger.Core.TestResultMessage;
+ using Trait = Spekt.TestLogger.Core.Trait;
[TestClass]
public class XunitTestAdapterTests
@@ -40,6 +44,45 @@ public void TransformShouldAddReasonForSkippedTests()
Assert.AreEqual("Dummy reason", transformedResults[1].Messages[0].Text);
}
+ [TestMethod]
+ public void TransformShouldAddReasonFromResultMessageForSkippedTests()
+ {
+ var result = new TestResultInfoBuilder("N", "C", "M1")
+ .WithOutcome(TestOutcome.Skipped)
+ .WithDisplayName("N.C.M1")
+ .Build();
+ result.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, "Skipped"));
+ var xunit = new XunitTestAdapter();
+
+ var transformedResults = xunit.TransformResults(new List { result }, new List());
+
+ var reasons = transformedResults[0].Messages.Where(m => m.Category == "skipReason").ToList();
+ Assert.AreEqual(1, reasons.Count);
+ Assert.AreEqual("Skipped", reasons[0].Text);
+ }
+
+ [TestMethod]
+ public void TransformShouldNotDuplicateReasonWhenBothSourcesMatch()
+ {
+ var result = new TestResultInfoBuilder("N", "C", "M2")
+ .WithOutcome(TestOutcome.Skipped)
+ .WithDisplayName("N.C.M2")
+ .Build();
+ result.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, "Skipped"));
+ var messages = new List
+ {
+ new(TestMessageLevel.Informational, "[xUnit.net 00:00:00.6490557] N.C.M2 [SKIP]"),
+ new(TestMessageLevel.Informational, "[SKIP] Dummy reason"),
+ };
+ var xunit = new XunitTestAdapter();
+
+ var transformedResults = xunit.TransformResults(new List { result }, messages);
+
+ var reasons = transformedResults[0].Messages.Where(m => m.Category == "skipReason").ToList();
+ Assert.AreEqual(1, reasons.Count);
+ Assert.AreEqual("Dummy reason", reasons[0].Text);
+ }
+
[TestMethod]
public void TransformShouldAddParameterData()
{
@@ -61,19 +104,17 @@ public void TransformShouldAddParameterData()
[TestMethod]
public void TransformResultShouldAddProperties()
{
- var results = new List
- {
- new TestResultInfoBuilder("N", "C", "M1")
- .WithOutcome(TestOutcome.Passed)
- .WithTraits([new Trait("traitKey", "traitVal")])
- .WithProperty("Xunit.Trait", new string[] { "key", "val" })
- .Build()
- };
+ var builder = new TestResultInfoBuilder("N", "C", "M1")
+ .WithOutcome(TestOutcome.Passed)
+ .WithTraits([new Trait("traitKey", "traitVal")])
+ .WithProperty("Xunit.Trait", new string[] { "key", "val" });
+
+ var results = new List { builder.Build() };
var messages = new List();
var xunit = new XunitTestAdapter();
- var transformedResults = xunit.TransformResults(results, messages);
+ var transformedResults = xunit.TransformResults(results, messages, builder.TestCase);
Assert.AreEqual(1, transformedResults.Count);
Assert.AreEqual(1, transformedResults.Count(x => x.Method == "M1"));
diff --git a/test/TestLogger.UnitTests/LoggerConfigurationTests.cs b/test/TestLogger.VSTest.UnitTests/LoggerConfigurationTests.cs
similarity index 98%
rename from test/TestLogger.UnitTests/LoggerConfigurationTests.cs
rename to test/TestLogger.VSTest.UnitTests/LoggerConfigurationTests.cs
index 6fdbeae7..7f1a6668 100644
--- a/test/TestLogger.UnitTests/LoggerConfigurationTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/LoggerConfigurationTests.cs
@@ -8,6 +8,7 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
+ using DefaultLoggerParameterNames = Spekt.TestLogger.Core.DefaultLoggerParameterNames;
[TestClass]
public class LoggerConfigurationTests
diff --git a/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeConsoleOutput.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeConsoleOutput.cs
new file mode 100644
index 00000000..229df10d
--- /dev/null
+++ b/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeConsoleOutput.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.UnitTests.TestDoubles
+{
+ using System.Collections.Generic;
+ using Spekt.TestLogger.Platform;
+
+ public class FakeConsoleOutput : IConsoleOutput
+ {
+ public FakeConsoleOutput() => this.Messages = new List<(string, string)>();
+
+#pragma warning disable SA1414 // Tuple types in signatures should have element names
+ public List<(string, string)> Messages { get; private set; }
+#pragma warning restore SA1414 // Tuple types in signatures should have element names
+
+ public void WriteMessage(string message)
+ {
+ this.Messages.Add(("stdout", message));
+ }
+
+ public void WriteError(string message)
+ {
+ this.Messages.Add(("stderr", message));
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeFileSystem.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeFileSystem.cs
new file mode 100644
index 00000000..eb7d34c2
--- /dev/null
+++ b/test/TestLogger.VSTest.UnitTests/TestDoubles/FakeFileSystem.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.UnitTests.TestDoubles
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using Spekt.TestLogger.Platform;
+
+ public class FakeFileSystem : IFileSystem
+ {
+ private readonly Dictionary files;
+ private readonly HashSet directories;
+
+ public FakeFileSystem()
+ {
+ this.files = new Dictionary();
+ this.directories = new HashSet { Path.GetTempPath() };
+ }
+
+ public void CreateDirectory(string path)
+ {
+ this.directories.Add(path);
+ }
+
+ public bool ExistsDirectory(string path)
+ {
+ return this.directories.Contains(path);
+ }
+
+ public void RemoveDirectory(string path)
+ {
+ // Remove all paths which could be children of provided path
+ foreach (var p in this.directories.Where(p => p.StartsWith(path)).ToList())
+ {
+ this.directories.Remove(p);
+ }
+ }
+
+ public string Read(string path)
+ {
+ if (this.files.TryGetValue(path, out var content))
+ {
+ return content;
+ }
+
+ throw new ArgumentException("File does not exist.", nameof(path));
+ }
+
+ public void Write(string path, string content)
+ {
+ this.files[path] = content;
+ }
+
+ public void Delete(string path)
+ {
+ if (this.files.ContainsKey(path))
+ {
+ this.files.Remove(path);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/TestLogger.VSTest.UnitTests/TestDoubles/InputSanitizerJson.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/InputSanitizerJson.cs
new file mode 100644
index 00000000..fbb46f86
--- /dev/null
+++ b/test/TestLogger.VSTest.UnitTests/TestDoubles/InputSanitizerJson.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.UnitTests.TestDoubles
+{
+ using System.Text;
+ using Spekt.TestLogger.Core;
+
+ ///
+ /// Sanitizes JSON input. NOTE, this is not optimized code, so is currently appropriate for test use only.
+ ///
+ public class InputSanitizerJson : IInputSanitizer
+ {
+ private static readonly char[] EscapeTable;
+ private static readonly char[] EscapeCharacters = { '"', '\\', '\b', '\f', '\n', '\r', '\t' };
+
+ static InputSanitizerJson()
+ {
+ EscapeTable = new char[93];
+ EscapeTable['"'] = '"';
+ EscapeTable['\\'] = '\\';
+ EscapeTable['\b'] = 'b';
+ EscapeTable['\f'] = 'f';
+ EscapeTable['\n'] = 'n';
+ EscapeTable['\r'] = 'r';
+ EscapeTable['\t'] = 't';
+ }
+
+ public string Sanitize(string input)
+ {
+ var sb = new StringBuilder();
+
+ if (input is null)
+ {
+ return null;
+ }
+
+ // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged)
+ if (input.IndexOfAny(EscapeCharacters) == -1)
+ {
+ return input;
+ }
+
+ int safeCharacterCount = 0;
+ char[] charArray = input.ToCharArray();
+
+ for (int i = 0; i < charArray.Length; i++)
+ {
+ char c = charArray[i];
+
+ // Non ascii characters are fine, buffer them up and send them to the builder
+ // in larger chunks if possible. The escape table is a 1:1 translation table
+ // with \0 [default(char)] denoting a safe character.
+ if (c >= EscapeTable.Length || EscapeTable[c] == default(char))
+ {
+ safeCharacterCount++;
+ }
+ else
+ {
+ if (safeCharacterCount > 0)
+ {
+ sb.Append(charArray, i - safeCharacterCount, safeCharacterCount);
+ safeCharacterCount = 0;
+ }
+
+ sb.Append('\\');
+ sb.Append((char)EscapeTable[c]);
+ }
+ }
+
+ if (safeCharacterCount > 0)
+ {
+ sb.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount);
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/test/TestLogger.VSTest.UnitTests/TestDoubles/JsonTestResultSerializer.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/JsonTestResultSerializer.cs
new file mode 100644
index 00000000..a2877ae8
--- /dev/null
+++ b/test/TestLogger.VSTest.UnitTests/TestDoubles/JsonTestResultSerializer.cs
@@ -0,0 +1,170 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Spekt.TestLogger.UnitTests.TestDoubles
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using Newtonsoft.Json;
+ using Spekt.TestLogger.Core;
+
+ ///
+ /// Test logger to serialize results into json format.
+ ///
+ ///
+ /// Sample json output:
+ ///
+ /// {
+ /// "TestAssemblies": [
+ /// {
+ /// "Name": "TestAssembly",
+ /// "Fixtures": [
+ /// {
+ /// "Name": "TestClass",
+ /// "Tests": [
+ /// {
+ /// "Name": "TestMethod",
+ /// "Result": (pass|fail|skipped),
+ /// }
+ /// ]
+ /// }
+ /// ]
+ /// }
+ /// ],
+ /// "TestMessages": [
+ /// {
+ /// "Level": (0,1,2),
+ /// "Message": "MessageText"
+ /// }
+ /// ]
+ /// }
+ ///
+ ///
+ public class JsonTestResultSerializer : ITestResultSerializer
+ {
+ public IInputSanitizer InputSanitizer { get; } = new InputSanitizerJson();
+
+ public string Serialize(
+ LoggerConfiguration loggerConfiguration,
+ TestRunConfiguration runConfiguration,
+ List results,
+ List messages)
+ {
+ var res = from r in results
+ group r by r.AssemblyPath
+ into assemblies
+ orderby assemblies.Key
+ select this.CreateAssembly(assemblies);
+
+ var content = new StringBuilder();
+ new JsonSerializer().Serialize(new StringWriter(content), new TestReport(res, messages, runConfiguration.Attachments));
+ return content.ToString();
+ }
+
+ private TestAssembly CreateAssembly(
+ IGrouping resultsByAssembly)
+ {
+ return new()
+ {
+ Name = resultsByAssembly.Key,
+ Fixtures = resultsByAssembly.GroupBy(a => a.Type).Select(this.CreateFixture)
+ };
+ }
+
+ private TestFixture CreateFixture(
+ IGrouping resultsByType)
+ {
+ return new()
+ {
+ Name = resultsByType.Key,
+ Tests = resultsByType.Select(this.CreateTest)
+ };
+ }
+
+ private Test CreateTest(TestResultInfo result)
+ {
+ // Mangle output to ensure predictable report
+ var props = result
+ .Properties
+ .Select(p => p.Key == "NUnit.Seed" ? new KeyValuePair(p.Key, "1100") : p)
+ .OrderBy(p => p.Key)
+ .ToList();
+
+ // Attachments have diff path in Windows vs Linux.
+ // MSTest duplicates the path in description.
+ var attachments = result.Attachments
+ .Select(a => new TestAttachmentInfo(Path.GetFileName(a.FilePath), "dummyDescription"))
+ .ToList();
+ return new()
+ {
+ FullyQualifiedName = result.FullyQualifiedName,
+ DisplayName = result.DisplayName,
+ Namespace = result.Namespace,
+ Type = result.Type,
+ Method = result.Method,
+ Result = result.Outcome.ToString(),
+ Traits = result.Traits.Select(t => new KeyValuePair(t.Name, t.Value)).ToList(),
+ Properties = props,
+ Attachments = attachments
+ };
+ }
+
+ public class TestReport
+ {
+ public TestReport(IEnumerable testAssemblies, IEnumerable testMessages, IReadOnlyCollection attachments)
+ {
+ this.TestAssemblies = testAssemblies ?? throw new ArgumentNullException(nameof(testAssemblies));
+ this.TestMessages = testMessages ?? throw new ArgumentNullException(nameof(testMessages));
+
+ // Mangle attachments to predictable filepath
+ this.Attachments = attachments
+ .Select(a => new TestAttachmentInfo(Path.GetFileName(a.FilePath), a.Description))
+ .ToList();
+ }
+
+ public IEnumerable TestAssemblies { get; set; }
+
+ public IEnumerable TestMessages { get; set; }
+
+ public IReadOnlyCollection Attachments { get; set; }
+ }
+
+ public class TestAssembly
+ {
+ public string Name { get; set; }
+
+ public IEnumerable Fixtures { get; set; }
+ }
+
+ public class TestFixture
+ {
+ public string Name { get; set; }
+
+ public IEnumerable Tests { get; set; }
+ }
+
+ public class Test
+ {
+ public string FullyQualifiedName { get; set; }
+
+ public string DisplayName { get; set; }
+
+ public string Namespace { get; set; }
+
+ public string Type { get; set; }
+
+ public string Method { get; set; }
+
+ public string Result { get; set; }
+
+ public List> Traits { get; set; }
+
+ public List> Properties { get; set; }
+
+ public List Attachments { get; set; }
+ }
+ }
+}
diff --git a/test/TestLogger.UnitTests/TestDoubles/MockTestLoggerEvents.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/MockTestLoggerEvents.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestDoubles/MockTestLoggerEvents.cs
rename to test/TestLogger.VSTest.UnitTests/TestDoubles/MockTestLoggerEvents.cs
diff --git a/test/TestLogger.UnitTests/TestDoubles/TestableTestLogger.cs b/test/TestLogger.VSTest.UnitTests/TestDoubles/TestableTestLogger.cs
similarity index 94%
rename from test/TestLogger.UnitTests/TestDoubles/TestableTestLogger.cs
rename to test/TestLogger.VSTest.UnitTests/TestDoubles/TestableTestLogger.cs
index 977e53c8..b244aec1 100644
--- a/test/TestLogger.UnitTests/TestDoubles/TestableTestLogger.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestDoubles/TestableTestLogger.cs
@@ -4,6 +4,7 @@
namespace Spekt.TestLogger.UnitTests.TestDoubles
{
using Spekt.TestLogger.Core;
+ using Spekt.TestLogger.VSTest;
public class TestableTestLogger : TestLogger
{
diff --git a/test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj b/test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj
new file mode 100644
index 00000000..1ca72bed
--- /dev/null
+++ b/test/TestLogger.VSTest.UnitTests/TestLogger.VSTest.UnitTests.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net10.0
+ true
+ true
+ false
+ true
+ Exe
+ true
+ true
+
+
+
+ Spekt.TestLogger.UnitTests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/TestLogger.UnitTests/TestLoggerTests.cs b/test/TestLogger.VSTest.UnitTests/TestLoggerTests.cs
similarity index 98%
rename from test/TestLogger.UnitTests/TestLoggerTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestLoggerTests.cs
index 110b05fe..d429d9d9 100644
--- a/test/TestLogger.UnitTests/TestLoggerTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestLoggerTests.cs
@@ -8,9 +8,10 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Spekt.TestLogger;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest;
+ using DefaultLoggerParameterNames = Spekt.TestLogger.Core.DefaultLoggerParameterNames;
[TestClass]
public class TestLoggerTests
diff --git a/test/TestLogger.UnitTests/TestResultInfoTests.cs b/test/TestLogger.VSTest.UnitTests/TestResultInfoTests.cs
similarity index 100%
rename from test/TestLogger.UnitTests/TestResultInfoTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestResultInfoTests.cs
diff --git a/test/TestLogger.UnitTests/TestRunBuilderTests.cs b/test/TestLogger.VSTest.UnitTests/TestRunBuilderTests.cs
similarity index 89%
rename from test/TestLogger.UnitTests/TestRunBuilderTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunBuilderTests.cs
index bd911d60..7c1ea02d 100644
--- a/test/TestLogger.UnitTests/TestRunBuilderTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunBuilderTests.cs
@@ -12,6 +12,9 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest.Core;
+ using DefaultLoggerParameterNames = Spekt.TestLogger.Core.DefaultLoggerParameterNames;
+ using TestMessageLevel = Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel;
[TestClass]
public class TestRunBuilderTests
@@ -31,14 +34,6 @@ public void TestRunBuilderShouldCreateDefaultRunConfiguration()
Assert.IsNotNull(run.RunConfiguration);
}
- [TestMethod]
- public void TestRunBuilderShouldCreateDefaultTestAdapterFactory()
- {
- var run = this.testRunBuilder.Build();
-
- Assert.IsNotNull(run.AdapterFactory);
- }
-
[TestMethod]
public void WithLoggerConfigurationShouldSetTestLoggerConfiguration()
{
@@ -68,7 +63,8 @@ public void WithSerializerShouldThrowForNullTestResultSerializer()
[TestMethod]
public void SubscribeShouldThrowForNullLoggerEvents()
{
- Assert.ThrowsExactly(() => this.testRunBuilder.Subscribe(null));
+ var run = this.testRunBuilder.Build();
+ Assert.ThrowsExactly(() => run.Subscribe(null));
}
[TestMethod]
@@ -77,7 +73,8 @@ public void SubscribeShouldSetupTraceAndThrowExceptionForEvents()
var testEvents = new MockTestLoggerEvents();
var consoleOutput = new FakeConsoleOutput();
- this.testRunBuilder.WithConsoleOutput(consoleOutput).Subscribe(testEvents);
+ var run = this.testRunBuilder.WithConsoleOutput(consoleOutput).Build();
+ run.Subscribe(testEvents);
Assert.ThrowsExactly(() => testEvents.RaiseTestRunMessage(TestMessageLevel.Error, "dummy message"));
Assert.ThrowsExactly(() => testEvents.RaiseTestResult(new Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult(new TestCase())));
diff --git a/test/TestLogger.UnitTests/TestRunCompleteWorkflowTests.cs b/test/TestLogger.VSTest.UnitTests/TestRunCompleteWorkflowTests.cs
similarity index 96%
rename from test/TestLogger.UnitTests/TestRunCompleteWorkflowTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunCompleteWorkflowTests.cs
index 18afa339..2c1b6e78 100644
--- a/test/TestLogger.UnitTests/TestRunCompleteWorkflowTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunCompleteWorkflowTests.cs
@@ -12,7 +12,10 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest.Core;
using JsonSerializer = System.Text.Json.JsonSerializer;
+ using TestMessageLevel = Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel;
+ using TestOutcome = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome;
using TestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult;
[TestClass]
@@ -128,7 +131,7 @@ public void CompleteShouldPassAllMessagesToSerializer()
Assert.AreEqual(expectedMessages.Count, results.TestMessages.Count());
expectedMessages
.ForEach(exp => Assert.IsTrue(
- results.TestMessages.SingleOrDefault(act => act.Level == exp.Level && act.Message == exp.Message) is TestMessageInfo));
+ results.TestMessages.SingleOrDefault(act => (int)act.Level == (int)exp.Level && act.Message == exp.Message) is TestMessageInfo));
}
[TestMethod]
diff --git a/test/TestLogger.UnitTests/TestRunMessageWorkflowTests.cs b/test/TestLogger.VSTest.UnitTests/TestRunMessageWorkflowTests.cs
similarity index 84%
rename from test/TestLogger.UnitTests/TestRunMessageWorkflowTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunMessageWorkflowTests.cs
index c217cbea..13568ecb 100644
--- a/test/TestLogger.UnitTests/TestRunMessageWorkflowTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunMessageWorkflowTests.cs
@@ -7,6 +7,8 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest.Core;
+ using TestMessageLevel = Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel;
[TestClass]
public class TestRunMessageWorkflowTests
@@ -32,7 +34,7 @@ public void MessageShouldStoreRunMessages()
testRun.Store.Pop(out _, out var messages);
Assert.AreEqual(1, messages.Count);
- Assert.AreEqual(TestMessageLevel.Informational, messages[0].Level);
+ Assert.AreEqual((int)TestMessageLevel.Informational, (int)messages[0].Level);
Assert.AreEqual("Dummy message", messages[0].Message);
}
}
diff --git a/test/TestLogger.UnitTests/TestRunResultWorkflowTests.cs b/test/TestLogger.VSTest.UnitTests/TestRunResultWorkflowTests.cs
similarity index 95%
rename from test/TestLogger.UnitTests/TestRunResultWorkflowTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunResultWorkflowTests.cs
index 971a2f56..34bd878f 100644
--- a/test/TestLogger.UnitTests/TestRunResultWorkflowTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunResultWorkflowTests.cs
@@ -10,6 +10,9 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest.Core;
+ using DefaultLoggerParameterNames = Spekt.TestLogger.Core.DefaultLoggerParameterNames;
+ using TestOutcome = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestOutcome;
using TestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult;
[TestClass]
@@ -54,7 +57,7 @@ public void ResultShouldCaptureTestCaseAndResult(TestOutcome testOutcome)
Assert.AreEqual("SampleNamespace.SampleClass.SampleTest", results[0].DisplayName);
Assert.AreEqual(DummySourceFile, results[0].AssemblyPath);
- Assert.AreEqual(testOutcome, results[0].Outcome);
+ Assert.AreEqual((int)testOutcome, (int)results[0].Outcome);
Assert.AreEqual("Dummy error", results[0].ErrorMessage);
Assert.AreEqual("Dummy stacktrace", results[0].ErrorStackTrace);
diff --git a/test/TestLogger.UnitTests/TestRunSimulator.cs b/test/TestLogger.VSTest.UnitTests/TestRunSimulator.cs
similarity index 98%
rename from test/TestLogger.UnitTests/TestRunSimulator.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunSimulator.cs
index c2af2b76..34564bdc 100644
--- a/test/TestLogger.UnitTests/TestRunSimulator.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunSimulator.cs
@@ -11,8 +11,8 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
- using Spekt.TestLogger;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest;
public class TestRunSimulator : IDisposable
{
diff --git a/test/TestLogger.UnitTests/TestRunStartWorkflowTests.cs b/test/TestLogger.VSTest.UnitTests/TestRunStartWorkflowTests.cs
similarity index 96%
rename from test/TestLogger.UnitTests/TestRunStartWorkflowTests.cs
rename to test/TestLogger.VSTest.UnitTests/TestRunStartWorkflowTests.cs
index b5d9ba16..e2bef08d 100644
--- a/test/TestLogger.UnitTests/TestRunStartWorkflowTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/TestRunStartWorkflowTests.cs
@@ -9,6 +9,7 @@ namespace Spekt.TestLogger.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Core;
using Spekt.TestLogger.UnitTests.TestDoubles;
+ using Spekt.TestLogger.VSTest.Core;
[TestClass]
public class TestRunStartWorkflowTests
@@ -77,7 +78,8 @@ public void StartShouldRecordStartTimeOfTestRun()
public void StartShouldUpdateTestRunConfiguration()
{
var loggerEvents = new MockTestLoggerEvents();
- var run = new TestRunBuilder().Subscribe(loggerEvents).Build();
+ var run = new TestRunBuilder().Build();
+ run.Subscribe(loggerEvents);
loggerEvents.RaiseTestRunStart(this.testRunCriteria);
diff --git a/test/TestLogger.UnitTests/Utilities/AttachmentSetExtensionsTests.cs b/test/TestLogger.VSTest.UnitTests/Utilities/AttachmentSetExtensionsTests.cs
similarity index 98%
rename from test/TestLogger.UnitTests/Utilities/AttachmentSetExtensionsTests.cs
rename to test/TestLogger.VSTest.UnitTests/Utilities/AttachmentSetExtensionsTests.cs
index 4475444e..1cab4873 100644
--- a/test/TestLogger.UnitTests/Utilities/AttachmentSetExtensionsTests.cs
+++ b/test/TestLogger.VSTest.UnitTests/Utilities/AttachmentSetExtensionsTests.cs
@@ -8,6 +8,7 @@ namespace Spekt.TestLogger.UnitTests.Utilities
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spekt.TestLogger.Utilities;
+ using Spekt.TestLogger.VSTest.Utilities;
[TestClass]
public class AttachmentSetExtensionsTests
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/AcceptanceTestCollection.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/AcceptanceTestCollection.cs
new file mode 100644
index 00000000..a37cb777
--- /dev/null
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/AcceptanceTestCollection.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Xunit.Xml.TestLogger.AcceptanceTests
+{
+ using Xunit;
+
+ // Fixtures spawn dotnet test subprocesses that share mutable state
+ // (test/assets/global.json selects the test runner per leg), so all
+ // fixture-bound test classes must run sequentially in one collection.
+ [CollectionDefinition("Acceptance")]
+ public class AcceptanceTestCollection : ICollectionFixture, ICollectionFixture
+ {
+ }
+}
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkAcceptanceTests.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkAcceptanceTests.cs
new file mode 100644
index 00000000..21eeb7a2
--- /dev/null
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkAcceptanceTests.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Xunit.Xml.TestLogger.AcceptanceTests
+{
+ using System.IO;
+ using System.Xml;
+ using Xunit;
+
+ ///
+ /// Validates running the MTP logger on a test project without a
+ /// Microsoft.NET.Test.Sdk reference (see issue #229).
+ ///
+ [Collection("Acceptance")]
+ public class NoTestSdkAcceptanceTests
+ {
+ private const string TargetFrameworkVersion = "net8.0";
+ private const string ObjectModelAssembly = "Microsoft.VisualStudio.TestPlatform.ObjectModel.dll";
+
+ private readonly NoTestSdkFixture fixture;
+
+ public NoTestSdkAcceptanceTests(NoTestSdkFixture fixture)
+ {
+ this.fixture = fixture;
+ }
+
+ [Fact]
+ public void MtpRunWithoutTestSdkShouldProduceResultsFile()
+ {
+ Assert.True(File.Exists(this.fixture.ResultsFile));
+ }
+
+ [Fact]
+ public void MtpRunWithoutTestSdkShouldReportTestCounts()
+ {
+ var resultsXml = new XmlDocument();
+ resultsXml.Load(this.fixture.ResultsFile);
+ var assemblyNode = resultsXml.SelectSingleNode("/assemblies/assembly");
+
+ Assert.NotNull(assemblyNode);
+ Assert.Equal("3", assemblyNode.Attributes["total"].Value);
+ Assert.Equal("2", assemblyNode.Attributes["passed"].Value);
+ Assert.Equal("1", assemblyNode.Attributes["failed"].Value);
+ }
+
+ [Fact]
+ public void MtpRunWithoutTestSdkShouldNotDeployTestPlatformObjectModel()
+ {
+#if DEBUG
+ var config = "Debug";
+#else
+ var config = "Release";
+#endif
+ var objectModelPath = Path.Combine(
+ this.fixture.AssetDirectory,
+ "bin",
+ config,
+ "mtp",
+ TargetFrameworkVersion,
+ ObjectModelAssembly);
+
+ Assert.False(File.Exists(objectModelPath), "Microsoft.VisualStudio.TestPlatform.ObjectModel must not be deployed for MTP-only runs (issue #229).");
+ }
+ }
+}
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkFixture.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkFixture.cs
new file mode 100644
index 00000000..dd34d8ea
--- /dev/null
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/NoTestSdkFixture.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Spekt Contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Xunit.Xml.TestLogger.AcceptanceTests
+{
+ using global::TestLogger.Fixtures;
+ using Xunit;
+
+ public class NoTestSdkFixture
+ {
+ private const string AssetName = "Xunit.Xml.TestLogger.NoTestSdk.Tests";
+ private const string ResultsFileName = "test-results-mtp.xml";
+
+ public NoTestSdkFixture()
+ {
+ // MTP-only asset without Microsoft.NET.Test.Sdk (see issue #229).
+ var mtpLoggerArgs = $"--report-spekt-xunit --report-spekt-xunit-filename {ResultsFileName}";
+ this.ResultsFile = global::TestLogger.Fixtures.DotnetTestFixture
+ .Create()
+ .WithNoBuild()
+ .Execute(AssetName, mtpLoggerArgs, collectCoverage: false, resultsFileName: ResultsFileName, isMTP: true);
+
+ Assert.False(string.IsNullOrEmpty(this.ResultsFile), "MTP results file cannot be null");
+ this.AssetDirectory = AssetName.ToAssetDirectoryPath();
+ }
+
+ public string ResultsFile { get; }
+
+ public string AssetDirectory { get; }
+ }
+}
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/TestResultsXmlTests.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/TestResultsXmlTests.cs
index 7fed747a..7fc62312 100644
--- a/test/Xunit.Xml.TestLogger.AcceptanceTests/TestResultsXmlTests.cs
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/TestResultsXmlTests.cs
@@ -14,7 +14,8 @@ namespace Xunit.Xml.TestLogger.AcceptanceTests
using System.Xml;
using Xunit;
- public class TestResultsXmlTests : IClassFixture
+ [Collection("Acceptance")]
+ public class TestResultsXmlTests
{
private const string AssembliesElement = @"/assemblies";
private const string AssemblyElement = @"/assemblies/assembly";
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/TestRunFixture.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/TestRunFixture.cs
index 0043cf42..a56d68c4 100644
--- a/test/Xunit.Xml.TestLogger.AcceptanceTests/TestRunFixture.cs
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/TestRunFixture.cs
@@ -16,14 +16,13 @@ public TestRunFixture()
var vstestLoggerArgs = "xunit;LogFilePath=test-results-vstest.xml";
var vstestResultsFile = global::TestLogger.Fixtures.DotnetTestFixture
.Create()
- .WithBuild()
.Execute("Xunit.Xml.TestLogger.NetCore.Tests", vstestLoggerArgs, collectCoverage: false, resultsFileName: "test-results-vstest.xml", isMTP: false);
// Run MTP tests
var mtpLoggerArgs = "--report-spekt-xunit --report-spekt-xunit-filename test-results-mtp.xml";
var mtpResultsFile = global::TestLogger.Fixtures.DotnetTestFixture
.Create()
- .WithBuild()
+ .WithNoBuild()
.Execute("Xunit.Xml.TestLogger.NetCore.Tests", mtpLoggerArgs, collectCoverage: false, resultsFileName: "test-results-mtp.xml", isMTP: true);
Assert.False(string.IsNullOrEmpty(vstestResultsFile), "VSTest results file cannot be null");
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/Xunit.Xml.TestLogger.AcceptanceTests.csproj b/test/Xunit.Xml.TestLogger.AcceptanceTests/Xunit.Xml.TestLogger.AcceptanceTests.csproj
index 11af767a..16be5f7a 100644
--- a/test/Xunit.Xml.TestLogger.AcceptanceTests/Xunit.Xml.TestLogger.AcceptanceTests.csproj
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/Xunit.Xml.TestLogger.AcceptanceTests.csproj
@@ -30,10 +30,17 @@
+
+
+
+
+
-
+
+
+
diff --git a/test/Xunit.Xml.TestLogger.AcceptanceTests/XunitTestLoggerNetFullAcceptanceTests.cs b/test/Xunit.Xml.TestLogger.AcceptanceTests/XunitTestLoggerNetFullAcceptanceTests.cs
index 3e62a45e..c62726e5 100644
--- a/test/Xunit.Xml.TestLogger.AcceptanceTests/XunitTestLoggerNetFullAcceptanceTests.cs
+++ b/test/Xunit.Xml.TestLogger.AcceptanceTests/XunitTestLoggerNetFullAcceptanceTests.cs
@@ -42,7 +42,6 @@ public static void SuiteInitialize(TestContext context)
// Enable reporting of internal properties in the adapter using runsettings
_ = DotnetTestFixture
.Create()
- .WithBuild()
.Execute(AssetName, loggerArgs, collectCoverage: false, "test-results.xml");
}
diff --git a/test/assets/Directory.Build.props b/test/assets/Directory.Build.props
index 7555e135..4f0b9c45 100644
--- a/test/assets/Directory.Build.props
+++ b/test/assets/Directory.Build.props
@@ -21,6 +21,28 @@
3.0.4
+
+
+ Debug
+
+
+
+
+ obj\mtp\
+ bin\$(Configuration)\mtp\
+ $(DefaultItemExcludes);obj\vstest\**
+
+
+ obj\vstest\
+ bin\$(Configuration)\vstest\
+ $(DefaultItemExcludes);obj\mtp\**
+
+
true
$(DefineConstants);USES_XUNIT3
diff --git a/test/assets/JUnit.Xml.TestLogger.NetCore.Tests/JUnit.Xml.TestLogger.NetCore.Tests.csproj b/test/assets/JUnit.Xml.TestLogger.NetCore.Tests/JUnit.Xml.TestLogger.NetCore.Tests.csproj
index e74a5831..c9a2b92a 100644
--- a/test/assets/JUnit.Xml.TestLogger.NetCore.Tests/JUnit.Xml.TestLogger.NetCore.Tests.csproj
+++ b/test/assets/JUnit.Xml.TestLogger.NetCore.Tests/JUnit.Xml.TestLogger.NetCore.Tests.csproj
@@ -3,12 +3,16 @@
net8.0
+
+ exe
+
false
-
+
+
diff --git a/test/assets/JUnit.Xml.TestLogger.NetFull.Tests/JUnit.Xml.TestLogger.NetFull.Tests.csproj b/test/assets/JUnit.Xml.TestLogger.NetFull.Tests/JUnit.Xml.TestLogger.NetFull.Tests.csproj
index 6cde5767..b29c9daa 100644
--- a/test/assets/JUnit.Xml.TestLogger.NetFull.Tests/JUnit.Xml.TestLogger.NetFull.Tests.csproj
+++ b/test/assets/JUnit.Xml.TestLogger.NetFull.Tests/JUnit.Xml.TestLogger.NetFull.Tests.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/test/assets/JUnit.Xml.TestLogger.NetMulti.Tests/JUnit.Xml.TestLogger.NetMulti.Tests.csproj b/test/assets/JUnit.Xml.TestLogger.NetMulti.Tests/JUnit.Xml.TestLogger.NetMulti.Tests.csproj
index 6f1cff81..d4c5210e 100644
--- a/test/assets/JUnit.Xml.TestLogger.NetMulti.Tests/JUnit.Xml.TestLogger.NetMulti.Tests.csproj
+++ b/test/assets/JUnit.Xml.TestLogger.NetMulti.Tests/JUnit.Xml.TestLogger.NetMulti.Tests.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/test/assets/JUnit.Xml.TestLogger.XUnit.NetCore.Tests/JUnit.Xml.TestLogger.XUnit.NetCore.Tests.csproj b/test/assets/JUnit.Xml.TestLogger.XUnit.NetCore.Tests/JUnit.Xml.TestLogger.XUnit.NetCore.Tests.csproj
index 05e26f43..486f4731 100644
--- a/test/assets/JUnit.Xml.TestLogger.XUnit.NetCore.Tests/JUnit.Xml.TestLogger.XUnit.NetCore.Tests.csproj
+++ b/test/assets/JUnit.Xml.TestLogger.XUnit.NetCore.Tests/JUnit.Xml.TestLogger.XUnit.NetCore.Tests.csproj
@@ -6,7 +6,8 @@
-
+
+
diff --git a/test/assets/NUnit.Xml.TestLogger.NetCore.Tests/NUnit.Xml.TestLogger.NetCore.Tests.csproj b/test/assets/NUnit.Xml.TestLogger.NetCore.Tests/NUnit.Xml.TestLogger.NetCore.Tests.csproj
index 405c06fb..3e8ace39 100644
--- a/test/assets/NUnit.Xml.TestLogger.NetCore.Tests/NUnit.Xml.TestLogger.NetCore.Tests.csproj
+++ b/test/assets/NUnit.Xml.TestLogger.NetCore.Tests/NUnit.Xml.TestLogger.NetCore.Tests.csproj
@@ -3,12 +3,16 @@
net8.0
+
+ exe
+
false
-
+
+
diff --git a/test/assets/NUnit.Xml.TestLogger.NetFull.Tests/NUnit.Xml.TestLogger.NetFull.Tests.csproj b/test/assets/NUnit.Xml.TestLogger.NetFull.Tests/NUnit.Xml.TestLogger.NetFull.Tests.csproj
index a20aeb55..81634cf4 100644
--- a/test/assets/NUnit.Xml.TestLogger.NetFull.Tests/NUnit.Xml.TestLogger.NetFull.Tests.csproj
+++ b/test/assets/NUnit.Xml.TestLogger.NetFull.Tests/NUnit.Xml.TestLogger.NetFull.Tests.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/test/assets/NUnit.Xml.TestLogger.NetMulti.Tests/NUnit.Xml.TestLogger.NetMulti.Tests.csproj b/test/assets/NUnit.Xml.TestLogger.NetMulti.Tests/NUnit.Xml.TestLogger.NetMulti.Tests.csproj
index 9ab09261..24ddd25c 100644
--- a/test/assets/NUnit.Xml.TestLogger.NetMulti.Tests/NUnit.Xml.TestLogger.NetMulti.Tests.csproj
+++ b/test/assets/NUnit.Xml.TestLogger.NetMulti.Tests/NUnit.Xml.TestLogger.NetMulti.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/test/assets/Xunit.Xml.TestLogger.NetCore.Tests/Xunit.Xml.TestLogger.NetCore.Tests.csproj b/test/assets/Xunit.Xml.TestLogger.NetCore.Tests/Xunit.Xml.TestLogger.NetCore.Tests.csproj
index cccb57ce..3984d818 100644
--- a/test/assets/Xunit.Xml.TestLogger.NetCore.Tests/Xunit.Xml.TestLogger.NetCore.Tests.csproj
+++ b/test/assets/Xunit.Xml.TestLogger.NetCore.Tests/Xunit.Xml.TestLogger.NetCore.Tests.csproj
@@ -6,7 +6,8 @@
-
+
+
diff --git a/test/assets/Xunit.Xml.TestLogger.NetFull.Tests/Xunit.Xml.TestLogger.NetFull.Tests.csproj b/test/assets/Xunit.Xml.TestLogger.NetFull.Tests/Xunit.Xml.TestLogger.NetFull.Tests.csproj
index 17a339e6..e314aa0b 100644
--- a/test/assets/Xunit.Xml.TestLogger.NetFull.Tests/Xunit.Xml.TestLogger.NetFull.Tests.csproj
+++ b/test/assets/Xunit.Xml.TestLogger.NetFull.Tests/Xunit.Xml.TestLogger.NetFull.Tests.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/UnitTest1.cs b/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/UnitTest1.cs
new file mode 100644
index 00000000..63a54d41
--- /dev/null
+++ b/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/UnitTest1.cs
@@ -0,0 +1,24 @@
+using Xunit;
+
+namespace Xunit.Xml.TestLogger.NoTestSdk.Tests
+{
+ public class UnitTest1
+ {
+ [Fact]
+ public void PassTest11()
+ {
+ }
+
+ [Fact]
+ public void PassTest12()
+ {
+ Assert.Equal(2, 2);
+ }
+
+ [Fact]
+ public void FailTest11()
+ {
+ Assert.False(true);
+ }
+ }
+}
diff --git a/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/Xunit.Xml.TestLogger.NoTestSdk.Tests.csproj b/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/Xunit.Xml.TestLogger.NoTestSdk.Tests.csproj
new file mode 100644
index 00000000..31a3d489
--- /dev/null
+++ b/test/assets/Xunit.Xml.TestLogger.NoTestSdk.Tests/Xunit.Xml.TestLogger.NoTestSdk.Tests.csproj
@@ -0,0 +1,32 @@
+
+
+
+
+ net8.0
+ exe
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ XunitXml.TestLogger
+ Spekt.TestReporter.Xunit.TestingPlatformBuilderHook
+
+
+
+
diff --git a/testlogger.slnx b/testlogger.slnx
index bbb78559..9e5b438c 100644
--- a/testlogger.slnx
+++ b/testlogger.slnx
@@ -6,13 +6,17 @@
-
+
+
-
+
+
-
+
+
-
+
+
@@ -24,7 +28,8 @@
-
+
+
diff --git a/version.txt b/version.txt
index ae9a76b9..8104cabd 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-8.0.0
+8.1.0