Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allure-specflow: selective run support #392

Merged
merged 3 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Allure.Features/Allure.Features.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="SpecFlow" Version="3.9.74" />
<PackageReference Include="SpecFlow.SharedSteps" Version="3.0.7" />
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.9.8" />
<PackageReference Include="SpecFlow.NUnit" Version="3.9.8" />

<!-- SpecFlow.SharedSteps doesn't work with SpecFlow.Tools.MsBuild.Generation v3.9.58+ -->
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.9.52" />

<PackageReference Include="SpecFlow.NUnit" Version="3.9.52" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Allure.Net.Commons\Allure.Net.Commons.csproj" />
Expand Down
3 changes: 2 additions & 1 deletion Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net462;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<IsPackable>true</IsPackable>
<Nullable>enable</Nullable>
<PackageId>Allure.SpecFlow</PackageId>
Expand All @@ -26,6 +26,7 @@

<ItemGroup>
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="Lib.Harmony" Version="2.3.0-prerelease.2" />
<PackageReference Include="SpecFlow" Version="[3.9.8, 3.10)" />
<PackageReference Include="System.Collections.Specialized" Version="4.3.0" />
</ItemGroup>
Expand Down
55 changes: 39 additions & 16 deletions Allure.SpecFlowPlugin/AllureBindingInvoker.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -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(
Expand Down Expand Up @@ -73,13 +78,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(
Expand Down Expand Up @@ -300,7 +320,7 @@ HookBinding hook
return result;
}

(object, TimeSpan) InvokeAllureBinding(
(object, TimeSpan) InvokeAllureHookBinding(
IBinding binding,
IContextManager contextManager,
object[] arguments,
Expand Down Expand Up @@ -361,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<string>(),
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<string>(),
new OrderedDictionary()
)
);

allure
.StopTestCase(makeBroken)
Expand Down
85 changes: 64 additions & 21 deletions Allure.SpecFlowPlugin/PluginHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<Label>, List<Link>) allureMetadata
)
{
var tags = GetTags(featureInfo, scenarioInfo);
var (labels, links) = allureMetadata;
var parameters = GetParameters(scenarioInfo);
var title = scenarioInfo.Title;
var testResult = new TestResult
Expand All @@ -75,14 +97,34 @@ ScenarioInfo scenarioInfo
),
Label.Feature(featureInfo.Title)
}
.Union(tags.Item1).ToList(),
links = tags.Item2,
.Union(labels).ToList(),
links = links,
parameters = parameters.parameters
};

AllureLifecycle.Instance.StartTestCase(testResult);
}

internal static (List<Label> labels, List<Link> links) GetOrParseLabelsAndLinks(
FeatureInfo featureInfo,
ScenarioContext scenarioContext
)
{
var cacheHit = scenarioContext.TryGetValue(
LABELS_AND_LINKS_CACHE_KEY,
out (List<Label>, List<Link>) items
);
if (!cacheHit)
{
items = ParseLabelsAndLinks(
featureInfo,
scenarioContext.ScenarioInfo
);
scenarioContext.Set(items, LABELS_AND_LINKS_CACHE_KEY);
}
return items;
}

internal static StatusDetails GetStatusDetails(Exception ex) =>
new()
{
Expand Down Expand Up @@ -232,12 +274,13 @@ static string GetFullExceptionMessage(Exception ex) =>
: string.Empty
);

