From da34417a2798236d721e1eaa9cfbce9b06ec3ae9 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 29 Sep 2023 03:41:51 +0700 Subject: [PATCH 1/3] Allure-specflow explicit net462 removal + refactoring - Remove net462 target from allure-specflow (net462 already implements netstandard2.0). - Fix allure-specflow README (version references, examples). - Increase SpecFlow.NUnit and SpecFlow.Tools.MsBuild.Generation to 3.9.52 (max version that doesn't break SpecFlow.SharedSteps). - Tiny refactoring of AllureBindingInvoker.cs --- Allure.Features/Allure.Features.csproj | 7 +- .../Allure.SpecFlowPlugin.csproj | 2 +- Allure.SpecFlowPlugin/AllureBindingInvoker.cs | 21 ++- Allure.SpecFlowPlugin/README.md | 137 +++++++++++++----- 4 files changed, 127 insertions(+), 40 deletions(-) diff --git a/Allure.Features/Allure.Features.csproj b/Allure.Features/Allure.Features.csproj index dfea952d..be4790ec 100644 --- a/Allure.Features/Allure.Features.csproj +++ b/Allure.Features/Allure.Features.csproj @@ -11,8 +11,11 @@ - - + + + + + diff --git a/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj b/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj index e664a2b6..a19326cf 100644 --- a/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj +++ b/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj @@ -1,7 +1,7 @@  - net462;netstandard2.0 + netstandard2.0 true enable Allure.SpecFlow diff --git a/Allure.SpecFlowPlugin/AllureBindingInvoker.cs b/Allure.SpecFlowPlugin/AllureBindingInvoker.cs index b91d1249..9d5a1a31 100644 --- a/Allure.SpecFlowPlugin/AllureBindingInvoker.cs +++ b/Allure.SpecFlowPlugin/AllureBindingInvoker.cs @@ -73,13 +73,28 @@ out duration ITestTracer testTracer, HookBinding hook ) => - IsAllureHook(hook) ? this.InvokeAllureBinding( + IsAllureHook(hook) ? this.InvokeAllureHookBinding( binding, contextManager, arguments, testTracer, hook - ) : hook.HookType switch + ) : this.MakeFixtureFromFeatureOrScenarioHook( + binding, + contextManager, + arguments, + testTracer, + hook + ); + + (object, TimeSpan) MakeFixtureFromFeatureOrScenarioHook( + IBinding binding, + IContextManager contextManager, + object[] arguments, + ITestTracer testTracer, + HookBinding hook + ) => + hook.HookType switch { HookType.BeforeFeature => this.MakeFixtureFromBeforeFeatureHook( @@ -300,7 +315,7 @@ HookBinding hook return result; } - (object, TimeSpan) InvokeAllureBinding( + (object, TimeSpan) InvokeAllureHookBinding( IBinding binding, IContextManager contextManager, object[] arguments, diff --git a/Allure.SpecFlowPlugin/README.md b/Allure.SpecFlowPlugin/README.md index 53210553..c6bf18d6 100644 --- a/Allure.SpecFlowPlugin/README.md +++ b/Allure.SpecFlowPlugin/README.md @@ -1,24 +1,52 @@ ## SpecFlow Adapter [![](http://img.shields.io/nuget/vpre/Allure.SpecFlow.svg?style=flat)](https://www.nuget.org/packages/Allure.SpecFlow) -Currently supports [SpecFlow](http://specflow.org/) v2.1 - 3.1.* -See [Allure report](https://allure-secondary.z23.web.core.windows.net/) generated from https://github.com/allure-framework/allure-csharp/tree/main/Allure.Features +Currently supports [SpecFlow](http://specflow.org/) v2.1 - 3.9.* + +See [Allure report](https://allure-secondary.z23.web.core.windows.net/) +generated from https://github.com/allure-framework/allure-csharp/tree/main/Allure.Features Please use corresponding NuGet package version. + ### Installation -Install [Allure.SpecFlow](https://www.nuget.org/packages/Allure.SpecFlow) nuget package according to your Specflow version. +Install [Allure.SpecFlow](https://www.nuget.org/packages/Allure.SpecFlow) +nuget package according to your Specflow version. + ### Configuration + For Specflow 3 please add or update the following section in your specflow.json: + ``` "stepAssemblies": [ { "assembly": "Allure.SpecFlowPlugin" } ] ``` -The plugin uses Allure.Commons json configuration extended with custom sections. -### Custom host name -In case if you want to customize host name which is displayed in Allure Timeline section, please configure `allure.title` property in json configuraion file. + +The plugin uses allureConfig.json extended with custom sections that are +described below. + +#### Custom host name + +In case if you want to customize host name which is displayed in Allure Timeline +section, please configure `allure.title` property in json configuraion file. + +```json +{ + "allure": { + "title": "My title" + } +} +``` + #### If you use NUnit -Default value for allure.directory in allureConfig.json is "allure-results", default working directory in NUnit 3.* is the working directory of console runner. If you don't want to place allure results into NUnit default working folder please either set absolute path in allure.config or set working directory for NUnit in your test setup, e.g.: + +The default value for allure.directory in allureConfig.json is "allure-results". +The default working directory in NUnit 3.* depends on what runner you use. + +If you don't want to place allure results into NUnit default working folder +please either set absolute path in allure.config or set working directory for +NUnit in your test setup, e.g.: + ``` csharp [OneTimeSetUp] public void Init() @@ -26,13 +54,21 @@ public void Init() Environment.CurrentDirectory = Path.GetDirectoryName(GetType().Assembly.Location); } ``` + ### Usage -Just run your SpecFlow scenarios and find `allure-results` folder ready to generate Allure report. + +Just run your SpecFlow scenarios and find the `allure-results` folder ready to +generate Allure report. ### Features + #### Grouping -You can structure your scenarios in 3 Allure hierarchies using feature and scenario tags. -Please read [report structure](https://docs.qameta.io/allure/latest/#_report_structure) Allure documentation section for additional details. Hierarchies consist of the following levels: + +You can structure your scenarios in 3 Allure hierarchies using feature and +scenario tags. +Please read [report structure](https://docs.qameta.io/allure/latest/#_report_structure) +Allure documentation section for additional details. Hierarchies consist of +the following levels: **Suites** * Parent Suite @@ -49,16 +85,22 @@ Please read [report structure](https://docs.qameta.io/allure/latest/#_report_str * * Class * * * Method -The plugin uses `allure:grouping` configuration section to parse tags with the regular expression. If the expression contains the group, it will be used as hierarchy level name otherwise entire match will be used. E.g: +The plugin uses `allure:grouping` configuration section to parse tags with the +regular expression. If the expression contains the group, it will be used as +hierarchy level name otherwise entire match will be used. E.g: `^mytag.*` : any tags starting with `@mytag` will be used for grouping. -`^type:(ui|api)` : `@ui` or `@api` tags from regex pattern will be used for grouping. +`^type:(ui|api)` : `@ui` or `@api` tags from regex pattern will be used for +grouping. -Check this [config example](https://github.com/allure-framework/allure-csharp/blob/main/Tests.SpecRun/allureConfig.json) as a starting point. +Check this [config example](https://github.com/allure-framework/allure-csharp/blob/main/Tests.SpecRun/allureConfig.json) +as a starting point. #### Links -You can add links to your scenarios using tags. Tag and link patterns can be configured in `allureConfig.json` +You can add links to your scenarios using tags. Tag and link patterns can be +configured in `allureConfig.json` + ``` json { "allure": { @@ -76,60 +118,85 @@ You can add links to your scenarios using tags. Tag and link patterns can be con } } ``` + The following scenario + ``` cucumber @123456 @tms:42 @link:http://example.org Scenario: I do like click on links in Allure report ``` + will have three links in Allure report: -[123456](https://myissuetracker.org/123456), [42](https://mytestmanagementsystem.org?test=tms-42) and http://example.org. +[123456](https://myissuetracker.org/123456), +[42](https://mytestmanagementsystem.org?test=tms-42) and http://example.org. + +Links generated dynamically during the tests can be added in code via +AllureLifecycle. The next example adds the [Example link](http://example.com) +link at runtime: -In case there are links, which are generated during tests, then they can be added in code via AllureLifecycle: ``` c# -AllureLifecycle.UpdateTestCase(testResult.uuid, tc => - { - tc.links.Add(new Link() - { - name = "Example link", - url = "http://example.com" - }); - }); +AllureLifecycle.Instance.UpdateTestCase(tc => +{ + tc.links.Add(new Link() + { + name = "Example link", + url = "http://example.com" + }); +}); ``` -This will show for scenario link with Text: Example link; and url: "http://example.com". #### Severity -You can add Severity for your scenarios using tags. It can be configured in `allureConfig.json` +You can add Severity for your scenarios using tags. It can be configured in +`allureConfig.json`: + ``` json "labels": { "severity": "^(normal|blocker|critical|minor|trivial)" }, ``` + The following scenario + ``` cucumber @critical Scenario: .... ``` -will set current scenario severity in Allure report as Blocker + +sets the current scenario's severity in Allure report as Blocker. #### Label -You can add Label for your scenarios using tags. It can be configured in `allureConfig.json` + +You can add allure labels for your scenarios using tags. It can be configured +in `allureConfig.json`: + ``` json "labels": { "label": "^label:([\\w]+):(.+)" }, ``` + The following scenario + ``` cucumber -@label:layer:e2e: @label:as_id:123 +@label:layer:e2e: @label:allure_id:123 Scenario: .... ``` -will set current scenario Layer as e2e and Id as 123 in Allure report + +sets the current scenario's layer as e2e and Id as 123 in Allure report #### Tables conversion -Table arguments in SpecFlow steps can be converted either to step csv-attacments or step parameters in the Allure report. The conversion is configurable in `specflow:stepArguments` config section. -With `specflow:stepArguments:convertToParameters` set to `true` the following table arguments will be represented as parameters: + +Table arguments in SpecFlow steps can be converted either to step +csv-attacments or step parameters in the Allure report. The conversion is +configurable in `specflow:stepArguments` config section. + +With `specflow:stepArguments:convertToParameters` set to `true` the following +table arguments will be represented as parameters: + * one row tables -* two column tables with the headers matching both `specflow:stepArguments:paramNameRegex` and `specflow:stepArguments:paramValueRegex` regular expressions. +* two column tables with the headers matching both + `specflow:stepArguments:paramNameRegex` and + `specflow:stepArguments:paramValueRegex` regular expressions. @@ -149,9 +216,11 @@ With `specflow:stepArguments:convertToParameters` set to `true` the following ta
SpecFlow
#### Attachments + You can add attachments to an Allure report from your step bindings: + ```csharp -using Allure.Commons; +using Allure.Net.Commons; ... AllureLifecycle.Instance.AddAttachment(path, "Attachment Title"); // or From a612a1fa5d1b23f7264936ecf51a79bf7463f0d0 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Sat, 30 Sep 2023 03:35:05 +0700 Subject: [PATCH 2/3] Implement selective run in allure-specflow --- .../Allure.SpecFlowPlugin.csproj | 1 + Allure.SpecFlowPlugin/AllureBindingInvoker.cs | 34 +-- Allure.SpecFlowPlugin/PluginHelper.cs | 85 ++++++-- .../SelectiveRun/AllureSpecFlowPatcher.cs | 119 +++++++++++ .../SelectiveRun/SelectiveRunTestRunner.cs | 202 ++++++++++++++++++ 5 files changed, 407 insertions(+), 34 deletions(-) create mode 100644 Allure.SpecFlowPlugin/SelectiveRun/AllureSpecFlowPatcher.cs create mode 100644 Allure.SpecFlowPlugin/SelectiveRun/SelectiveRunTestRunner.cs diff --git a/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj b/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj index a19326cf..5b6e2ec3 100644 --- a/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj +++ b/Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj @@ -26,6 +26,7 @@ + diff --git a/Allure.SpecFlowPlugin/AllureBindingInvoker.cs b/Allure.SpecFlowPlugin/AllureBindingInvoker.cs index 9d5a1a31..1936acc4 100644 --- a/Allure.SpecFlowPlugin/AllureBindingInvoker.cs +++ b/Allure.SpecFlowPlugin/AllureBindingInvoker.cs @@ -1,13 +1,14 @@ using System; using System.Collections.Specialized; using Allure.Net.Commons; +using Allure.SpecFlowPlugin.SelectiveRun; using TechTalk.SpecFlow; using TechTalk.SpecFlow.Bindings; using TechTalk.SpecFlow.Configuration; using TechTalk.SpecFlow.ErrorHandling; using TechTalk.SpecFlow.Infrastructure; using TechTalk.SpecFlow.Tracing; - +using TechTalk.SpecFlow.UnitTestProvider; namespace Allure.SpecFlowPlugin { @@ -29,13 +30,17 @@ internal class AllureBindingInvoker : BindingInvoker public AllureBindingInvoker( SpecFlowConfiguration specFlowConfiguration, IErrorProvider errorProvider, - ISynchronousBindingDelegateInvoker synchronousBindingDelegateInvoker + ISynchronousBindingDelegateInvoker synchronousBindingDelegateInvoker, + IUnitTestRuntimeProvider unitTestRuntimeProvider ) : base( specFlowConfiguration, errorProvider, synchronousBindingDelegateInvoker ) { + AllureSpecFlowPatcher.EnsureTestPlanSupportInjected( + unitTestRuntimeProvider + ); } public override object InvokeBinding( @@ -376,17 +381,20 @@ Exception error // to indicate the error. if (!featureContext.ContainsKey(PLACEHOLDER_TESTCASE_KEY)) { - PluginHelper.StartTestCase(featureContext.FeatureInfo, new( - "Feature hook failure placeholder", - string.Format( - "This is a placeholder scenario to indicate an " + - "exception occured in a feature-level fixture " + - "of '{0}'", - featureContext.FeatureInfo.Title - ), - Array.Empty(), - new OrderedDictionary() - )); + PluginHelper.StartTestCase( + featureContext.FeatureInfo, + new ScenarioInfo( + "Feature hook failure placeholder", + string.Format( + "This is a placeholder scenario to indicate an " + + "exception occured in a feature-level " + + "fixture of '{0}'", + featureContext.FeatureInfo.Title + ), + Array.Empty(), + new OrderedDictionary() + ) + ); allure .StopTestCase(makeBroken) diff --git a/Allure.SpecFlowPlugin/PluginHelper.cs b/Allure.SpecFlowPlugin/PluginHelper.cs index 8fe1fecc..852a503c 100644 --- a/Allure.SpecFlowPlugin/PluginHelper.cs +++ b/Allure.SpecFlowPlugin/PluginHelper.cs @@ -13,6 +13,7 @@ namespace Allure.SpecFlowPlugin public static class PluginHelper { public static string IGNORE_EXCEPTION = "IgnoreException"; + const string LABELS_AND_LINKS_CACHE_KEY = "LABELS_AND_LINKS"; internal static PluginConfiguration PluginConfiguration = GetConfiguration(AllureLifecycle.Instance.JsonConfiguration); @@ -51,12 +52,33 @@ internal static void StartTestContainer() => uuid = NewId() }); + internal static void StartTestCase( + FeatureInfo featureInfo, + ScenarioContext scenarioContext + ) => + StartTestCase( + featureInfo, + scenarioContext.ScenarioInfo, + GetOrParseLabelsAndLinks(featureInfo, scenarioContext) + ); + internal static void StartTestCase( FeatureInfo featureInfo, ScenarioInfo scenarioInfo + ) => + StartTestCase( + featureInfo, + scenarioInfo, + ParseLabelsAndLinks(featureInfo, scenarioInfo) + ); + + internal static void StartTestCase( + FeatureInfo featureInfo, + ScenarioInfo scenarioInfo, + (List