diff --git a/Allure.Xunit/AllureMessageSink.cs b/Allure.Xunit/AllureMessageSink.cs index 43ec84c9..7fb7a079 100644 --- a/Allure.Xunit/AllureMessageSink.cs +++ b/Allure.Xunit/AllureMessageSink.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Linq; using Allure.Net.Commons; using Allure.Net.Commons.TestPlan; @@ -73,6 +72,12 @@ void OnTestStarting(MessageHandlerArgs args) { var message = args.Message; var test = message.Test; + + if (AllureXunitHelper.IsOnExternalAuthority(args.Message.Test)) + { + return; + } + var testData = this.GetOrCreateTestData(test); if (testData.IsSelected) @@ -100,7 +105,12 @@ MessageHandlerArgs args { var message = args.Message; var test = message.Test; - + + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + if (!IsStaticTestMethod(message)) { var testResult = this.GetOrCreateTestData(test).TestResult; @@ -109,22 +119,46 @@ MessageHandlerArgs args } } - void OnTestFailed(MessageHandlerArgs args) => + void OnTestFailed(MessageHandlerArgs args) + { + var test = args.Message.Test; + + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + this.RunInTestContext( - args.Message.Test, + test, () => AllureXunitHelper.ApplyTestFailure(args.Message) ); + } + + void OnTestPassed(MessageHandlerArgs args) + { + var test = args.Message.Test; + + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } - void OnTestPassed(MessageHandlerArgs args) => this.RunInTestContext( - args.Message.Test, + test, () => AllureXunitHelper.ApplyTestSuccess(args.Message) ); + } void OnTestSkipped(MessageHandlerArgs args) { var message = args.Message; var test = message.Test; + + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + var testData = this.GetOrCreateTestData(test); if (testData.IsSelected) { @@ -146,6 +180,12 @@ void OnTestFinished(MessageHandlerArgs args) { var message = args.Message; var test = args.Message.Test; + + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + var testData = this.GetOrCreateTestData(test); if (testData.IsSelected) diff --git a/Allure.Xunit/AllureXunitConfiguration.cs b/Allure.Xunit/AllureXunitConfiguration.cs index 9968f2ad..c5ef1747 100644 --- a/Allure.Xunit/AllureXunitConfiguration.cs +++ b/Allure.Xunit/AllureXunitConfiguration.cs @@ -11,8 +11,16 @@ namespace Allure.Xunit { internal class AllureXunitConfiguration : AllureConfiguration { + const string KNOWN_TOOL_REQNROLL = "Reqnroll"; + const string KNOWN_TOOL_SPECFLOW = "TechTalk.SpecFlow"; + public string XunitRunnerReporter { get; set; } = "auto"; + public List FirstClassIntegrationTools { get; set; } = [ + KNOWN_TOOL_REQNROLL, + KNOWN_TOOL_SPECFLOW, + ]; + [JsonConstructor] protected AllureXunitConfiguration( string? title, diff --git a/Allure.Xunit/AllureXunitHelper.cs b/Allure.Xunit/AllureXunitHelper.cs index 5620f21e..62795c7a 100644 --- a/Allure.Xunit/AllureXunitHelper.cs +++ b/Allure.Xunit/AllureXunitHelper.cs @@ -1,4 +1,5 @@ using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using Allure.Net.Commons; @@ -16,6 +17,17 @@ static class AllureXunitHelper internal const string NS_OBSOLETE_MSG = "The Allure.XUnit namespace is deprecated. Please, use Allure.Xunit instead"; + /// + /// Returns true if the test is likely reported by another Allure + /// integration like Allure.Reqnroll. + /// + internal static bool IsOnExternalAuthority(ITest test) => + test.TestCase.TestMethod.TestClass.Class + .GetCustomAttributes(typeof(GeneratedCodeAttribute)) + .Select(a => a.GetNamedArgument(nameof(GeneratedCodeAttribute.Tool))) + .Where(v => !string.IsNullOrEmpty(v)) + .Any(AllureXunitConfiguration.CurrentConfig.FirstClassIntegrationTools.Contains!); + internal static TestResultContainer StartNewAllureContainer( string className ) @@ -108,7 +120,7 @@ internal static void ApplyDefaultSuites(ITestMethod method) var className = string.IsNullOrEmpty(@namespace) ? testClass.Name - : testClass.Name?.Substring(@namespace.Length + 1); + : testClass.Name?.Substring(@namespace!.Length + 1); AllureLifecycle.Instance.UpdateTestCase( testResult => ModelFunctions.EnsureSuites( diff --git a/Allure.Xunit/AllureXunitPatcher.cs b/Allure.Xunit/AllureXunitPatcher.cs index f7fc4261..7cc53388 100644 --- a/Allure.Xunit/AllureXunitPatcher.cs +++ b/Allure.Xunit/AllureXunitPatcher.cs @@ -97,12 +97,24 @@ private static void PatchXunitTestRunnerCtors(Harmony patcher) private static void OnTestRunnerCreating(ITest test, ref string skipReason) { + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + if (!CurrentSink.SelectByTestPlan(test)) { skipReason = AllureTestPlan.SkipReason; } } - private static void OnTestRunnerCreated(ITest test, object[] testMethodArguments) => + private static void OnTestRunnerCreated(ITest test, object[] testMethodArguments) + { + if (AllureXunitHelper.IsOnExternalAuthority(test)) + { + return; + } + CurrentSink.OnTestArgumentsCreated(test, testMethodArguments); + } } \ No newline at end of file diff --git a/Allure.Xunit/Schemas/allureConfig.schema.json b/Allure.Xunit/Schemas/allureConfig.schema.json index 9be09c9f..8501cf36 100644 --- a/Allure.Xunit/Schemas/allureConfig.schema.json +++ b/Allure.Xunit/Schemas/allureConfig.schema.json @@ -26,6 +26,15 @@ "description": "The runner switch or the assembly qualified class name of a runner reporter." } ] + }, + "firstClassIntegrationTools": { + "description": "A list of tools that generate xUnit.net tests and have a tool-specific Allure integration enabled in the project. Allure.Xunit will ignore such tests. The test classes produced by the tools must be marked with `[System.CodeDom.Compiler.GeneratedCodeAttribute]` that mentions the tool as the first argument for this feature to work. The default list includes \"Reqnroll\" and \"TechTalk.SpecFlow\".", + "default": ["Reqnroll", "TechTalk.SpecFlow"], + "type": "array", + "items": { + "type": "string", + "description": "The name of a tool, i.e., the first argument of `[System.CodeDom.Compiler.GeneratedCodeAttribute]` applied by the tool to generated xUnit.net test classes." + } } } }