static Tuple<List<Label>, List<Link>> GetTags(
static (List<Label> labels, List<Link> links) ParseLabelsAndLinks(
FeatureInfo featureInfo,
ScenarioInfo scenarioInfo
)
{
var result = Tuple.Create(new List<Label>(), new List<Link>());
var labels = new List<Label>();
var links = new List<Link>();

var tags = scenarioInfo.Tags
.Union(featureInfo.Tags)
Expand All @@ -249,7 +292,7 @@ ScenarioInfo scenarioInfo
// link
if (TryUpdateValueByMatch(PluginConfiguration.links.link, ref tagValue))
{
result.Item2.Add(new()
links.Add(new()
{
name = tagValue,
url = tagValue
Expand All @@ -260,7 +303,7 @@ ScenarioInfo scenarioInfo
// issue
if (TryUpdateValueByMatch(PluginConfiguration.links.issue, ref tagValue))
{
result.Item2.Add(
links.Add(
Link.Issue(tagValue, tagValue)
);
continue;
Expand All @@ -269,7 +312,7 @@ ScenarioInfo scenarioInfo
// tms
if (TryUpdateValueByMatch(PluginConfiguration.links.tms, ref tagValue))
{
result.Item2.Add(
links.Add(
Link.Tms(tagValue, tagValue)
);
continue;
Expand All @@ -278,7 +321,7 @@ ScenarioInfo scenarioInfo
// parent suite
if (TryUpdateValueByMatch(PluginConfiguration.grouping.suites.parentSuite, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.ParentSuite(tagValue)
);
continue;
Expand All @@ -287,7 +330,7 @@ ScenarioInfo scenarioInfo
// suite
if (TryUpdateValueByMatch(PluginConfiguration.grouping.suites.suite, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.Suite(tagValue)
);
continue;
Expand All @@ -296,7 +339,7 @@ ScenarioInfo scenarioInfo
// sub suite
if (TryUpdateValueByMatch(PluginConfiguration.grouping.suites.subSuite, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.SubSuite(tagValue)
);
continue;
Expand All @@ -305,7 +348,7 @@ ScenarioInfo scenarioInfo
// epic
if (TryUpdateValueByMatch(PluginConfiguration.grouping.behaviors.epic, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.Epic(tagValue)
);
continue;
Expand All @@ -314,7 +357,7 @@ ScenarioInfo scenarioInfo
// story
if (TryUpdateValueByMatch(PluginConfiguration.grouping.behaviors.story, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.Story(tagValue)
);
continue;
Expand All @@ -323,7 +366,7 @@ ScenarioInfo scenarioInfo
// package
if (TryUpdateValueByMatch(PluginConfiguration.grouping.packages.package, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.Package(tagValue)
);
continue;
Expand All @@ -332,7 +375,7 @@ ScenarioInfo scenarioInfo
// test class
if (TryUpdateValueByMatch(PluginConfiguration.grouping.packages.testClass, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.TestClass(tagValue)
);
continue;
Expand All @@ -341,7 +384,7 @@ ScenarioInfo scenarioInfo
// test method
if (TryUpdateValueByMatch(PluginConfiguration.grouping.packages.testMethod, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.TestMethod(tagValue)
);
continue;
Expand All @@ -350,7 +393,7 @@ ScenarioInfo scenarioInfo
// owner
if (TryUpdateValueByMatch(PluginConfiguration.labels.owner, ref tagValue))
{
result.Item1.Add(
labels.Add(
Label.Owner(tagValue)
);
continue;
Expand All @@ -360,7 +403,7 @@ ScenarioInfo scenarioInfo
if (TryUpdateValueByMatch(PluginConfiguration.labels.severity, ref tagValue) &&
Enum.TryParse(tagValue, out SeverityLevel level))
{
result.Item1.Add(
labels.Add(
Label.Severity(level)
);
continue;
Expand All @@ -369,7 +412,7 @@ ScenarioInfo scenarioInfo
// label
if (GetLabelProps(PluginConfiguration.labels.label, tagValue, out var props))
{
result.Item1.Add(new()
labels.Add(new()
{
name = props.Key,
value = props.Value
Expand All @@ -378,12 +421,12 @@ ScenarioInfo scenarioInfo
}

// tag
result.Item1.Add(
labels.Add(
Label.Tag(tagValue)
);
}

return result;
return (labels, links);
}

static (List<Parameter> parameters, string hash) GetParameters(
Expand Down
Loading
Loading