Skip to content

Commit

Permalink
Implement selective run in allure-specflow
Browse files Browse the repository at this point in the history
  • Loading branch information
delatrie committed Oct 10, 2023
1 parent da34417 commit a612a1f
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 34 deletions.
1 change: 1 addition & 0 deletions Allure.SpecFlowPlugin/Allure.SpecFlowPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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
34 changes: 21 additions & 13 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 @@ -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<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

0 comments on commit a612a1f

Please sign in to comment.