diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index fc1da497..e835f72d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -71,6 +71,10 @@ jobs:
--no-restore\
--no-build\
--configuration ${{ env.BUILD_CONFIGURATION }}
+ dotnet run --project ./tests/Allure.Xunit.Tests\
+ --no-restore\
+ --no-build\
+ --configuration ${{ env.BUILD_CONFIGURATION }}
dotnet test ./tests/Allure.SpecFlow.Tests\
--no-restore\
--no-build\
diff --git a/allure-csharp.slnx b/allure-csharp.slnx
index 80f6ebcd..1aabca56 100644
--- a/allure-csharp.slnx
+++ b/allure-csharp.slnx
@@ -86,6 +86,9 @@
+
+
+
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index e6b0eeb9..163a9081 100644
--- a/src/Allure.NUnit/Core/AllureNUnitHelper.cs
+++ b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
@@ -4,9 +4,10 @@
using System.Linq;
using System.Text;
using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
using Allure.Net.Commons.Functions;
+using Allure.Net.Commons.Sdk;
using Allure.Net.Commons.TestPlan;
-using Allure.NUnit.Attributes;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
@@ -120,7 +121,8 @@ internal static TestResult CreateTestResult(ITest test)
..ModelFunctions.EnumerateGlobalLabels(),
]
};
- UpdateTestDataFromAllureAttributes(test, testResult);
+ ApplyLegacyAllureAttributes(test, testResult);
+ ApplyAllureAttributes(test, testResult);
AddTestParametersFromNUnit(test, testResult);
SetIdentifiers(test, testResult);
return testResult;
@@ -262,27 +264,24 @@ static void SetLegacyIdentifiers(ITest test, TestResult testResult)
static void AddTestParametersFromNUnit(ITest test, TestResult testResult)
{
- var arguments = CollectNUnitArguments(test);
+ var parameters = test.Method.MethodInfo.GetParameters();
+ var arguments = test.Arguments;
var formatters = AllureLifecycle.TypeFormatters;
- foreach (var (name, value) in arguments)
- {
- testResult.parameters.Add(new()
- {
- name = name,
- value = FormatFunctions.Format(value, formatters)
- });
- }
+
+ testResult.parameters.AddRange(
+ ModelFunctions.CreateParameters(parameters, arguments, formatters)
+ );
}
- static IEnumerable<(string, object)> CollectNUnitArguments(ITest test) =>
- test.Method.MethodInfo.GetParameters()
- .Select(p => p.Name)
- .Zip(
- test.Arguments,
- (n, v) => (n, v)
- );
+ static void ApplyAllureAttributes(ITest test, TestResult testResult)
+ {
+ var testFixtureClass = GetTestFixture(test).TypeInfo.Type;
+
+ AllureApiAttribute.ApplyTypeAttributes(testFixtureClass, testResult);
+ AllureApiAttribute.ApplyMethodAttributes(test.Method.MethodInfo, testResult);
+ }
- static void UpdateTestDataFromAllureAttributes(ITest test, TestResult testResult)
+ static void ApplyLegacyAllureAttributes(ITest test, TestResult testResult)
{
foreach (var attribute in IterateAllAllureAttribites(test))
{
@@ -290,12 +289,12 @@ static void UpdateTestDataFromAllureAttributes(ITest test, TestResult testResult
}
}
- static IEnumerable IterateAllAllureAttribites(ITest test) =>
+ static IEnumerable IterateAllAllureAttribites(ITest test) =>
test.Method
- .GetCustomAttributes(true)
+ .GetCustomAttributes(true)
.Concat(
GetTestFixture(test)
- .GetCustomAttributes(true)
+ .GetCustomAttributes(true)
);
static string GetNamespace(string classFullName)
@@ -309,6 +308,14 @@ static string GetNamespace(string classFullName)
);
}
+ static string ResolveSubSuite(TestFixture testFixture)
+ => AllureApiAttribute
+ .GetTypeAttributes(testFixture.TypeInfo.Type)
+ .OfType()
+ .LastOrDefault()
+ ?.Name
+ ?? GetClassName(testFixture.FullName);
+
static string GetClassName(string classFullName)
{
var lastDotIndex = StripTypeArgs(classFullName)?.LastIndexOf('.') ?? -1;
@@ -349,39 +356,66 @@ static TestFixture GetTestFixture(ITest test)
internal static void ApplyDefaultSuiteHierarchy(ITest test)
{
- var testClassFullName = GetTestFixture(test).FullName;
+ var testFixture = GetTestFixture(test);
+ var testClassFullName = testFixture.FullName;
var assemblyName = test.TypeInfo?.Assembly?.GetName().Name;
var @namespace = GetNamespace(testClassFullName);
- var className = GetClassName(testClassFullName);
+ var subSuite = ResolveSubSuite(testFixture);
AllureLifecycle.UpdateTestCase(
testResult => ModelFunctions.EnsureSuites(
testResult,
assemblyName,
@namespace,
- className
+ subSuite
)
);
}
private void UpdateTestDataFromNUnitProperties()
{
- foreach (var p in GetTestProperties(PropertyNames.Description))
+ this.ApplyNUnitDescriptions();
+ this.ApplyNUnitAuthors();
+ this.ApplyNUnitCategories();
+ }
+
+ void ApplyNUnitDescriptions()
+ {
+ bool hasDescription = false;
+ AllureLifecycle.UpdateTestCase((tr) =>
{
- AllureLifecycle.UpdateTestCase(x => x.description += $"{p}\n"
- );
+ hasDescription = tr.description is not null || tr.descriptionHtml is not null;
+ });
+
+ if (hasDescription)
+ {
+ // If a description is provided via the Allure API,
+ // NUnit descriptions are ignored.
+ return;
}
- foreach (var p in GetTestProperties(PropertyNames.Author))
+ foreach (var p in EnumerateTestProperties(PropertyNames.Description))
{
- AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Owner(p))
- );
+ AllureLifecycle.UpdateTestCase(x =>
+ x.description = string.IsNullOrEmpty(x.description)
+ ? p
+ : $"{x.description}\n\n{p}");
}
+ }
- foreach (var p in GetTestProperties(PropertyNames.Category))
+ void ApplyNUnitAuthors()
+ {
+ foreach (var p in EnumerateTestProperties(PropertyNames.Author))
{
- AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Tag(p))
- );
+ AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Owner(p)));
+ }
+ }
+
+ void ApplyNUnitCategories()
+ {
+ foreach (var p in EnumerateTestProperties(PropertyNames.Category))
+ {
+ AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Tag(p)));
}
}
@@ -402,30 +436,32 @@ private void AddConsoleOutputAttachment()
}
}
- private IEnumerable GetTestProperties(string name)
+ IEnumerable EnumerateTestProperties(string name)
{
- var list = new List();
- var currentTest = _test;
- while (currentTest.GetType() != typeof(TestSuite)
- && currentTest.GetType() != typeof(TestAssembly))
+ var propertyContainers = EnumeratePropertyContainers().Reverse();
+ foreach (var obj in propertyContainers)
{
- if (currentTest.Properties.ContainsKey(name))
+ if (obj.Properties.ContainsKey(name))
{
- if (currentTest.Properties[name].Count > 0)
+ for (var i = 0; i < obj.Properties[name].Count; i++)
{
- for (var i = 0; i < currentTest.Properties[name].Count; i++)
- {
- list.Add(
- currentTest.Properties[name][i].ToString()
- );
- }
+ yield return obj.Properties[name][i].ToString();
}
}
+ }
+ }
- currentTest = currentTest.Parent;
+ IEnumerable EnumeratePropertyContainers()
+ {
+ for (var test = this._test; ShouldContinue(test); test = test.Parent)
+ {
+ yield return test;
}
- return list;
+ static bool ShouldContinue(ITest test)
+ => test is not null
+ && test.GetType() != typeof(TestSuite)
+ && test.GetType() != typeof(TestAssembly);
}
private string ContainerId => $"tc-{_test.Id}";
diff --git a/src/Allure.NUnit/README.md b/src/Allure.NUnit/README.md
index 1809a03b..5dedd529 100644
--- a/src/Allure.NUnit/README.md
+++ b/src/Allure.NUnit/README.md
@@ -32,7 +32,155 @@ Some examples are available [here](https://github.com/allure-framework/allure-cs
## Notes
-### Namespace changed to Allure.NUnit
+### New in 2.15.0: the common Attribute API
+
+Use the attributes in `Allure.Net.Commons.Attributes` instead of `Allure.NUnit.Attributes`. Read more details [here](https://github.com/allure-framework/allure-csharp/pull/647).
+
+In most cases, the migration is as simple as swapping the using directive:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+using Allure.NUnit;
+using NUnit.Framework;
+
+[AllureFeature("My feature")]
+class MyTestClass
+{
+ [AllureStory("My story")]
+ [Test]
+ public void MyTestMethod()
+ {
+
+ }
+}
+```
+
+In some cases, the usage must be updated. They are listed below.
+
+#### `[AllureDescription]`
+
+Set `Append` to keep the concatenation behavior:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+-[AllureDescription("First description")]
++[AllureDescription("First description", Append = true)]
+class MyTestClass
+{
+- [AllureDescription("Second description")]
++ [AllureDescription("Second description", Append = true)]
+ [Test]
+ public void MyTestMethod()
+ {
+
+ }
+}
+```
+
+Use `[AllureDescriptionHtml]` instead of setting `Html`:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+class MyTestClass
+{
+- [AllureDescription("Html text
", Html = true)]
++ [AllureDescriptionHtml("Html text
")]
+ [Test]
+ public void MyTestMethod()
+ {
+ }
+}
+```
+
+#### `[AllureFeature]`, `[AllureStory]` with multiple values
+
+Use multiple `[AllureFeature]` or `[AllureStory]` attributes instead:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureFeature("Feature 1", "Feature 2")]
++[AllureFeature("Feature 1")]
++[AllureFeature("Feature 2")]
+-[AllureStory("Story 1", "Story 2")]
++[AllureStory("Story 1")]
++[AllureStory("Story 2")]
+class MyTestClass
+{
+}
+```
+
+#### `[AllureLink]`, `[AllureIssue]`, `[AllureTms]`
+
+Pass the URL or ID as the only positional argument. Use the `Title` property to pass the display
+text. Also, use `[AllureTmsItem]` instead of `[AllureTms]`:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureLink("Homepage", "https://allurereport.org")]
++[AllureLink("https://allurereport.org", Title = "Homepage")]
+-[AllureIssue("ISSUE-123", "123")]
++[AllureIssue("123", Title = "ISSUE-123")]
+-[AllureTms("TMS-345", "345")]
++[AllureTmsItem("345", Title = "TMS-345")]
+class MyTestClass
+{
+}
+```
+
+#### `[AllureSeverity]`
+
+Always pass an explicit value as the argument:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureSeverity]
++[AllureSeverity(SeverityLevel.normal)]
+class MyTestClass
+{
+}
+```
+
+#### `[Name]` and `[Skip]`
+
+Use `[AllureParameter]` with `Name` and `Ignore` correspondingly:
+
+```diff
+- using Allure.NUnit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+class MyTestClass
+{
+ [AllureStep]
+ public void MyStepMethod(
+- [Name("Foo")] int parameter1,
++ [AllureParameter(Name = "Foo")] int parameter1,
+- [Skip] int parameter2
++ [AllureParameter(Ignore = true)] int parameter2
+ )
+ {
+ }
+}
+```
+
+#### Deprecation notice
+
+Attributes from the `Allure.NUnit.Attributes` namespace will be deprecated in one of the future
+releases. Please, migrate to `Allure.Net.Commons.Attributes`.
+
+### New in 2.12.0: Namespace changed to Allure.NUnit
Starting from 2.12.0, the namespace `NUnit.Allure` is deprecated. The API in
that namespace still works, but it will be removed in the future. Please use
diff --git a/src/Allure.Net.Commons/AllureApi.cs b/src/Allure.Net.Commons/AllureApi.cs
index 0dc8c837..cfffd0fb 100644
--- a/src/Allure.Net.Commons/AllureApi.cs
+++ b/src/Allure.Net.Commons/AllureApi.cs
@@ -2,6 +2,7 @@
using System.IO;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using Allure.Net.Commons.Functions;
using HeyRed.Mime;
@@ -21,12 +22,12 @@ public static class AllureApi
const string DIFF_MEDIA_TYPE = "application/vnd.allure.image.diff";
const string DIFF_ENTRY_PREFIX = "data:image/png;base64,";
- static AllureLifecycle? lifecycleInstance;
+ static readonly AsyncLocal lifecycleInstance = new();
internal static AllureLifecycle CurrentLifecycle
{
- get => lifecycleInstance ?? AllureLifecycle.Instance;
- set => lifecycleInstance = value;
+ get => lifecycleInstance.Value ?? AllureLifecycle.Instance;
+ set => lifecycleInstance.Value = value;
}
internal static bool HasTest => ExtendedApi.HasTest;
@@ -793,9 +794,9 @@ internal static T ExecuteAction(
}
- static void AddAttachmentInternal(
+ internal static void AddAttachmentInternal(
string name,
- string type,
+ string? type,
byte[] content,
string fileExtension
)
diff --git a/src/Allure.Net.Commons/AllureLifecycle.cs b/src/Allure.Net.Commons/AllureLifecycle.cs
index d553e050..ace03d84 100644
--- a/src/Allure.Net.Commons/AllureLifecycle.cs
+++ b/src/Allure.Net.Commons/AllureLifecycle.cs
@@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Threading;
+using System.Threading.Tasks;
using Allure.Net.Commons.Configuration;
using Allure.Net.Commons.Functions;
using Allure.Net.Commons.TestPlan;
@@ -177,6 +178,35 @@ Action action
}
}
+ ///
+ /// Binds the provided value as the current Allure context and executes
+ /// the specified function. The context is then restored to the initial
+ /// value. That allows the Allure context to bypass .NET execution
+ /// context boundaries.
+ ///
+ ///
+ /// Unlike , this method doesn't have a return value
+ /// because changed made by to the context
+ /// may be auotmatically reverted upon its exit.
+ ///
+ ///
+ /// A context that was previously captured with .
+ /// If it is null, the code is executed in the current context.
+ ///
+ /// A code to run.
+ public async Task RunInContextAsync(AllureContext? context, Func asyncAction)
+ {
+ if (context is null)
+ {
+ await asyncAction();
+ return;
+ }
+
+ // This change will be discarded once the method exits because it's async.
+ this.Context = context;
+ await asyncAction();
+ }
+
///
/// Binds the provided value as the current Allure context. This allows the
/// Allure context to bypass .NET execution context boundaries. Use this
diff --git a/src/Allure.Net.Commons/Attributes/AllureAfterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureAfterAttribute.cs
new file mode 100644
index 00000000..5478d303
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureAfterAttribute.cs
@@ -0,0 +1,27 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Wraps each call of the method in a tear down fixture.
+///
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class AllureAfterAttribute : Steps.AllureStepAttributes.AbstractAfterAttribute
+{
+ ///
+ /// Wraps each call of the method in a tear down fixture using the method's
+ /// name as the name of the fixture.
+ ///
+ public AllureAfterAttribute() : base() { }
+
+ ///
+ /// Wraps each call of the method in a named tear down fixture.
+ ///
+ ///
+ /// A name of the fixture. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureAfterAttribute(string name) : base(name) { }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
new file mode 100644
index 00000000..ecc677a0
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
@@ -0,0 +1,69 @@
+using System;
+using Allure.Net.Commons.Sdk.Aspects;
+using AspectInjector.Broker;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// When applied to a method returning byte[] , string ,
+/// , or a corresponding async type
+/// (e.g., Task<byte[]> ), creates an attachment
+/// from the return value each time the method is called.
+///
+[Injection(typeof(AllureAttachmentAspect))]
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class AllureAttachmentAttribute : Attribute
+{
+ ///
+ /// A name of the attachment to display in the report. The {paramName} placeholders can
+ /// be used to interpolate the method's arguments into the name.
+ ///
+ public string? Name { get; }
+
+ ///
+ /// A content type of the attachment. It affects how the attachment is rendered in the report.
+ /// By default, application/octet-stream is used for byte[] and text/plain
+ /// for string .
+ ///
+ ///
+ /// Examples: application/json , image/png .
+ ///
+ public string? ContentType { get; init; }
+
+ ///
+ /// A file extension to use when the attachment is downloaded.
+ ///
+ ///
+ /// By default, the extension is derived from the content type if possible.
+ ///
+ public string? Extension { get; init; }
+
+ ///
+ /// Which encoding to use when converting a string into a byte array. By default,
+ /// UTF-8 is used.
+ ///
+ ///
+ /// If the method returns a type other than string (or its async counterpart),
+ /// this property has no effect.
+ ///
+ public string? Encoding { get; init; }
+
+ ///
+ /// Creates attachments named after the method.
+ ///
+ public AllureAttachmentAttribute() { }
+
+ ///
+ /// Creates attachments with explicit names. Argument interpolation is supported.
+ ///
+ ///
+ /// The attachment's name. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureAttachmentAttribute(string name)
+ {
+ this.Name = name;
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureAttachmentFileAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureAttachmentFileAttribute.cs
new file mode 100644
index 00000000..70bfc4c5
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureAttachmentFileAttribute.cs
@@ -0,0 +1,51 @@
+using System;
+using Allure.Net.Commons.Sdk.Aspects;
+using AspectInjector.Broker;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// When applied to a method returning string ,
+/// , or a corresponding async type
+/// (e.g., Task<string> ), interprets the return value of the method
+/// as a path to a file and attaches it each time the method is called.
+///
+[Injection(typeof(AllureAttachmentFileAspect))]
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class AllureAttachmentFileAttribute : Attribute
+{
+ ///
+ /// A name of the attachment to display in the report. The {paramName} placeholders can
+ /// be used to interpolate the method's arguments into the name.
+ ///
+ public string? Name { get; }
+
+ ///
+ /// A content type of the attachment. It affects how the attachment is rendered in the report.
+ /// By default, application/octet-stream is used for byte[] and text/plain
+ /// for string .
+ ///
+ ///
+ /// Examples: application/json , image/png .
+ ///
+ public string? ContentType { get; init; }
+
+ ///
+ /// Creates attachments with the same names as the original files.
+ ///
+ public AllureAttachmentFileAttribute() { }
+
+ ///
+ /// Creates attachments with explicit names. Argument interpolation is supported.
+ ///
+ ///
+ /// The attachment's name. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureAttachmentFileAttribute(string name)
+ {
+ this.Name = name;
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
new file mode 100644
index 00000000..43d45ade
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
@@ -0,0 +1,78 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies the whole BDD hierarchy at once.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
+public class AllureBddHierarchyAttribute : AllureApiAttribute
+{
+ ///
+ /// Value for the epic label.
+ ///
+ public string? Epic { get; init; }
+
+ ///
+ /// Value for the feature label.
+ ///
+ public string? Feature { get; init; }
+
+ ///
+ /// Value for the story label.
+ ///
+ public string? Story { get; init; }
+
+ ///
+ /// A shorthand for ,
+ /// , and .
+ ///
+ public AllureBddHierarchyAttribute(string epic, string feature, string story)
+ {
+ this.Epic = epic;
+ this.Feature = feature;
+ this.Story = story;
+ }
+
+ ///
+ /// A shorthand for and
+ /// .
+ ///
+ public AllureBddHierarchyAttribute(string epic, string feature)
+ {
+ this.Epic = epic;
+ this.Feature = feature;
+ }
+
+ ///
+ /// An alias for .
+ ///
+ public AllureBddHierarchyAttribute(string feature)
+ {
+ this.Feature = feature;
+ }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ var labels = testResult.labels;
+
+ if (this.Epic is not null)
+ {
+ labels.Add(Label.Epic(this.Epic));
+ }
+
+ if (this.Feature is not null)
+ {
+ labels.Add(Label.Feature(this.Feature));
+ }
+
+ if (this.Story is not null)
+ {
+ labels.Add(Label.Story(this.Story));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
new file mode 100644
index 00000000..8ada34a6
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
@@ -0,0 +1,27 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Wraps each call of the method in a setup fixture.
+///
+[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
+public class AllureBeforeAttribute : Steps.AllureStepAttributes.AbstractBeforeAttribute
+{
+ ///
+ /// Wraps each call of the method or constructor in an setup fixture using the method's
+ /// name as the name of the fixture.
+ ///
+ public AllureBeforeAttribute() : base() { }
+
+ ///
+ /// Wraps each call of the method or constructor in a named setup fixture.
+ ///
+ ///
+ /// A name of the fixture. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureBeforeAttribute(string name) : base(name) { }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
new file mode 100644
index 00000000..ab6e0c60
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -0,0 +1,53 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a description.
+///
+/// A description text. Markdown is supported.
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureDescriptionAttribute(string markdownText) : AllureApiAttribute
+{
+ ///
+ /// Description text in Markdown format.
+ ///
+ public string MarkdownText { get; init; } = markdownText;
+
+ ///
+ /// If set to true , the description is appended to the existing one with "\n\n" .
+ /// Otherwise, the existing description will be overwritten with the new one.
+ ///
+ ///
+ /// Here is a list of guarantees about the order in which attribute targets are considered when
+ /// the attributes are applied:
+ ///
+ /// - Interfaces before classes/structs.
+ /// - Base classes before derived classes.
+ /// - Classes/structs before methods.
+ /// - Base methods before method overrides.
+ ///
+ ///
+ public bool Append { get; init; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.MarkdownText is null)
+ {
+ return;
+ }
+
+ if (this.Append && !string.IsNullOrEmpty(testResult.description))
+ {
+ testResult.description += $"\n\n{this.MarkdownText}";
+ }
+ else
+ {
+ testResult.description = this.MarkdownText;
+ }
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
new file mode 100644
index 00000000..4752e4a9
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
@@ -0,0 +1,59 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a description in HTML.
+///
+///
+/// Prefer , which supports markdown.
+///
+/// A description text in HTML.
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureDescriptionHtmlAttribute(string htmlText) : AllureApiAttribute
+{
+ ///
+ /// Description text in HTML.
+ ///
+ public string HtmlText { get; init; } = htmlText;
+
+ ///
+ /// If set to true , the description is appended to the existing one. No separator is
+ /// inserted.
+ /// Use a block element like <p> to separate the values.
+ /// If set to false (which is the default), the existing description will be
+ /// overwritten with the new one.
+ ///
+ ///
+ /// Here is a list of guarantees about the order in which attribute targets are considered when
+ /// the attributes are applied:
+ ///
+ /// - Interfaces before classes/structs.
+ /// - Base classes before derived classes.
+ /// - Classes/structs before methods.
+ /// - Base methods before method overrides.
+ ///
+ ///
+ public bool Append { get; init; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.HtmlText is null)
+ {
+ return;
+ }
+
+ if (this.Append && testResult.descriptionHtml is not null)
+ {
+ testResult.descriptionHtml += this.HtmlText;
+ }
+ else
+ {
+ testResult.descriptionHtml = this.HtmlText;
+ }
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureEpicAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureEpicAttribute.cs
new file mode 100644
index 00000000..6d6d5648
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureEpicAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies an epic label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureEpicAttribute(string epic)
+ : AllureLabelAttribute(LabelName.EPIC, epic);
diff --git a/src/Allure.Net.Commons/Attributes/AllureFeatureAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureFeatureAttribute.cs
new file mode 100644
index 00000000..ab915daf
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureFeatureAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a feature label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureFeatureAttribute(string feature)
+ : AllureLabelAttribute(LabelName.FEATURE, feature);
diff --git a/src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs
new file mode 100644
index 00000000..5047d6c6
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Globalization;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Sets an Allure ID. Can only be applied to methods.
+///
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+public class AllureIdAttribute(int id)
+ : AllureLabelAttribute(
+ LabelName.ALLURE_ID,
+ Convert.ToString(id, CultureInfo.InvariantCulture));
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
new file mode 100644
index 00000000..6262771d
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a link to an issue.
+///
+///
+/// The issue's ID or URL. If ID is specified, make sure a corresponding link template
+/// exists in the configuration.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureIssueAttribute(string issueIdOrUrl) : AllureApiAttribute
+{
+ ///
+ /// The ID of the issue or its full URL.
+ ///
+ public string IdOrUrl { get; init; } = issueIdOrUrl;
+
+ ///
+ /// A display text of the issue link.
+ ///
+ public string? Title { get; set; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.IdOrUrl is null)
+ {
+ return;
+ }
+
+ testResult.links.Add(new()
+ {
+ url = this.IdOrUrl,
+ name = this.Title,
+ type = LinkType.ISSUE,
+ });
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
new file mode 100644
index 00000000..ff2ef2ab
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -0,0 +1,36 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a custom label.
+///
+/// A label's name.
+/// A label's value.
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureLabelAttribute(string name, string value) : AllureApiAttribute
+{
+ ///
+ /// The name of the label.
+ ///
+ public string Name { get; init; } = name;
+
+ ///
+ /// The value of the label.
+ ///
+ public string Value { get; init; } = value;
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (string.IsNullOrEmpty(this.Name) || this.Value is null)
+ {
+ return;
+ }
+
+ testResult.labels.Add(new() { name = this.Name, value = this.Value });
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
new file mode 100644
index 00000000..9c64c5ca
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -0,0 +1,49 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a link.
+///
+///
+/// A full URL or a portion of it. If a portion of the URL is used, a URL template that fits
+/// the link's type must exist in the configuration.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureLinkAttribute(string url) : AllureApiAttribute
+{
+ ///
+ /// The URL of the link.
+ ///
+ public string Url { get; init; } = url;
+
+ ///
+ /// A display text of the link.
+ ///
+ public string? Title { get; init; }
+
+ ///
+ /// A type of the link. Use this property to select the correct link template from the
+ /// configuration.
+ ///
+ public string? Type { get; init; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.Url is null)
+ {
+ return;
+ }
+
+ testResult.links.Add(new()
+ {
+ url = this.Url,
+ name = this.Title,
+ type = this.Type,
+ });
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
new file mode 100644
index 00000000..91d22ca7
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Reflection;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies all the attributes applied to its subclass, serving as a shortcut for them.
+///
+public abstract class AllureMetaAttribute : AllureApiAttribute
+{
+ private readonly AllureApiAttribute[] attributes;
+
+ public AllureMetaAttribute()
+ {
+ this.attributes = [
+ ..this.GetType().GetCustomAttributes(true),
+ ];
+ }
+
+ ///
+ sealed public override void Apply(TestResult testResult)
+ {
+ foreach (var attr in this.attributes)
+ {
+ attr.Apply(testResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
new file mode 100644
index 00000000..de1d83c0
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -0,0 +1,31 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a display name to a test or a class.
+///
+[AttributeUsage(
+ AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
+ AllowMultiple = false,
+ Inherited = false
+)]
+public class AllureNameAttribute(string name) : AllureApiAttribute
+{
+ ///
+ /// The provided name.
+ ///
+ public string Name { get; init; } = name;
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.Name is not null)
+ {
+ testResult.name = this.Name;
+ }
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs
new file mode 100644
index 00000000..55a20257
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies an owner label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
+public class AllureOwnerAttribute(string owner)
+ : AllureLabelAttribute(LabelName.OWNER, owner);
diff --git a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
new file mode 100644
index 00000000..987a351b
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Controls how Allure treats test and step parameters created from method arguments.
+///
+[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
+public class AllureParameterAttribute : Attribute
+{
+ ///
+ /// If set to true, the argument will be precluded from the report.
+ ///
+ public bool Ignore { get; init; } = false;
+
+ ///
+ /// A display name of the parameter. If unset, the source name of the parameter will be used.
+ ///
+ public string? Name { get; init; }
+
+ ///
+ /// A display mode of the parameter.
+ ///
+ ///
+ /// This property controls how Allure displays the value of the parameter. It doesn't affect
+ /// how the value is represented in result files.
+ ///
+ public ParameterMode Mode { get; init; } = ParameterMode.Default;
+
+ ///
+ /// If set to true , the parameter doesn't affect the test's historyId.
+ /// Use for timestamps, random values, and other values that may change across runs by design.
+ ///
+ ///
+ /// Setting this property doesn't remove the parameter from the report. To remove the parameter
+ /// entirely, use .
+ ///
+ /// Has no effect when applied to a step's parameter.
+ ///
+ public bool Excluded { get; init; } = false;
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureParentSuiteAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParentSuiteAttribute.cs
new file mode 100644
index 00000000..4397ee93
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureParentSuiteAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a parentSuite label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureParentSuiteAttribute(string parentSuite)
+ : AllureLabelAttribute(LabelName.PARENT_SUITE, parentSuite);
diff --git a/src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs
new file mode 100644
index 00000000..a921a64e
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a severity label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
+public class AllureSeverityAttribute(SeverityLevel severity)
+ : AllureLabelAttribute(LabelName.SEVERITY, severity.ToString());
diff --git a/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
new file mode 100644
index 00000000..7083030e
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
@@ -0,0 +1,27 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Wraps each call of the method in an Allure step.
+///
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+public class AllureStepAttribute : Steps.AllureStepAttributes.AbstractStepAttribute
+{
+ ///
+ /// Wraps each call of the method in an Allure step using the method's name as the
+ /// name of the step.
+ ///
+ public AllureStepAttribute() : base() { }
+
+ ///
+ /// Wraps each call of the method in a named Allure step.
+ ///
+ ///
+ /// A name of the step. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureStepAttribute(string name) : base(name) { }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureStoryAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureStoryAttribute.cs
new file mode 100644
index 00000000..bdc51ccc
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureStoryAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a story label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureStoryAttribute(string story)
+ : AllureLabelAttribute(LabelName.STORY, story);
diff --git a/src/Allure.Net.Commons/Attributes/AllureSubSuiteAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSubSuiteAttribute.cs
new file mode 100644
index 00000000..2bbb9876
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSubSuiteAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a subSuite label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureSubSuiteAttribute(string subSuite)
+ : AllureLabelAttribute(LabelName.SUB_SUITE, subSuite);
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteAttribute.cs
new file mode 100644
index 00000000..8c464821
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a suite label.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureSuiteAttribute(string suite)
+ : AllureLabelAttribute(LabelName.SUITE, suite);
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
new file mode 100644
index 00000000..7b75ae0b
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
@@ -0,0 +1,78 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies the whole suite hierarchy at once.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
+public class AllureSuiteHierarchyAttribute : AllureApiAttribute
+{
+ ///
+ /// The value of the parentSuite label.
+ ///
+ public string? ParentSuite { get; init; }
+
+ ///
+ /// The value of the suite label.
+ ///
+ public string? Suite { get; init; }
+
+ ///
+ /// The value of the subSuite label.
+ ///
+ public string? SubSuite { get; init; }
+
+ ///
+ /// A shorthand for ,
+ /// , and .
+ ///
+ public AllureSuiteHierarchyAttribute(string parentSuite, string suite, string subSuite)
+ {
+ this.ParentSuite = parentSuite;
+ this.Suite = suite;
+ this.SubSuite = subSuite;
+ }
+
+ ///
+ /// A shorthand for and
+ /// .
+ ///
+ public AllureSuiteHierarchyAttribute(string parentSuite, string suite)
+ {
+ this.ParentSuite = parentSuite;
+ this.Suite = suite;
+ }
+
+ ///
+ /// An alias for .
+ ///
+ public AllureSuiteHierarchyAttribute(string suite)
+ {
+ this.Suite = suite;
+ }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ var labels = testResult.labels;
+
+ if (this.ParentSuite is not null)
+ {
+ labels.Add(Label.ParentSuite(this.ParentSuite));
+ }
+
+ if (this.Suite is not null)
+ {
+ labels.Add(Label.Suite(this.Suite));
+ }
+
+ if (this.SubSuite is not null)
+ {
+ labels.Add(Label.SubSuite(this.SubSuite));
+ }
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
new file mode 100644
index 00000000..1bd4bf74
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Immutable;
+using System.Linq;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies tags.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureTagAttribute(string tag, params string[] moreTags)
+ : AllureApiAttribute
+{
+ ///
+ /// The provided tags.
+ ///
+ public ImmutableArray Tags { get; init; } = CreateTagArray(tag, moreTags);
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ testResult.labels.AddRange(
+ this.Tags
+ .Where(static (v) =>
+ !string.IsNullOrEmpty(v))
+ .Select(Label.Tag)
+ );
+ }
+
+ static ImmutableArray CreateTagArray(string tag, string[] moreTags)
+ {
+ var builder = ImmutableArray.CreateBuilder(moreTags.Length + 1);
+ builder.Add(tag);
+ builder.AddRange(moreTags);
+ return builder.MoveToImmutable();
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
new file mode 100644
index 00000000..b11760bf
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a link to a test management system (TMS) item.
+///
+///
+/// The item's ID or URL. If ID is specified, make sure a corresponding link template
+/// exists in the configuration.
+///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureApiAttribute
+{
+ ///
+ /// The ID of the TMS item or its full URL.
+ ///
+ public string IdOrUrl { get; init; } = tmsItemIdOrUrl;
+
+ ///
+ /// A display text of the TMS item link.
+ ///
+ public string? Title { get; set; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (this.IdOrUrl is null)
+ {
+ return;
+ }
+
+ testResult.links.Add(new()
+ {
+ url = this.IdOrUrl,
+ name = this.Title,
+ type = LinkType.TMS_ITEM,
+ });
+ }
+}
diff --git a/src/Allure.Net.Commons/Functions/ModelFunctions.cs b/src/Allure.Net.Commons/Functions/ModelFunctions.cs
index b27d6e23..99312a1e 100644
--- a/src/Allure.Net.Commons/Functions/ModelFunctions.cs
+++ b/src/Allure.Net.Commons/Functions/ModelFunctions.cs
@@ -3,7 +3,9 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using System.Reflection;
using System.Threading;
+using Allure.Net.Commons.Attributes;
using Allure.Net.Commons.Configuration;
#nullable enable
@@ -137,6 +139,90 @@ from kv in Config.GlobalLabels ?? []
where !string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value)
select new Label { name = kv.Key, value = kv.Value };
+ ///
+ /// Creates Allure parameter objects from method parameters paired with their values.
+ ///
+ ///
+ /// This method applies .
+ ///
+ ///
+ /// A sequence of the test method's parameters.
+ ///
+ ///
+ /// A sequence of values.
+ /// The order of the sequence must match the order of
+ ///
+ ///
+ /// Custom formatters to convert values of specific types to strings.
+ /// Typically comes from .
+ ///
+ /// A sequence of Allure parameters.
+ public static IEnumerable CreateParameters(
+ IEnumerable parameters,
+ IEnumerable values,
+ IReadOnlyDictionary formatters
+ )
+ => CreateParameters(
+ parameters.Select(static (p) => p.Name),
+ parameters.Select(static (p) => p.GetCustomAttribute()),
+ values,
+ formatters
+ );
+
+ ///
+ /// Creates Allure parameter objects from parameter names, attributes, and values.
+ /// All three sequences must have a matching order.
+ ///
+ ///
+ /// A sequence of parameter names. These names are used by default unless an explicit
+ /// name is provided via .
+ ///
+ ///
+ /// A sequence of Allure parameter attributes that affect how the parameters are handled.
+ /// If no attribute is defined for the parameter, the corresponding item of this sequence
+ /// must be null .
+ /// See the description of for more details.
+ ///
+ /// A sequence of values.
+ ///
+ /// Custom formatters to convert values of specific types to strings.
+ /// Typically comes from .
+ /// If no formatter is defined to the type, the default algorithm is used that converts
+ /// the value into its JSON representation.
+ ///
+ /// A sequence of Allure parameters.
+ public static IEnumerable CreateParameters(
+ IEnumerable parameterNames,
+ IEnumerable attributes,
+ IEnumerable values,
+ IReadOnlyDictionary formatters
+ )
+ => parameterNames
+ .Zip(attributes, static (n, a) => (name: n, attr: a))
+ .Zip(values, static (p, v) => (p.name, p.attr, value: v))
+ .Where(static (tuple) => tuple.attr?.Ignore is not true)
+ .Select((tuple) =>
+ CreateParameter(tuple.name, tuple.attr, tuple.value, formatters));
+
+ static Parameter CreateParameter(
+ string parameterName,
+ AllureParameterAttribute? attribute,
+ object? value,
+ IReadOnlyDictionary formatters
+ )
+ => new()
+ {
+ name = attribute?.Name ?? parameterName,
+ value = FormatFunctions.Format(value, formatters),
+ excluded = attribute?.Excluded == true,
+ mode = ResolveParameterMode(attribute)
+ };
+
+ static ParameterMode? ResolveParameterMode(AllureParameterAttribute? attribute)
+ => attribute is AllureParameterAttribute { Mode: ParameterMode mode and not ParameterMode.Default }
+ ? mode
+ : null;
+
static bool ShouldAddEnvVarAsLabel(
[NotNullWhen(true)] string? name,
[NotNullWhen(true)] string? value
diff --git a/src/Allure.Net.Commons/Helpers/LinkHelper.cs b/src/Allure.Net.Commons/Helpers/LinkHelper.cs
index d6fbd6f9..08aba446 100644
--- a/src/Allure.Net.Commons/Helpers/LinkHelper.cs
+++ b/src/Allure.Net.Commons/Helpers/LinkHelper.cs
@@ -10,8 +10,7 @@ public class LinkHelper
public static void UpdateLinks(IEnumerable links, HashSet patterns)
{
foreach (var linkTypeGroup in links
- .Where(l => !string.IsNullOrWhiteSpace(l.type))
- .GroupBy(l => l.type))
+ .GroupBy(l => l.type ?? "link"))
{
var typePattern = $"{{{linkTypeGroup.Key}}}";
var linkPattern = patterns.FirstOrDefault(x =>
@@ -19,11 +18,15 @@ public static void UpdateLinks(IEnumerable links, HashSet patterns
if (linkPattern != null)
{
var linkArray = linkTypeGroup.ToArray();
- for (var i = 0; i < linkArray.Length; i++)
+ foreach (var link in linkTypeGroup)
{
- var replacedLink = Regex.Replace(linkPattern, typePattern, linkArray[i].url ?? string.Empty,
- RegexOptions.IgnoreCase);
- linkArray[i].url = Uri.EscapeUriString(replacedLink);
+ var replacedLink = Regex.Replace(
+ linkPattern,
+ typePattern,
+ link.url ?? string.Empty,
+ RegexOptions.IgnoreCase
+ );
+ link.url = Uri.EscapeUriString(replacedLink);
}
}
}
diff --git a/src/Allure.Net.Commons/README.md b/src/Allure.Net.Commons/README.md
index e7a19f6a..9e178d33 100644
--- a/src/Allure.Net.Commons/README.md
+++ b/src/Allure.Net.Commons/README.md
@@ -100,6 +100,183 @@ considered broken. An exception's type matches a name if:
2. One of its base classes matches the name, OR
3. It implements an interface that matches the name.
+## Attribute API
+
+Use the attributes defined in the `Allure.Net.Commons.Attributes` namespaces:
+
+|Attribute|Effect|Apply to|Notes|
+|--|--|--|--|
+|`[AllureAfter]` |Creates a tear down fixture from the method call. |Method. |Uses AspectInjector under the hood.|
+|`[AllureAttachment]` |Creates an attachment from the method's return value. |Method. |Only supports `string` and `byte[]` return types. Uses AspectInjector under the hood.|
+|`[AllureBddHierarchy]` |Adds the `epic`, `feature`, and `story` labels to test results at once.|Method, class, interface.|This is a shorthand for `[AllureEpic]`, `AllureFeature`, and `[AllureStory]`.|
+|`[AllureBefore]` |Creates a setup fixture from the method or constructor call. |Method, constructor. |Uses AspectInjector under the hood.|
+|`[AllureDescription]` |Sets a description of test results. |Method, class, interface.|If applied multiple times with `Append` set, all the strings are joined with `\n\n`.|
+|`[AllureDescriptionHtml]`|Sets a description of test results in raw HTML. |Method, class, interface.|If applied multiple times with `Append` set, all the strings are joined (no separator used).|
+|`[AllureEpic]` |Adds the `epic` label to test results. |Method, class, interface.|Discards the default BDD hierarchy.|
+|`[AllureFeature]` |Adds the `feature` label to test results. |Method, class, interface.|Discards the default BDD hierarchy.|
+|`[AllureId]` |Applies the `ALLURE_ID` label to test results. |Method. |-|
+|`[AllureIssue]` |Adds an issue link to test results |Method, class, interface.|If a short ID is used instead of a full URL, a link template must exists in the config.|
+|`[AllureLabel]` |Adds a custom label to test results. |Method, class, interface.|-|
+|`[AllureLink]` |Adds a link to test results. |Method, class, interface.|If a short ID is used instead of a full URL, a link template must exists in the config.|
+|`[AllureMeta]` |Applies a custom set of attributes to test results. |Method, class, interface.|See #406.|
+|`[AllureName]` |Sets a display name of test results. |Method, class, interface.|When applied to a test class, affects the value of the default `suite` label created from this class.|
+|`[AllureOwner]` |Applies the `owner` label to test results. |Method, class, interface.|-|
+|`[AllureParameter]` |Affects how method arguments are converted to Allure parameters. |Parameter. |Allows for ignoring the parameters, see #482.|
+|`[AllureParentSuite]` |Applies the `parentSuite` label to test results. |Method, class, interface.|Discards the default suite hierarchy.|
+|`[AllureSeverity]` |Applies the `severity` label to test results. |Method, class, interface.|-|
+|`[AllureStep]` |Creates Allure steps from method calls. |Method. |Uses AspectInjector under the hood.|
+|`[AllureStory]` |Applies the `story` label to test results. |Method, class, interface.|Discards the default BDD hierarchy.|
+|`[AllureSubSuite]` |Applies the `subSuite` label to test results. |Method, class, interface.|Discards the default suite hierarchy.|
+|`[AllureSuite]` |Applies the `suite` label to test results. |Method, class, interface.|Discards the default suite hierarchy.|
+|`[AllureSuiteHierarchy]` |Applies the `parentSuite`, `suite`, and `subSuite` labels at once. |Method, class, interface.|This is a shorthand for `[AllureParentSuite]`, `[AllureSuite]` and `[AllureSubSuite]`.|
+|`[AllureTag]` |Applies the `tag` labels to test results. |Method, class, interface.|-|
+|`[AllureTmsItem]` |Applies a TMS item link to test results |Method, class, interface.|If a short ID is used instead of a full URL, a link template must exists in the config.|
+
+Most of the attributes are straightforward and can be applied on a method, class, or interface:
+
+ - When applied to a method, they affect test results produced by this method.
+ - When applied to a class, they affect test results produced by all methods of this class and its subclasses.
+ - When applied to an interface, they affect test results produced by all methods of classes that implement the interface.
+
+### AOP attributes
+
+Applying `[AllureStep]` automatically wraps method calls into Allure step. Call arguments are automatically converted to Allure parameters.
+
+Similarly, `[AllureBefore]` and `[AllureAfter]` wrap method calls into fixtures. Apply these to
+setup/teardown methods that are invoked by the framework to add fixtures to the report.
+
+Apply `[AllureAttachment]` to a method that returns `string`, `byte[]`, `System.IO.Stream`,
+or async versions of these types (e.g., `Task`) to automatically attach returned values
+each time the method is called.
+
+Apply `[AllureAttachmentFile]` to a method that returns `string`, `FileInfo`, or async versions
+of these types (e.g., `Task`) to automatically attach files on each call. The returned
+values are treated as file paths.
+
+All four attributes mentioned above requires rely on AspectInjector. If you disable AspectInjector
+(e.g., by setting the `AspectInjector_Enabled` MSBuild property to `false`), the attributes won't
+do anything.
+
+### Controlling parameters
+
+There are two contexts where Allure automatically converts method arguments into Allure parameters:
+
+ - When creating a test result.
+ - When creating a step result.
+
+In both contexts, `[AllureParameter]` can be used to affect the conversion:
+
+ - Set `Ignored` to skip the argument.
+ - Use `Name` to explicitly name the parameter.
+ - Use `Mode` to mask or hide the value (the original value will still exist in the result files).
+ - Set `Excluded` to ignore the parameter when identifying the test that corresponds to the test
+ result (see [here](https://allurereport.org/docs/history-and-retries/#common-pitfall-a-test-s-retries-are-displayed-as-separate-tests)).
+
+Example:
+
+```csharp
+using Allure.Net.Commons;
+
+public class MyTests
+{
+ public void MyParameterizedTestMethod(
+ [AllureParameter(Ignore = true)] IUserService users,
+ [AllureParameter(Name = "User")] string userName,
+ [AllureParameter(Mode = ParameterMode.Masked)] string password,
+ [AllureParameter(Excluded = true)] DateTime timestamp
+ )
+ {
+ // ...
+ }
+}
+```
+
+### Attribute composition
+
+You can compose multiple attributes in two ways.
+
+#### Composition via an interface
+
+Apply the attributes to a new interface and apply the interface to the classes the attributes
+should affect:
+
+```csharp
+using Allure.Net.Commons.Attributes;
+
+[AllureEpic("My epic")]
+[AllureFeature("My feature")]
+[AllureIssue("125")]
+[AllureTag("acceptance")]
+public interface IMyFeatureTests { }
+
+public class MyTestClass : IMyFeatureTests
+{
+ // tests
+}
+
+public class AnotherTestClass : IMyFeatureTests
+{
+ // more tests
+}
+```
+
+#### Composition via `[AllureMeta]`
+
+Define a new attribute class that derives from `AllureMetaAttribute` and apply the attributes
+to this class. Use the new class to apply all the attributes to test classes and methods:
+
+```csharp
+using System;
+using Allure.Net.Commons.Attributes;
+
+[AllureEpic("My epic")]
+[AllureFeature("My feature")]
+[AllureIssue("125")]
+[AllureTag("acceptance")]
+public class MyFeatureAttribute : AllureMetaAttribute { }
+
+[MyFeature]
+public class MyTestClass : IMyFeatureTests
+{
+ // tests
+}
+
+public class AnotherTestClass : IMyFeatureTests
+{
+ [Test]
+ [MyFeature]
+ public void MyTestMethod()
+ {
+ // test body
+ }
+}
+```
+
+### Descriptions
+
+If `[AllureDescription]` is applied multiple times on different levels, the most specific one wins,
+unless you set `Append`. In such a case, all strings are joined with `\n\n` creating separate
+markdown paragraphs:
+
+```csharp
+[AllureDescription("Paragraph 1", Append = true)]
+class Base { }
+
+[AllureDescription("Paragraph 2", Append = true)]
+class TestClass : Base
+{
+ [Test]
+ [AllureDescription("Paragraph 3", Append = true)] // Without Append, the description will be just "Paragraph 3"
+ public void MyTest()
+ {
+ // test body
+ }
+}
+```
+
+For `[AllureDescriptionHtml]`, the behavior is almost the same. The only difference is that no
+separator is used to join multiple strings. Use block elements to keep the descriptions separate.
+
## Runtime API
Use this API to enhance the report at runtime.
@@ -116,10 +293,8 @@ functions.
* `SetStepName`
* `SetDescription`
* `SetDescriptionHtml`
-* `SetDescriptionHtml`
* `AddLabels`
* `AddLabel`
-* `SetLabel`
* `SetSeverity`
* `SetOwner`
* `SetAllureId`
@@ -132,17 +307,11 @@ functions.
#### Hierrarchies
* `AddParentSuite`
-* `SetParentSuite`
* `AddSuite`
-* `SetSuite`
* `AddSubSuite`
-* `SetSubSuite`
* `AddEpic`
-* `SetEpic`
* `AddFeature`
-* `SetFeature`
* `AddStory`
-* `SetStory`
#### Lambda steps
@@ -208,7 +377,7 @@ Use this class to access some less commonly used functions.
## The integration API
This API is designed for adapter or library authors. You may still use it as a
-test author, but we recommend considering the Runtime API first.
+test author, but we recommend considering the Attribute/Runtime API first.
### AllureLifecycle
diff --git a/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
new file mode 100644
index 00000000..6c3a1b1b
--- /dev/null
+++ b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Sdk;
+
+///
+/// A base class for attributes that apply metadata to test results.
+///
+public abstract class AllureApiAttribute : Attribute
+{
+ ///
+ /// Default targets for Allure metadata attributes.
+ ///
+ public const AttributeTargets ALLURE_METADATA_TARGETS
+ = AttributeTargets.Class
+ | AttributeTargets.Struct
+ | AttributeTargets.Method
+ | AttributeTargets.Interface;
+
+ ///
+ /// Applies the attribute to a test result.
+ ///
+ public abstract void Apply(TestResult testResult);
+
+ ///
+ /// Returns metadata attributes of a and its base methods.
+ ///
+ ///
+ /// Attributes of the base methods (virtual or abstract) are guaranteed to appear
+ /// before attributes of the derived ones.
+ ///
+ public static IEnumerable GetMethodAttributes(MethodInfo method)
+ => method
+ .GetCustomAttributes()
+ .Reverse();
+
+ ///
+ /// Returns metadata attributes of a .
+ ///
+ ///
+ /// Here are the guarantees about the order:
+ ///
+ /// - Attributes of interfaces before attributes of classes/structs.
+ /// -
+ /// Attributes of base classes before attributes of derived classes.
+ ///
+ ///
+ ///
+ public static IEnumerable GetTypeAttributes(Type type)
+ => type
+ .GetCustomAttributes()
+ .Concat(
+ type
+ .GetInterfaces()
+ .SelectMany(static (iFace) =>
+ iFace.GetCustomAttributes()))
+ .Reverse();
+
+ ///
+ /// Returns metadata attributes of a and its declaring
+ /// type.
+ ///
+ ///
+ /// Here are the guarantees about the order:
+ ///
+ /// - Attributes of interfaces before attributes of classes/structs.
+ /// -
+ /// Attributes of base classes before attributes of derived classes.
+ ///
+ /// - Attributes of classes/structs before attributes of methods
+ /// - Attributes of base methods before attributes of methods overrides.
+ ///
+ ///
+ public static IEnumerable GetAllAttributes(MethodInfo method)
+ => GetTypeAttributes(method.DeclaringType)
+ .Concat(
+ GetMethodAttributes(method)
+ );
+
+ ///
+ /// Applies metadata attributes of a and its base methods to
+ /// .
+ ///
+ ///
+ /// Attributes of the base methods (virtual or abstract) are guaranteed to be applied before
+ /// attributes of the derived ones.
+ ///
+ public static void ApplyMethodAttributes(MethodInfo method, TestResult testResult)
+ {
+ foreach (var attr in GetMethodAttributes(method))
+ {
+ attr.Apply(testResult);
+ }
+ }
+
+ ///
+ /// Applies metadata attributes of a , its base types, and implemented
+ /// interfaces to .
+ ///
+ ///
+ /// The following is guaranteed about the order of application:
+ ///
+ /// - Interfaces are handled before classes/structs.
+ /// - Base classes are handled before derived classes.
+ ///
+ ///
+ public static void ApplyTypeAttributes(Type type, TestResult testResult)
+ {
+ var typeAttributesToApply
+ = GetTypeAttributes(type)
+ .Where(static (a) => a is not AllureNameAttribute);
+
+ foreach (var attr in typeAttributesToApply)
+ {
+ attr.Apply(testResult);
+ }
+ }
+
+ ///
+ /// Applies metadata attributes of a and its declaring type
+ /// to a test result.
+ ///
+ ///
+ /// The following is guaranteed about the order of application:
+ ///
+ /// - Interfaces are handled before classes/structs.
+ /// - Base classes are handled before derived classes.
+ /// - Classes/structs are handled before methods
+ /// - Base methods are handled before methods overrides.
+ ///
+ ///
+ public static void ApplyAllAttributes(MethodInfo method, TestResult testResult)
+ {
+ ApplyTypeAttributes(method.DeclaringType, testResult);
+ ApplyMethodAttributes(method, testResult);
+ }
+
+ ///
+ /// Applies to .
+ ///
+ public static void ApplyAttributes(
+ IEnumerable attributes,
+ TestResult testResult
+ )
+ {
+ foreach (var attribute in attributes)
+ {
+ attribute.Apply(testResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
new file mode 100644
index 00000000..b9aedb62
--- /dev/null
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -0,0 +1,112 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using Allure.Net.Commons.Attributes;
+using AspectInjector.Broker;
+using HeyRed.Mime;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Sdk.Aspects;
+
+///
+/// An aspect that creates attachments from a functions' return values.
+///
+[Aspect(Scope.Global)]
+public class AllureAttachmentAspect
+{
+ [Advice(Kind.After)]
+ public void AttachReturnValue(
+ [Argument(Source.Name)] string name,
+ [Argument(Source.Metadata)] MethodBase metadata,
+ [Argument(Source.Arguments)] object[] arguments,
+ [Argument(Source.ReturnType)] Type returnType,
+ [Argument(Source.ReturnValue)] object? returnValue
+ )
+ {
+ if (!AllureApi.HasTestOrFixture)
+ {
+ return;
+ }
+
+ var attr = metadata.GetCustomAttribute();
+
+ var attachmentName = ResolveAttachmentName(attr, name, metadata, arguments);
+ var contentType = ResolveContentType(attr, returnType);
+ var extension = ResolveExtension(attr, contentType);
+ byte[] content = ResolveContent(attr, returnValue);
+
+ AllureApi.AddAttachmentInternal(attachmentName, contentType, content, extension);
+ }
+
+ static string ResolveAttachmentName(
+ AllureAttachmentAttribute? attr,
+ string name,
+ MethodBase methodInfo,
+ object[] arguments
+ )
+ => string.IsNullOrEmpty(attr?.Name)
+ ? name
+ : Steps.AllureStepParameterHelper.GetStepName(
+ attr!.Name,
+ methodInfo,
+ arguments,
+ AllureApi.CurrentLifecycle.TypeFormatters
+ );
+
+ static string? ResolveContentType(AllureAttachmentAttribute? attr, Type valueType)
+ => attr?.ContentType
+ ?? (valueType == typeof(string)
+ ? "text/plain"
+ : null);
+
+ static string ResolveExtension(AllureAttachmentAttribute? attr, string? contentType)
+ {
+ var extension
+ = attr?.Extension
+ ?? (contentType is null
+ ? ""
+ : MimeTypesMap.GetExtension(contentType))
+ ?? "";
+ return extension.Length == 0 || extension.StartsWith(".")
+ ? extension
+ : $".{extension}";
+ }
+
+ static byte[] ResolveContent(AllureAttachmentAttribute? attr, object? value) => value switch
+ {
+ null => [],
+ byte[] byteArray => byteArray,
+ string text => Encoding.GetEncoding(attr?.Encoding ?? "UTF-8").GetBytes(text),
+ Stream stream => ConsumeStream(stream),
+ _ => throw new InvalidOperationException(
+ $"Can't create an Allure attachment from {value.GetType().FullName}. "
+ + "A string, byte[], or stream was expected."
+ )
+ };
+
+ static byte[] ConsumeStream(Stream stream)
+ {
+ if (!stream.CanRead)
+ {
+ throw new InvalidOperationException(
+ $"Can't create an Allure attachment from {stream.GetType().FullName}: "
+ + "this stream does not support the read operation."
+ );
+ }
+
+ if (!stream.CanSeek)
+ {
+ throw new InvalidOperationException(
+ $"Can't create an Allure attachment from {stream.GetType().FullName}: "
+ + "this stream does not support the seek operation."
+ );
+ }
+
+ using var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+ stream.Position = 0;
+ return memoryStream.ToArray();
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentFileAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentFileAspect.cs
new file mode 100644
index 00000000..c71f5d7b
--- /dev/null
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentFileAspect.cs
@@ -0,0 +1,79 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using AspectInjector.Broker;
+using HeyRed.Mime;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Sdk.Aspects;
+
+///
+/// An aspect that creates attachments from files pointed by a functions' return values.
+///
+[Aspect(Scope.Global)]
+public class AllureAttachmentFileAspect
+{
+ [Advice(Kind.After)]
+ public void AttachReturnValue(
+ [Argument(Source.Name)] string name,
+ [Argument(Source.Metadata)] MethodBase metadata,
+ [Argument(Source.Arguments)] object[] arguments,
+ [Argument(Source.ReturnType)] Type returnType,
+ [Argument(Source.ReturnValue)] object? returnValue
+ )
+ {
+ if (!AllureApi.HasTestOrFixture)
+ {
+ return;
+ }
+
+ var attachmentFile = ResolveFile(returnValue);
+ if (attachmentFile is null)
+ {
+ return;
+ }
+
+ var attr = metadata.GetCustomAttribute();
+
+ var attachmentName = ResolveAttachmentName(attachmentFile, attr, metadata, arguments);
+ var contentType = attr?.ContentType;
+ var extension = ResolveExtension(attachmentFile, contentType);
+ var content = File.ReadAllBytes(attachmentFile.FullName);
+
+ AllureApi.AddAttachmentInternal(attachmentName, contentType, content, extension);
+ }
+
+ static FileInfo? ResolveFile(object? value) => value switch
+ {
+ null => null,
+ string path => new FileInfo(path),
+ FileInfo fInfo => fInfo,
+ _ => throw new InvalidOperationException(
+ $"Can't create an Allure file attachment from {value.GetType().FullName}. "
+ + "A string or System.IO.FileInfo was expected."),
+ };
+
+ static string ResolveAttachmentName(
+ FileInfo attachmentFile,
+ AllureAttachmentFileAttribute? attr,
+ MethodBase methodInfo,
+ object[] arguments
+ )
+ => string.IsNullOrEmpty(attr?.Name)
+ ? attachmentFile.Name
+ : Steps.AllureStepParameterHelper.GetStepName(
+ attr!.Name,
+ methodInfo,
+ arguments,
+ AllureApi.CurrentLifecycle.TypeFormatters
+ );
+
+ static string ResolveExtension(FileInfo attachmentFile, string? contentType)
+ => string.IsNullOrEmpty(attachmentFile.Extension)
+ ? (contentType is null
+ ? ""
+ : $".{MimeTypesMap.GetExtension(contentType)}")
+ : attachmentFile.Extension;
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Steps/AllureStepAspect.cs b/src/Allure.Net.Commons/Steps/AllureStepAspect.cs
index 0b518195..79296067 100644
--- a/src/Allure.Net.Commons/Steps/AllureStepAspect.cs
+++ b/src/Allure.Net.Commons/Steps/AllureStepAspect.cs
@@ -49,8 +49,14 @@ private static void ThrowStep(MethodBase metadata, Exception e)
}
}
- private static void StartFixture(MethodBase metadata, string fixtureName)
+ private static void StartFixture(
+ MethodBase metadata,
+ string fixtureName,
+ List parameters
+ )
{
+ bool hadFixture = ExtendedApi.HasFixture;
+
if (IsBeforeFixture(metadata))
{
ExtendedApi.StartBeforeFixture(fixtureName);
@@ -60,6 +66,13 @@ private static void StartFixture(MethodBase metadata, string fixtureName)
{
ExtendedApi.StartAfterFixture(fixtureName);
}
+
+ if (!hadFixture && ExtendedApi.HasFixture)
+ {
+ AllureLifecycle.Instance.UpdateFixture(
+ (fixture) => fixture.parameters.AddRange(parameters)
+ );
+ }
}
private static void PassFixture(MethodBase metadata)
@@ -88,7 +101,7 @@ Lazy> stepParameters
{
if (ExtendedApi.HasContainer)
{
- StartFixture(metadata, stepName.Value);
+ StartFixture(metadata, stepName.Value, stepParameters.Value);
}
if (ExtendedApi.HasTestOrFixture)
{
@@ -221,14 +234,18 @@ public object Around(
)
{
var formatters = AllureLifecycle.Instance.TypeFormatters;
- var stepNamePattern = metadata.GetCustomAttribute().Name ?? name;
+ var explicitName = metadata.GetCustomAttribute().Name;
var stepName = new Lazy(
- () => AllureStepParameterHelper.GetStepName(
- stepNamePattern,
- metadata,
- args,
- formatters
- )
+ explicitName is null
+ ? () => metadata.IsConstructor && name == ".ctor"
+ ? $"{metadata.DeclaringType.Name}.ctor"
+ : name
+ : () => AllureStepParameterHelper.GetStepName(
+ explicitName,
+ metadata,
+ args,
+ formatters
+ )
);
var stepParameters = new Lazy>(
() => AllureStepParameterHelper.GetStepParameters(
diff --git a/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs b/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
index 22f910c8..5f8bcda1 100644
--- a/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
+++ b/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
+using Allure.Net.Commons.Attributes;
using Allure.Net.Commons.Functions;
namespace Allure.Net.Commons.Steps
@@ -144,22 +145,37 @@ public static List GetStepParameters(
IReadOnlyDictionary formatters
)
{
- return metadata.GetParameters()
- .Select(x => (
- name: x.GetCustomAttribute()?.Name ?? x.Name,
- skip: x.GetCustomAttribute() != null))
- .Zip(args,
- (parameter, value) => parameter.skip
- ? null
- : new Parameter
- {
- name = parameter.name,
- value = FormatFunctions.Format(value, formatters)
- })
- .Where(x => x != null)
- .ToList();
+ return [
+ .. metadata
+ .GetParameters()
+ .Select(x => (
+ name: GetCustomParameterName(x) ?? x.Name,
+ skip: ShouldParameterBeIgnored(x),
+ mode: GetCustomParameterMode(x)))
+ .Zip(args,
+ (parameter, value) => parameter.skip
+ ? null
+ : new Parameter
+ {
+ name = parameter.name,
+ value = FormatFunctions.Format(value, formatters),
+ mode = parameter.mode,
+ })
+ .Where(x => x != null)
+ ];
}
+ static string GetCustomParameterName(ParameterInfo pInfo) =>
+ pInfo.GetCustomAttribute()?.Name
+ ?? pInfo.GetCustomAttribute()?.Name;
+
+ static bool ShouldParameterBeIgnored(ParameterInfo pInfo) =>
+ pInfo.GetCustomAttribute()?.Ignore == true
+ || pInfo.GetCustomAttribute() is not null;
+
+ static ParameterMode? GetCustomParameterMode(ParameterInfo pInfo) =>
+ pInfo.GetCustomAttribute()?.Mode;
+
private static bool TrySplit(string s, char separator, out string[] parts)
{
parts = s.Split(separator);
diff --git a/src/Allure.Xunit/AllureMessageSink.cs b/src/Allure.Xunit/AllureMessageSink.cs
index 7fb7a079..adcbc13a 100644
--- a/src/Allure.Xunit/AllureMessageSink.cs
+++ b/src/Allure.Xunit/AllureMessageSink.cs
@@ -231,7 +231,11 @@ void AddAllureParameters(ITest test, object[]? arguments)
}
else
{
- AllureXunitHelper.ApplyTestParameters(parameters, arguments);
+ AllureXunitHelper.ApplyTestParameters(
+ testCase.TestMethod.Method.ToRuntimeMethod(),
+ parameters,
+ arguments
+ );
}
}
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index 31637644..fe688ef2 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -2,9 +2,11 @@
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
using Allure.Net.Commons.Functions;
-using Allure.Xunit.Attributes;
+using Allure.Net.Commons.Sdk;
using Xunit;
using Xunit.Abstractions;
@@ -89,25 +91,32 @@ internal static void ApplyTestSkip(ITestSkipped skip)
}
internal static void ApplyTestParameters(
+ MethodInfo methodInfo,
IEnumerable parameters,
object[] arguments
)
{
- var parametersList = parameters.Zip(
- arguments,
- (param, value) => new Parameter
- {
- name = param.Name,
- value = FormatFunctions.Format(
- value,
- AllureLifecycle.Instance.TypeFormatters
- )
- }
- ).ToList();
+ var runtimeParameters
+ = methodInfo
+ .GetParameters()
+ .ToDictionary(static (p) => p.Name);
+
+ Parameter[] parametersFromMethod = [
+ ..ModelFunctions.CreateParameters(
+ parameters.Select(static (p) => p.Name),
+ parameters.Select((p) =>
+ runtimeParameters.TryGetValue(p.Name, out var pInfo)
+ ? pInfo.GetCustomAttribute()
+ : null),
+ arguments,
+ AllureLifecycle.Instance.TypeFormatters
+ )
+ ];
AllureLifecycle.Instance.UpdateTestCase(testResult =>
{
- testResult.parameters = parametersList;
+ var dynamicParameters = testResult.parameters;
+ testResult.parameters = [..parametersFromMethod, ..dynamicParameters];
});
}
@@ -117,21 +126,28 @@ internal static void ApplyDefaultSuites(ITestMethod method)
var runtimeType = testClass.ToRuntimeType();
var assemblyName = runtimeType?.Assembly?.GetName().Name;
var @namespace = runtimeType?.Namespace;
- var className =
- string.IsNullOrEmpty(@namespace)
- ? testClass.Name
- : testClass.Name?.Substring(@namespace!.Length + 1);
+ var subSuite = ResolveSubSuite(testClass, runtimeType, @namespace);
AllureLifecycle.Instance.UpdateTestCase(
testResult => ModelFunctions.EnsureSuites(
testResult,
assemblyName,
@namespace,
- className
+ subSuite
)
);
}
+ static string? ResolveSubSuite(ITypeInfo xunitTestClass, Type? testClass, string? @namespace)
+ => (testClass is null ? null : AllureApiAttribute
+ .GetTypeAttributes(testClass)
+ .OfType()
+ .LastOrDefault()
+ ?.Name)
+ ?? (string.IsNullOrEmpty(@namespace)
+ ? xunitTestClass.Name
+ : xunitTestClass.Name?.Substring(@namespace!.Length + 1));
+
internal static void ReportCurrentTestCase()
{
AllureLifecycle.Instance.StopTestCase();
@@ -179,7 +195,8 @@ string displayName
]
};
SetTestResultIdentifiers(testCase, displayName, testResult);
- UpdateTestDataFromAttributes(testResult, testMethod);
+ ApplyLegacyAllureAttributes(testResult, testMethod);
+ ApplyAllureAttributes(testResult, testMethod);
return testResult;
}
@@ -243,23 +260,32 @@ TestResult testResult
testResult.historyId = displayName;
}
- static void UpdateTestDataFromAttributes(
+ static void ApplyAllureAttributes(TestResult testResult, ITestMethod xunitTestMethod)
+ {
+ var method = xunitTestMethod.Method.ToRuntimeMethod();
+ var testClass = xunitTestMethod.TestClass.Class.ToRuntimeType();
+
+ AllureApiAttribute.ApplyTypeAttributes(testClass, testResult);
+ AllureApiAttribute.ApplyMethodAttributes(method, testResult);
+ }
+
+ static void ApplyLegacyAllureAttributes(
TestResult testResult,
ITestMethod method
)
{
var classAttributes = method.TestClass.Class.GetCustomAttributes(
- typeof(IAllureInfo)
+ typeof(Attributes.IAllureInfo)
);
var methodAttributes = method.Method.GetCustomAttributes(
- typeof(IAllureInfo)
+ typeof(Attributes.IAllureInfo)
);
foreach (var attribute in classAttributes.Concat(methodAttributes))
{
switch (((IReflectionAttributeInfo)attribute).Attribute)
{
- case AllureFeatureAttribute featureAttribute:
+ case Attributes.AllureFeatureAttribute featureAttribute:
testResult.labels.AddDistinct(
"feature",
featureAttribute.Features,
@@ -267,43 +293,43 @@ ITestMethod method
);
break;
- case AllureLinkAttribute linkAttribute:
+ case Attributes.AllureLinkAttribute linkAttribute:
testResult.links.Add(linkAttribute.Link);
break;
- case AllureIssueAttribute issueAttribute:
+ case Attributes.AllureIssueAttribute issueAttribute:
testResult.links.Add(issueAttribute.IssueLink);
break;
- case AllureOwnerAttribute ownerAttribute:
+ case Attributes.AllureOwnerAttribute ownerAttribute:
testResult.labels.AddDistinct(
Label.Owner(ownerAttribute.Owner),
ownerAttribute.Overwrite
);
break;
- case AllureSuiteAttribute suiteAttribute:
+ case Attributes.AllureSuiteAttribute suiteAttribute:
testResult.labels.AddDistinct(
Label.Suite(suiteAttribute.Suite),
suiteAttribute.Overwrite
);
break;
- case AllureSubSuiteAttribute subSuiteAttribute:
+ case Attributes.AllureSubSuiteAttribute subSuiteAttribute:
testResult.labels.AddDistinct(
Label.SubSuite(subSuiteAttribute.SubSuite),
subSuiteAttribute.Overwrite
);
break;
- case AllureEpicAttribute epicAttribute:
+ case Attributes.AllureEpicAttribute epicAttribute:
testResult.labels.AddDistinct(
Label.Epic(epicAttribute.Epic),
epicAttribute.Overwrite
);
break;
- case AllureTagAttribute tagAttribute:
+ case Attributes.AllureTagAttribute tagAttribute:
testResult.labels.AddDistinct(
"tag",
tagAttribute.Tags,
@@ -311,21 +337,21 @@ ITestMethod method
);
break;
- case AllureSeverityAttribute severityAttribute:
+ case Attributes.AllureSeverityAttribute severityAttribute:
testResult.labels.AddDistinct(
Label.Severity(severityAttribute.Severity),
true
);
break;
- case AllureParentSuiteAttribute parentSuiteAttribute:
+ case Attributes.AllureParentSuiteAttribute parentSuiteAttribute:
testResult.labels.AddDistinct(
Label.ParentSuite(parentSuiteAttribute.ParentSuite),
parentSuiteAttribute.Overwrite
);
break;
- case AllureStoryAttribute storyAttribute:
+ case Attributes.AllureStoryAttribute storyAttribute:
testResult.labels.AddDistinct(
"story",
storyAttribute.Stories,
@@ -333,11 +359,11 @@ ITestMethod method
);
break;
- case AllureDescriptionAttribute descriptionAttribute:
+ case Attributes.AllureDescriptionAttribute descriptionAttribute:
testResult.description = descriptionAttribute.Description;
break;
- case AllureIdAttribute allureIdAttribute:
+ case Attributes.AllureIdAttribute allureIdAttribute:
var allureIdLabel = new Label
{
name = "ALLURE_ID",
@@ -346,7 +372,7 @@ ITestMethod method
testResult.labels.AddDistinct(allureIdLabel, false);
break;
- case AllureLabelAttribute labelAttribute:
+ case Attributes.AllureLabelAttribute labelAttribute:
var label = new Label()
{
name = labelAttribute.Label,
diff --git a/src/Allure.Xunit/README.md b/src/Allure.Xunit/README.md
index fba2e454..d0e93b9b 100644
--- a/src/Allure.Xunit/README.md
+++ b/src/Allure.Xunit/README.md
@@ -37,7 +37,162 @@ Some examples are available [here](https://github.com/allure-framework/allure-cs
## Notes
-### Namespaces consolidated to Allure.Xunit
+### New in 2.15.0: the common Attribute API
+
+Use the attributes in `Allure.Net.Commons.Attributes` instead of `Allure.Xunit.Attributes`. Read more details [here](https://github.com/allure-framework/allure-csharp/pull/647).
+
+In most cases, the migration is straightforward:
+
+```diff
+- using Allure.Xunit.Attributes;
++ using Allure.Net.Commons.Attributes;
+using Xunit;
+
+[AllureFeature("My feature")]
+public class MyTestClass
+{
+ [AllureStory("My story")]
+ [Fact]
+ public void MyTestMethod()
+ {
+
+ }
+}
+```
+
+In some cases, the usage must be updated. Such cases are listed below.
+
+#### `[AllureFeature]`, `[AllureStory]` with multiple values
+
+Use multiple `[AllureFeature]` or `[AllureStory]` attributes instead:
+
+```diff
+- using Allure.Xunit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureFeature("Feature 1", "Feature 2")]
++[AllureFeature("Feature 1")]
++[AllureFeature("Feature 2")]
+-[AllureStory("Story 1", "Story 2")]
++[AllureStory("Story 1")]
++[AllureStory("Story 2")]
+public class MyTestClass
+{
+}
+```
+
+#### `[AllureLink]`, `[AllureIssue]`
+
+Pass the URL or ID as the only positional argument. Use the `Title` property to pass the display
+text:
+
+```diff
+- using Allure.Xunit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureLink("Homepage", "https://allurereport.org")]
++[AllureLink("https://allurereport.org", Title = "Homepage")]
+-[AllureIssue("ISSUE-123", "123")]
++[AllureIssue("123", Title = "ISSUE-123")]
+public class MyTestClass
+{
+}
+```
+
+#### `[AllureSeverity]`
+
+Always pass an explicit value as the argument:
+
+```diff
+- using Allure.Xunit.Attributes;
++ using Allure.Net.Commons.Attributes;
+
+-[AllureSeverity]
++[AllureSeverity(SeverityLevel.normal)]
+public class MyTestClass
+{
+}
+```
+
+#### `[Name]` and `[Skip]`
+
+Use `[AllureParameter]` with `Name` and `Ignore` correspondingly:
+
+```diff
+- using Allure.Xunit.Attributes.Steps;
++ using Allure.Net.Commons.Attributes;
+
+public class MyTestClass
+{
+ [AllureStep]
+ public void MyStepMethod(
+- [Name("Foo")] int parameter1,
++ [AllureParameter(Name = "Foo")] int parameter1,
+- [Skip] int parameter2
++ [AllureParameter(Ignore = true)] int parameter2
+ )
+ {
+ }
+}
+```
+
+#### `[AllureId]`
+
+Pass an integer value instead of a string:
+
+```diff
+- using Allure.Xunit.Attributes;
++ using Allure.Net.Commons.Attributes;
+using Xunit;
+
+public class MyTestClass
+{
+ [Fact]
+- [AllureId("102")]
++ [AllureId(102)]
+ public void MyTestMethod()
+ {
+ }
+}
+```
+
+#### The `Overwrite` argument
+
+The new attributes don't have an equivalent of the `overwrite` argument that removes the existing
+metadata. You should rearrange the attributes to avoid duplicates:
+
+```diff
+-using Allure.Xunit.Attributes;
++using Allure.Net.Commons.Attributes;
+using Xunit;
+
+-[AllureEpic(["Epic 1"], true)]
+public class TestClass
+{
+ [Fact]
+- [AllureEpic(["Epic 2"], true)]
++ [AllureEpic("Epic 2")]
+ public void Test1()
+ {
+
+ }
+
+ [Fact]
+- [AllureEpic(["Epic 3"], true)]
++ [AllureEpic("Epic 3")]
+ public void Test1()
+ {
+
+ }
+}
+```
+
+#### Deprecation notice
+
+Attributes from the `Allure.Xunit.Attributes` namespace will be deprecated in one of the future
+releases. Please, migrate to `Allure.Net.Commons.Attributes`.
+
+### New in 2.12.0: Namespaces consolidated to Allure.Xunit
Previously, the package contained a mix of `Allure.Xunit` and `Allure.XUnit`
namespaces. Starting from 2.12.0, you should only use `Allure.Xunit`. The API is
diff --git a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
index 6c0fd7b6..6cede44e 100644
--- a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
+++ b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
@@ -7,7 +7,10 @@
-
+
+
+
+
diff --git a/tests/Allure.NUnit.Tests/EpicTests.cs b/tests/Allure.NUnit.Tests/AllureIdTests.cs
similarity index 56%
rename from tests/Allure.NUnit.Tests/EpicTests.cs
rename to tests/Allure.NUnit.Tests/AllureIdTests.cs
index 9c8048c0..75fff0c0 100644
--- a/tests/Allure.NUnit.Tests/EpicTests.cs
+++ b/tests/Allure.NUnit.Tests/AllureIdTests.cs
@@ -3,17 +3,16 @@
namespace Allure.NUnit.Tests;
-class EpicTests
+class AllureIdTests
{
- public static IEnumerable> GetEpicSamples()
+ public static IEnumerable> GetAllureIdSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.EpicAttributeOnClass,
- AllureSampleRegistry.EpicAttributeOnMethod,
- AllureSampleRegistry.EpicAttributeOnBaseClass,
- AllureSampleRegistry.AddEpicFromSetUp,
- AllureSampleRegistry.AddEpicFromTest,
- AllureSampleRegistry.AddEpicFromTearDown,
+ AllureSampleRegistry.SetAllureIdFromSetUp,
+ AllureSampleRegistry.SetAllureIdFromTest,
+ AllureSampleRegistry.SetAllureIdFromTearDown,
+ AllureSampleRegistry.AllureIdAttributeOnMethod,
+ AllureSampleRegistry.LegacyAllureIdAttributeOnMethod,
];
return samples.Select(static (sample) =>
@@ -21,8 +20,8 @@ public static IEnumerable> GetEpicSamples
}
[Test]
- [MethodDataSource(nameof(GetEpicSamples))]
- public async Task CheckEpicIsAdded(AllureSampleRegistryEntry sample)
+ [MethodDataSource(nameof(GetAllureIdSamples))]
+ public async Task CheckAllureIdLabelIsAdded(AllureSampleRegistryEntry sample)
{
var results = await AllureSampleRunner.RunAsync(sample);
@@ -31,7 +30,7 @@ public async Task CheckEpicIsAdded(AllureSampleRegistryEntry sample)
await Assert.That(nodes).Any(
l =>
{
- return (string)l["name"] == "epic" && (string)l["value"] == "foo";
+ return (string)l["name"] == "ALLURE_ID" && (string)l["value"] == "1001";
}
);
}
diff --git a/tests/Allure.NUnit.Tests/BddLabelTests.cs b/tests/Allure.NUnit.Tests/BddLabelTests.cs
new file mode 100644
index 00000000..53476d26
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/BddLabelTests.cs
@@ -0,0 +1,151 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class BddLabelTests
+{
+ public static IEnumerable> GetBddHierarchySamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.BddHierarchyAttributeOnClass,
+ AllureSampleRegistry.BddHierarchyAttributeOnMethod,
+ AllureSampleRegistry.BddHierarchyAttributeOnBaseClass,
+ AllureSampleRegistry.BddHierarchyAttributeOnInterface,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetBddHierarchySamples))]
+ public async Task CheckBddLabelsAreAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "epic" && (string)l["value"] == "foo";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "feature" && (string)l["value"] == "bar";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "story" && (string)l["value"] == "baz";
+ }
+ );
+ }
+
+ public static IEnumerable> GetEpicSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.EpicAttributeOnClass,
+ AllureSampleRegistry.EpicAttributeOnMethod,
+ AllureSampleRegistry.EpicAttributeOnBaseClass,
+ AllureSampleRegistry.EpicAttributeOnInterface,
+ AllureSampleRegistry.AddEpicFromSetUp,
+ AllureSampleRegistry.AddEpicFromTest,
+ AllureSampleRegistry.AddEpicFromTearDown,
+ AllureSampleRegistry.LegacyEpicAttributeOnClass,
+ AllureSampleRegistry.LegacyEpicAttributeOnMethod,
+ AllureSampleRegistry.LegacyEpicAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetEpicSamples))]
+ public async Task CheckEpicIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "epic" && (string)l["value"] == "foo";
+ }
+ );
+ }
+
+ public static IEnumerable> GetFeatureSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.FeatureAttributeOnClass,
+ AllureSampleRegistry.FeatureAttributeOnMethod,
+ AllureSampleRegistry.FeatureAttributeOnBaseClass,
+ AllureSampleRegistry.FeatureAttributeOnInterface,
+ AllureSampleRegistry.AddFeatureFromSetUp,
+ AllureSampleRegistry.AddFeatureFromTest,
+ AllureSampleRegistry.AddFeatureFromTearDown,
+ AllureSampleRegistry.LegacyFeatureAttributeOnClass,
+ AllureSampleRegistry.LegacyFeatureAttributeOnMethod,
+ AllureSampleRegistry.LegacyFeatureAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetFeatureSamples))]
+ public async Task CheckFeatureIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "feature" && (string)l["value"] == "foo";
+ }
+ );
+ }
+
+ public static IEnumerable> GetStorySamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.StoryAttributeOnClass,
+ AllureSampleRegistry.StoryAttributeOnMethod,
+ AllureSampleRegistry.StoryAttributeOnBaseClass,
+ AllureSampleRegistry.StoryAttributeOnInterface,
+ AllureSampleRegistry.AddStoryFromSetUp,
+ AllureSampleRegistry.AddStoryFromTest,
+ AllureSampleRegistry.AddStoryFromTearDown,
+ AllureSampleRegistry.LegacyStoryAttributeOnClass,
+ AllureSampleRegistry.LegacyStoryAttributeOnMethod,
+ AllureSampleRegistry.LegacyStoryAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetStorySamples))]
+ public async Task CheckStoryIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "story" && (string)l["value"] == "foo";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/CustomLabelTests.cs b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
index dcb158cb..0503051d 100644
--- a/tests/Allure.NUnit.Tests/CustomLabelTests.cs
+++ b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
@@ -11,9 +11,13 @@ public static IEnumerable> GetCustomLabel
AllureSampleRegistry.LabelAttributeOnClass,
AllureSampleRegistry.LabelAttributeOnMethod,
AllureSampleRegistry.LabelAttributeOnBaseClass,
+ AllureSampleRegistry.LabelAttributeOnInterface,
AllureSampleRegistry.AddLabelFromSetUp,
AllureSampleRegistry.AddLabelFromTest,
AllureSampleRegistry.AddLabelFromTearDown,
+ AllureSampleRegistry.LegacyLabelAttributeOnClass,
+ AllureSampleRegistry.LegacyLabelAttributeOnMethod,
+ AllureSampleRegistry.LegacyLabelAttributeOnBaseClass,
];
return samples.Select(static (sample) =>
diff --git a/tests/Allure.NUnit.Tests/DescriptionTests.cs b/tests/Allure.NUnit.Tests/DescriptionTests.cs
new file mode 100644
index 00000000..57a797a1
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/DescriptionTests.cs
@@ -0,0 +1,118 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class DescriptionTests
+{
+ public static IEnumerable> GetCommonDescriptionSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.NUnitDescriptionAttributeOnMethod,
+ AllureSampleRegistry.NUnitDescriptionAttributeOnClass,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTest,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTestCase,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTestFixture,
+ AllureSampleRegistry.DescriptionAttributeOnMethod,
+ AllureSampleRegistry.DescriptionAttributeOnClass,
+ AllureSampleRegistry.DescriptionAttributeOnBaseClass,
+ AllureSampleRegistry.DescriptionAttributeOnInterface,
+ AllureSampleRegistry.AddDescriptionFromSetUp,
+ AllureSampleRegistry.AddDescriptionFromTest,
+ AllureSampleRegistry.AddDescriptionFromTearDown,
+ AllureSampleRegistry.LegacyDescriptionAttribute,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetCommonDescriptionSamples))]
+ public async Task CheckDescriptionIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["description"]).IsEqualTo("Lorem Ipsum");
+ }
+
+ public static IEnumerable> GetHtmlDescriptionSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.DescriptionHtmlAttributeOnMethod,
+ AllureSampleRegistry.DescriptionHtmlAttributeOnClass,
+ AllureSampleRegistry.DescriptionHtmlAttributeOnBaseClass,
+ AllureSampleRegistry.DescriptionHtmlAttributeOnInterface,
+ AllureSampleRegistry.AddDescriptionHtmlFromSetUp,
+ AllureSampleRegistry.AddDescriptionHtmlFromTest,
+ AllureSampleRegistry.AddDescriptionHtmlFromTearDown,
+ AllureSampleRegistry.LegacyDescriptionAttributeHtml,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetHtmlDescriptionSamples))]
+ public async Task CheckHtmlDescriptionIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["descriptionHtml"]).IsEqualTo("Lorem Ipsum");
+ }
+
+ [Test]
+ public async Task NUnitDescriptionAttributesCompose()
+ {
+ var results = await AllureSampleRunner.RunAsync(
+ AllureSampleRegistry.NUnitDescriptionAttributeComposition
+ );
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert
+ .That((string)results.TestResults[0]["description"])
+ .IsEqualTo("Lorem Ipsum\n\nDolor Sit Amet");
+ }
+
+ [Test]
+ public async Task NUnitDescriptionPropertiesCompose()
+ {
+ var results = await AllureSampleRunner.RunAsync(
+ AllureSampleRegistry.NUnitDescriptionPropertyComposition
+ );
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert
+ .That((string)results.TestResults[0]["description"])
+ .IsEqualTo("Lorem Ipsum\n\nDolor Sit Amet\n\nConsectetur Adipiscing Elit");
+ }
+
+ [Test]
+ public async Task NUnitDescriptionIgnoredIfDescriptionAlreadyProvided()
+ {
+ var results = await AllureSampleRunner.RunAsync(
+ AllureSampleRegistry.NUnitDescriptionPropertyWithAllureDescription
+ );
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert
+ .That((string)results.TestResults[0]["description"])
+ .IsEqualTo("Lorem Ipsum");
+ }
+
+ [Test]
+ public async Task NUnitDescriptionIgnoredIfDescriptionHtmlAlreadyProvided()
+ {
+ var results = await AllureSampleRunner.RunAsync(
+ AllureSampleRegistry.NUnitDescriptionPropertyWithAllureDescriptionHtml
+ );
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert
+ .That((string)results.TestResults[0]["description"])
+ .IsNull();
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/FeatureTests.cs b/tests/Allure.NUnit.Tests/FeatureTests.cs
deleted file mode 100644
index 7ba02bb1..00000000
--- a/tests/Allure.NUnit.Tests/FeatureTests.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class FeatureTests
-{
- public static IEnumerable> GetFeatureSamples()
- {
- IEnumerable samples = [
- AllureSampleRegistry.FeatureAttributeOnClass,
- AllureSampleRegistry.FeatureAttributeOnMethod,
- AllureSampleRegistry.FeatureAttributeOnBaseClass,
- AllureSampleRegistry.AddFeatureFromSetUp,
- AllureSampleRegistry.AddFeatureFromTest,
- AllureSampleRegistry.AddFeatureFromTearDown,
- ];
-
- return samples.Select(static (sample) =>
- new TestDataRow(sample, DisplayName: sample.Id));
- }
-
- [Test]
- [MethodDataSource(nameof(GetFeatureSamples))]
- public async Task CheckFeatureIsAdded(AllureSampleRegistryEntry sample)
- {
- var results = await AllureSampleRunner.RunAsync(sample);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var nodes = results.TestResults[0]["labels"].AsArray().Cast();
- await Assert.That(nodes).Any(
- l =>
- {
- return (string)l["name"] == "feature" && (string)l["value"] == "foo";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/FixtureTests.cs b/tests/Allure.NUnit.Tests/FixtureTests.cs
new file mode 100644
index 00000000..3ff4a1fc
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/FixtureTests.cs
@@ -0,0 +1,78 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class FixtureTests
+{
+ record class ContainerExpectation(
+ string Name,
+ List Befores,
+ List Afters
+ )
+ {
+ public bool Check(JsonObject fixture)
+ => (string)fixture["name"] == this.Name
+ && StepTests.StepExpectations.CheckAll(
+ this.Befores,
+ fixture["befores"].AsArray())
+ && StepTests.StepExpectations.CheckAll(
+ this.Afters,
+ fixture["afters"].AsArray());
+ }
+
+ [Test]
+ [Skip("Can't emit OneTime-fixture container: need sdk hook")]
+ public async Task FixtureAttributesWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.FixtureAttributes);
+
+ var testResults = results.TestResults.Cast().ToArray();
+ var containers = results.Containers.Cast().ToArray();
+
+ await Assert.That(containers).Count().IsEqualTo(2);
+ await Assert.That(testResults).Count().IsEqualTo(1);
+ var uuid = (string)testResults[0]["uuid"];
+ await Assert.That(containers).Any(
+ (c) => new ContainerExpectation(
+ "Allure.NUnit.Tests.Samples.LegacyFixtureAttributes.TestsClass",
+ [new StepTests.StepExpectations("OneTimeSetUp", "passed", [], [])],
+ [new StepTests.StepExpectations("Bar", "passed", [], [])]
+ ).Check(c)
+ );
+ await Assert.That(containers).Any(
+ (c) => new ContainerExpectation(
+ "Allure.NUnit.Tests.Samples.LegacyFixtureAttributes.TestsClass.TestMethod",
+ [new StepTests.StepExpectations("Foo", "passed", [], [])],
+ [new StepTests.StepExpectations("TearDown", "passed", [], [])]
+ ).Check(c)
+ );
+ }
+
+ [Test]
+ public async Task LegacyFixtureAttributesWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyFixtureAttributes);
+
+ var testResults = results.TestResults.Cast().ToArray();
+ var containers = results.Containers.Cast().ToArray();
+
+ await Assert.That(containers).Count().IsEqualTo(2);
+ await Assert.That(testResults).Count().IsEqualTo(1);
+ var uuid = (string)testResults[0]["uuid"];
+ await Assert.That(containers).Any(
+ (c) => new ContainerExpectation(
+ "Allure.NUnit.Tests.Samples.LegacyFixtureAttributes.TestsClass",
+ [new StepTests.StepExpectations("OneTimeSetUp", "passed", [], [])],
+ [new StepTests.StepExpectations("Bar", "passed", [], [])]
+ ).Check(c)
+ );
+ await Assert.That(containers).Any(
+ (c) => new ContainerExpectation(
+ "Allure.NUnit.Tests.Samples.LegacyFixtureAttributes.TestsClass.TestMethod",
+ [new StepTests.StepExpectations("Foo", "passed", [], [])],
+ [new StepTests.StepExpectations("TearDown", "passed", [], [])]
+ ).Check(c)
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/LinkTests.cs b/tests/Allure.NUnit.Tests/LinkTests.cs
new file mode 100644
index 00000000..d3f54045
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/LinkTests.cs
@@ -0,0 +1,221 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class LinkTests
+{
+ [Test]
+ public async Task CheckLinksRuntimeApiWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddLinksAtRuntime);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(4);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && l["type"] is null);
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && l["type"] is null);
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "name-3"
+ && (string)l["type"] == "type-3");
+ await Assert.That(links[3]).Satisfies(static (l) =>
+ (string)l["url"] == "url-4"
+ && (string)l["name"] == "name-4"
+ && (string)l["type"] == "type-4");
+ }
+
+ [Test]
+ public async Task CheckLegacyLinkAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyLinkAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(3);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "name-3"
+ && (string)l["type"] == "link");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "link");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && (string)l["name"] == "url-1"
+ && (string)l["type"] == "link");
+ }
+
+ [Test]
+ public async Task CheckLinkAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LinkAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(4);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && l["type"] is null);
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && l["type"] is null);
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && l["name"] is null
+ && (string)l["type"] == "type-3");
+ await Assert.That(links[3]).Satisfies(static (l) =>
+ (string)l["url"] == "url-4"
+ && (string)l["name"] == "name-4"
+ && (string)l["type"] == "type-4");
+ }
+
+ [Test]
+ public async Task CheckIssuesRuntimeApiWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddIssuesAtRuntime);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(3);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && (string)l["type"] == "issue");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "issue");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "name-3"
+ && (string)l["type"] == "issue");
+ }
+
+ [Test]
+ public async Task CheckLegacyIssueAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyIssueAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(3);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "url-3"
+ && (string)l["type"] == "issue");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "issue");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && (string)l["name"] == "url-1"
+ && (string)l["type"] == "issue");
+ }
+
+ [Test]
+ public async Task CheckIssueAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.IssueAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(4);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && (string)l["type"] == "issue");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "issue");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && l["name"] is null
+ && (string)l["type"] == "issue");
+ await Assert.That(links[3]).Satisfies(static (l) =>
+ (string)l["url"] == "url-4"
+ && l["name"] is null
+ && (string)l["type"] == "issue");
+ }
+
+ [Test]
+ public async Task CheckTmsLinksRuntimeApiWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddTmsItemsAtRuntime);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(3);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "tms");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "name-3"
+ && (string)l["type"] == "tms");
+ }
+
+ [Test]
+ public async Task CheckLegacyTmsAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyTmsAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(3);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "url-3"
+ && (string)l["type"] == "tms");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "tms");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && (string)l["name"] == "url-1"
+ && (string)l["type"] == "tms");
+ }
+
+ [Test]
+ public async Task CheckTmsItemAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.TmsItemAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(4);
+ await Assert.That(links[0]).Satisfies(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ await Assert.That(links[1]).Satisfies(static (l) =>
+ (string)l["url"] == "url-2"
+ && (string)l["name"] == "name-2"
+ && (string)l["type"] == "tms");
+ await Assert.That(links[2]).Satisfies(static (l) =>
+ (string)l["url"] == "url-3"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ await Assert.That(links[3]).Satisfies(static (l) =>
+ (string)l["url"] == "url-4"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/MetaAttributeTests.cs b/tests/Allure.NUnit.Tests/MetaAttributeTests.cs
new file mode 100644
index 00000000..fc756439
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/MetaAttributeTests.cs
@@ -0,0 +1,66 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class MetaAttributeTests
+{
+ [Test]
+ public async Task MetaAttributeShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.MetaAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+
+ var labels = results.TestResults[0]["labels"].AsArray().Cast();
+ var links = results.TestResults[0]["links"].AsArray().Cast();
+
+ await Assert.That(labels).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "epic" && (string)l["value"] == "Foo";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "owner" && (string)l["value"] == "John Doe";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "feature" && (string)l["value"] == "Bar";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "tag" && (string)l["value"] == "foo";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "tag" && (string)l["value"] == "bar";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "story" && (string)l["value"] == "Baz";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "severity" && (string)l["value"] == "critical";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "suite" && (string)l["value"] == "Qux";
+ }
+ );
+ await Assert.That(links).Any(
+ static (l) =>
+ (string)l["url"] == "https://foo.bar/"
+ && l["name"] is null
+ && l["type"] is null
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/NameTests.cs b/tests/Allure.NUnit.Tests/NameTests.cs
new file mode 100644
index 00000000..e27bbe97
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/NameTests.cs
@@ -0,0 +1,58 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class NameTests
+{
+ public static IEnumerable> GetTestRenameSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SetTestNameFromSetUp,
+ AllureSampleRegistry.SetTestNameFromTest,
+ AllureSampleRegistry.SetTestNameFromTearDown,
+ AllureSampleRegistry.LegacyNameAttribute,
+ AllureSampleRegistry.NameAttributeOnMethod,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetTestRenameSamples))]
+ public async Task CheckTestCanBeRenamed(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["name"]).IsEqualTo("Lorem Ipsum");
+ }
+
+ [Test]
+ public async Task MethodNameIsUsedForTestCases()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.SingleTescCase);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["name"]).IsEqualTo("TestMethod");
+ }
+
+ [Test]
+ public async Task CheckAllureNameOnTestFixtureAffectsSuiteOnly()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.NameAttributeOnClass);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var testResult = results.TestResults[0];
+ await Assert.That((string)testResult["name"]).IsEqualTo("TestMethod");
+ var labels = testResult["labels"].AsArray().Cast();
+ var subSuiteLabel = labels.First(static (l) => (string)l["name"] == "subSuite");
+ await Assert.That((string)subSuiteLabel["value"]).IsEqualTo("Lorem Ipsum");
+ await Assert.That(labels).Any(
+ static (l) => (string)l["name"] == "parentSuite"
+ ).And.Any(
+ static (l) => (string)l["name"] == "suite"
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.NUnit.Tests/OwnerTests.cs b/tests/Allure.NUnit.Tests/OwnerTests.cs
new file mode 100644
index 00000000..cff3431b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/OwnerTests.cs
@@ -0,0 +1,41 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class OwnerTests
+{
+ public static IEnumerable> GetOwnerSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.NUnitAuthorPropertyOnTest,
+ AllureSampleRegistry.NUnitAuthorPropertyOnTestCase,
+ AllureSampleRegistry.NUnitAuthorPropertyOnTestFixture,
+ AllureSampleRegistry.OwnerAttributeOnBaseClass,
+ AllureSampleRegistry.OwnerAttributeOnClass,
+ AllureSampleRegistry.OwnerAttributeOnInterface,
+ AllureSampleRegistry.OwnerAttributeOnMethod,
+ AllureSampleRegistry.SetOwnerFromSetUp,
+ AllureSampleRegistry.SetOwnerFromTearDown,
+ AllureSampleRegistry.SetOwnerFromTest,
+ AllureSampleRegistry.LegacyOwnerAttributeOnClass,
+ AllureSampleRegistry.LegacyOwnerAttributeOnMethod,
+ AllureSampleRegistry.LegacyOwnerAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetOwnerSamples))]
+ public async Task CheckOwnerIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var labels = results.TestResults[0]["labels"].AsArray().Cast();
+ var owner = labels.First(static (l) => (string)l["name"] == "owner");
+ await Assert.That((string)owner["value"]).IsEqualTo("John Doe");
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/ParameterTests.cs b/tests/Allure.NUnit.Tests/ParameterTests.cs
index 722de25b..ca07a3b1 100644
--- a/tests/Allure.NUnit.Tests/ParameterTests.cs
+++ b/tests/Allure.NUnit.Tests/ParameterTests.cs
@@ -5,13 +5,11 @@ namespace Allure.NUnit.Tests;
class ParameterTests
{
- public static IEnumerable> GetSingleParameterSamples()
+ public static IEnumerable> GetParameterSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.AddParameterFromSetUp,
- AllureSampleRegistry.AddParameterFromTest,
- AllureSampleRegistry.AddParameterFromTearDown,
- AllureSampleRegistry.OneNUnitTestCaseWithOneParameter,
+ AllureSampleRegistry.AddTestParameter,
+ AllureSampleRegistry.ParameterAttributesOnTestCaseParameters,
];
return samples.Select(static (sample) =>
@@ -19,64 +17,45 @@ public static IEnumerable> GetSingleParam
}
[Test]
- [MethodDataSource(nameof(GetSingleParameterSamples))]
- public async Task CheckParameterIsAdded(AllureSampleRegistryEntry sample)
+ [MethodDataSource(nameof(GetParameterSamples))]
+ public async Task AddTestParameterApiWorks(AllureSampleRegistryEntry sample)
{
var results = await AllureSampleRunner.RunAsync(sample);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var nodes = results.TestResults[0]["parameters"].AsArray().Cast();
- await Assert.That(nodes).ContainsOnly(
- p => (string)p["name"] == "foo" && (string)p["value"] == "\"bar\""
- );
- }
-
- [Test]
- public async Task CheckMaskedParameter()
- {
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.MaskedParameter);
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var parameters = results.TestResults[0]["parameters"].AsArray().Cast().ToList();
- var parameters = results.TestResults[0]["parameters"].AsArray().Cast();
- await Assert.That(parameters).HasSingleItem().And.All(
- static (p) => (string)p["mode"] == "masked"
+ await Assert.That(parameters.Count).IsEqualTo(5);
+ await Assert.That(parameters[0]).Satisfies(
+ static (p) => (string)p["name"] == "name1"
+ && (string)p["value"] == "\"value-1\""
+ && p["mode"] is null
+ && (bool)p["excluded"] is false
);
- }
-
- [Test]
- public async Task CheckHiddenParameter()
- {
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.HiddenParameter);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
-
- var parameters = results.TestResults[0]["parameters"].AsArray().Cast();
- await Assert.That(parameters).HasSingleItem().And.All(
- static (p) => (string)p["mode"] == "hidden"
+ await Assert.That(parameters[1]).Satisfies(
+ static (p) => (string)p["name"] == "name2"
+ && (string)p["value"] == "\"value-2\""
+ && (string)p["mode"] == "masked"
+ && (bool)p["excluded"] is false
);
- }
-
- [Test]
- public async Task CheckExcludedParameter()
- {
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.ExcludedParameter);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(2);
-
- var testResult1 = results.TestResults[0];
- var testResult2 = results.TestResults[1];
-
- var testResult1Parameters = testResult1["parameters"].AsArray().Cast();
- var testResult2Parameters = testResult2["parameters"].AsArray().Cast();
- await Assert.That(testResult1Parameters).Any(
- static (p) => (string)p["name"] == "timestamp" && (bool)p["excluded"] == true
+ await Assert.That(parameters[2]).Satisfies(
+ static (p) => (string)p["name"] == "name3"
+ && (string)p["value"] == "\"value-3\""
+ && (string)p["mode"] == "hidden"
+ && (bool)p["excluded"] is false
);
- await Assert.That(testResult2Parameters).Any(
- static (p) => (string)p["name"] == "timestamp" && (bool)p["excluded"] == true
+ await Assert.That(parameters[3]).Satisfies(
+ static (p) => (string)p["name"] == "name4"
+ && (string)p["value"] == "\"value-4\""
+ && p["mode"] is null
+ && (bool)p["excluded"] is true
+ );
+ await Assert.That(parameters[4]).Satisfies(
+ static (p) => (string)p["name"] == "name5"
+ && (string)p["value"] == "\"value-5\""
+ && (string)p["mode"] == "masked"
+ && (bool)p["excluded"] is true
);
-
- // It must not affect historyId
- await Assert.That((string)testResult1["historyId"]).IsEqualTo((string)testResult2["historyId"]);
}
}
\ No newline at end of file
diff --git a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
deleted file mode 100644
index 0463b822..00000000
--- a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class ParentSuiteTests
-{
- public static IEnumerable> GetParentSuiteSamples()
- {
- IEnumerable samples = [
- AllureSampleRegistry.ParentSuiteAttributeOnClass,
- AllureSampleRegistry.ParentSuiteAttributeOnMethod,
- AllureSampleRegistry.ParentSuiteAttributeOnBaseClass,
- AllureSampleRegistry.AddParentSuiteFromSetUp,
- AllureSampleRegistry.AddParentSuiteFromTest,
- AllureSampleRegistry.AddParentSuiteFromTearDown,
- ];
-
- return samples.Select(static (sample) =>
- new TestDataRow(sample, DisplayName: sample.Id));
- }
-
- [Test]
- [MethodDataSource(nameof(GetParentSuiteSamples))]
- public async Task CheckParentSuiteIsAdded(AllureSampleRegistryEntry sample)
- {
- var results = await AllureSampleRunner.RunAsync(sample);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var nodes = results.TestResults[0]["labels"].AsArray().Cast();
- await Assert.That(nodes).Any(
- l =>
- {
- return (string)l["name"] == "parentSuite" && (string)l["value"] == "foo";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
similarity index 66%
rename from tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs
rename to tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
index 059ee425..35676315 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.AddParameterFromSetUp
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromSetUp
{
[AllureNUnit]
public class TestsClass
@@ -9,11 +9,10 @@ public class TestsClass
[SetUp]
public void SetUp()
{
- AllureApi.AddTestParameter("foo", "bar");
+ AllureApi.SetDescription("Lorem Ipsum");
}
[Test]
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
similarity index 66%
rename from tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs
rename to tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
index 18cad2be..66c9ae10 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.AddParameterFromTearDown
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromTearDown
{
[AllureNUnit]
public class TestsClass
@@ -9,11 +9,10 @@ public class TestsClass
[TearDown]
public void TearDown()
{
- AllureApi.AddTestParameter("foo", "bar");
+ AllureApi.SetDescription("Lorem Ipsum");
}
[Test]
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
similarity index 61%
rename from tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs
rename to tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
index 6d8afcbf..1b7b79f9 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.AddParameterFromTest
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromTest
{
[AllureNUnit]
public class TestsClass
@@ -9,8 +9,7 @@ public class TestsClass
[Test]
public void TestMethod()
{
- AllureApi.AddTestParameter("foo", "bar");
+ AllureApi.SetDescription("Lorem Ipsum");
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromSetUp.cs
new file mode 100644
index 00000000..257dcac7
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionHtmlFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTearDown.cs
new file mode 100644
index 00000000..39aa2bf2
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionHtmlFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/HiddenParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
similarity index 55%
rename from tests/Allure.NUnit.Tests/Samples/HiddenParameter.cs
rename to tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
index d3bd1c20..37c4186a 100644
--- a/tests/Allure.NUnit.Tests/Samples/HiddenParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
@@ -1,8 +1,7 @@
-using System;
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.HiddenParameter
+namespace Allure.NUnit.Tests.Samples.AddDescriptionHtmlFromTest
{
[AllureNUnit]
public class TestsClass
@@ -10,8 +9,7 @@ public class TestsClass
[Test]
public void TestMethod()
{
- AllureApi.AddTestParameter("foo", "bar", ParameterMode.Hidden);
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddEpicFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddEpicFromSetUp.cs
index 8f7bb573..6f1042af 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddEpicFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddEpicFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddEpicFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddEpicFromTearDown.cs
index 15b1bba9..9eb7e0cd 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddEpicFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddEpicFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddEpicFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddEpicFromTest.cs
index b5c3cb26..12f23e8e 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddEpicFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddEpicFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromSetUp.cs
index bd21510a..d32a8e1d 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTearDown.cs
index e52238a7..0d0b9b2b 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTest.cs
index 70afd1d0..8d118440 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddFeatureFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddIssuesAtRuntime.cs b/tests/Allure.NUnit.Tests/Samples/AddIssuesAtRuntime.cs
new file mode 100644
index 00000000..9e0d9808
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddIssuesAtRuntime.cs
@@ -0,0 +1,27 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddIssuesAtRuntime
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.AddIssue("url-1");
+ }
+
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.AddIssue("name-2", "url-2");
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.AddIssue("name-3", "url-3");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddLabelFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddLabelFromSetUp.cs
index cad9e40a..1d19834c 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddLabelFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddLabelFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddLabelFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddLabelFromTearDown.cs
index 5011136b..7323ca7c 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddLabelFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddLabelFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddLabelFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddLabelFromTest.cs
index 7731b18d..9190af43 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddLabelFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddLabelFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddLinksAtRuntime.cs b/tests/Allure.NUnit.Tests/Samples/AddLinksAtRuntime.cs
new file mode 100644
index 00000000..a2fec3c5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddLinksAtRuntime.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddLinksAtRuntime
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.AddLink("url-1");
+ }
+
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.AddLink("name-2", "url-2");
+ AllureApi.AddLinks(
+ new Link(){ url = "url-3", name = "name-3", type = "type-3" }
+ );
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.AddLink("name-4", "type-4", "url-4");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromSetUp.cs
index a4a78a52..173a6f6e 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTearDown.cs
index f795e009..19013897 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTest.cs
index 7c43ed05..405b29cd 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddStoryFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddStoryFromSetUp.cs
index 7fb11d7e..0a347143 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddStoryFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddStoryFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddStoryFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddStoryFromTearDown.cs
index aa1645f9..66e9e94d 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddStoryFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddStoryFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddStoryFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddStoryFromTest.cs
index 00d18ebd..ae9a0b4e 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddStoryFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddStoryFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromSetUp.cs
index d0ba678e..e79e1a4a 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTearDown.cs
index 7c59280a..2c6de594 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTest.cs
index 9ac3af6d..b5700c68 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromSetUp.cs
index 5fdf62f9..97d28995 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTearDown.cs
index 4cd679f9..d9d8c309 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTest.cs
index ddd35d6f..67e21cf8 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddSuiteFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs b/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs
new file mode 100644
index 00000000..2a59d698
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs
@@ -0,0 +1,27 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddTagsApiCalls
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.AddTags("foo");
+ }
+
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.AddTags("bar", "baz");
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.AddTags("qux");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs
new file mode 100644
index 00000000..3f1c58f8
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs
@@ -0,0 +1,31 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddTestParameters
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.AddTestParameter("name1", "value-1");
+ }
+
+ [TestCase]
+ public void TestMethod(
+
+ )
+ {
+ AllureApi.AddTestParameter("name2", "value-2", ParameterMode.Masked);
+ AllureApi.AddTestParameter("name3", "value-3", ParameterMode.Hidden);
+ AllureApi.AddTestParameter("name4", "value-4", excluded: true);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.AddTestParameter("name5", "value-5", ParameterMode.Masked, true);
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddTmsItemsAtRuntime.cs b/tests/Allure.NUnit.Tests/Samples/AddTmsItemsAtRuntime.cs
new file mode 100644
index 00000000..2af1c66c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddTmsItemsAtRuntime.cs
@@ -0,0 +1,27 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddTmsItemsAtRuntime
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.AddTmsItem("url-1");
+ }
+
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.AddTmsItem("name-2", "url-2");
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.AddTmsItem("name-3", "url-3");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AllureIdAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/AllureIdAttributeOnMethod.cs
new file mode 100644
index 00000000..e3ca1772
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AllureIdAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AllureIdAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureId(1001)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
new file mode 100644
index 00000000..59450846
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.BddHierarchyAttributeOnBaseClass
+{
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnClass.cs
new file mode 100644
index 00000000..6c532285
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.BddHierarchyAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
new file mode 100644
index 00000000..013d6870
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.BddHierarchyAttributeOnInterface
+{
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
new file mode 100644
index 00000000..ec79e42b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.BddHierarchyAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnBaseClass.cs
new file mode 100644
index 00000000..5da9592c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionAttributeOnBaseClass
+{
+ [AllureDescription("Lorem Ipsum")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ public class TestsClass : TestClassBase
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnClass.cs
new file mode 100644
index 00000000..8908c344
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureDescription("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnInterface.cs
new file mode 100644
index 00000000..9acaf299
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionAttributeOnInterface
+{
+ [AllureDescription("Lorem Ipsum")]
+ public interface IMetadataInterface { }
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnMethod.cs
new file mode 100644
index 00000000..d67bacee
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureDescription("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnBaseClass.cs
new file mode 100644
index 00000000..e89d9f5f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionHtmlAttributeOnBaseClass
+{
+ [AllureDescriptionHtml("Lorem Ipsum")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ public class TestsClass : TestClassBase
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnClass.cs
new file mode 100644
index 00000000..e4345fb5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionHtmlAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureDescriptionHtml("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnInterface.cs
new file mode 100644
index 00000000..f0d4b521
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionHtmlAttributeOnInterface
+{
+ [AllureDescriptionHtml("Lorem Ipsum")]
+ public interface IMetadataInterface { }
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnMethod.cs
new file mode 100644
index 00000000..59b0c40f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.DescriptionHtmlAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureDescriptionHtml("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
index 3302b12b..540cc06a 100644
--- a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.EpicAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
index 6c45d1ca..8b57de13 100644
--- a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.EpicAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnInterface.cs
new file mode 100644
index 00000000..87e876d3
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.EpicAttributeOnInterface
+{
+ [AllureEpic("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
index a94c2cea..410232c5 100644
--- a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.EpicAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/ExcludedParameter.cs b/tests/Allure.NUnit.Tests/Samples/ExcludedParameter.cs
deleted file mode 100644
index bd9f2009..00000000
--- a/tests/Allure.NUnit.Tests/Samples/ExcludedParameter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using Allure.Net.Commons;
-using NUnit.Framework;
-
-namespace Allure.NUnit.Tests.Samples.ExcludedParameter
-{
- [AllureNUnit]
- public class TestsClass
- {
- [TestCase(0)]
- [TestCase(0)]
- public void TestMethod(int _)
- {
- AllureApi.AddTestParameter("timestamp", DateTime.Now, true);
- }
- }
-}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
index 58e0d1e6..61491b25 100644
--- a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
index d2607b69..0946e61a 100644
--- a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnInterface.cs
new file mode 100644
index 00000000..fd0332bc
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnInterface
+{
+ [AllureFeature("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
index b2dda642..eba7a297 100644
--- a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/FixtureAttributes.cs b/tests/Allure.NUnit.Tests/Samples/FixtureAttributes.cs
new file mode 100644
index 00000000..de630da5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/FixtureAttributes.cs
@@ -0,0 +1,29 @@
+using Allure.NUnit;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.FixtureAttributes
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [OneTimeSetUp]
+ [AllureBefore]
+ public static void OneTimeSetUp() { }
+
+ [SetUp]
+ [AllureBefore("Foo")]
+ public void SetUp() { }
+
+ [Test]
+ public void TestMethod() { }
+
+ [TearDown]
+ [AllureAfter]
+ public void TearDown() { }
+
+ [OneTimeTearDown]
+ [AllureAfter("Bar")]
+ public static void OneTimeTearDown() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/IssueAttributes.cs b/tests/Allure.NUnit.Tests/Samples/IssueAttributes.cs
new file mode 100644
index 00000000..84743618
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/IssueAttributes.cs
@@ -0,0 +1,20 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.IssueAttributes
+{
+ [AllureIssue("url-1")]
+ public interface IMetadata { }
+
+ [AllureIssue("url-2", Title = "name-2")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureIssue("url-3")]
+ public class TestsClass : TestClassBase, IMetadata
+ {
+ [Test]
+ [AllureIssue("url-4")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
index 3f10acd8..bd1a34aa 100644
--- a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.LabelAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
index 45772662..3cca54c6 100644
--- a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.LabelAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnInterface.cs
new file mode 100644
index 00000000..e78fe550
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LabelAttributeOnInterface
+{
+ [AllureLabel("foo", "bar")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
index 2c1b8643..4c0e7921 100644
--- a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.LabelAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
new file mode 100644
index 00000000..6b7378dc
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AllureIdAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureId(1001)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttribute.cs b/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttribute.cs
new file mode 100644
index 00000000..bf3b9faa
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttribute.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyDescriptionAttribute
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureDescription("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttributeHtml.cs b/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttributeHtml.cs
new file mode 100644
index 00000000..7921c6ec
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttributeHtml.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyDescriptionAttributeHtml
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureDescription("Lorem Ipsum", true)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
new file mode 100644
index 00000000..b804c315
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnBaseClass
+{
+ [AllureEpic("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
new file mode 100644
index 00000000..2992045f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureEpic("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
new file mode 100644
index 00000000..0db370e6
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureEpic("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
new file mode 100644
index 00000000..f3034efb
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnBaseClass
+{
+ [AllureFeature("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
new file mode 100644
index 00000000..c2c224e8
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureFeature("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
new file mode 100644
index 00000000..a1410735
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureFeature("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFixtureAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFixtureAttributes.cs
new file mode 100644
index 00000000..3a856415
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFixtureAttributes.cs
@@ -0,0 +1,29 @@
+using Allure.NUnit;
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyFixtureAttributes
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [OneTimeSetUp]
+ [AllureBefore]
+ public static void OneTimeSetUp() { }
+
+ [SetUp]
+ [AllureBefore("Foo")]
+ public void SetUp() { }
+
+ [Test]
+ public void TestMethod() { }
+
+ [TearDown]
+ [AllureAfter]
+ public void TearDown() { }
+
+ [OneTimeTearDown]
+ [AllureAfter("Bar")]
+ public static void OneTimeTearDown() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyIssueAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyIssueAttributes.cs
new file mode 100644
index 00000000..9bd5283b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyIssueAttributes.cs
@@ -0,0 +1,17 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyIssueAttributes
+{
+ [AllureIssue("url-1")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureIssue("name-2", "url-2")]
+ public class TestsClass : TestClassBase
+ {
+ [Test]
+ [AllureIssue("url-3")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
new file mode 100644
index 00000000..9cfe3847
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnBaseClass
+{
+ [AllureLabel("foo", "bar")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
new file mode 100644
index 00000000..80f6cc1a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureLabel("foo", "bar")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
new file mode 100644
index 00000000..869d676d
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureLabel("foo", "bar")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLinkAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLinkAttributes.cs
new file mode 100644
index 00000000..25ff9994
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLinkAttributes.cs
@@ -0,0 +1,17 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyLinkAttributes
+{
+ [AllureLink("url-1")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureLink("name-2", "url-2")]
+ public class TestsClass : TestClassBase
+ {
+ [Test]
+ [AllureLink("name-3", "url-3")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyNameAttribute.cs b/tests/Allure.NUnit.Tests/Samples/LegacyNameAttribute.cs
new file mode 100644
index 00000000..968db0ea
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyNameAttribute.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyNameAttribute
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureName("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnBaseClass.cs
new file mode 100644
index 00000000..44621708
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyOwnerAttributeOnBaseClass
+{
+ [AllureOwner("John Doe")]
+ public class BaseClass { }
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnClass.cs
new file mode 100644
index 00000000..3adb3798
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyOwnerAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureOwner("John Doe")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnMethod.cs
new file mode 100644
index 00000000..245a5a81
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyOwnerAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureOwner("John Doe")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..63220b7c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnBaseClass
+{
+ [AllureParentSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
new file mode 100644
index 00000000..e6c4fff8
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureParentSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
new file mode 100644
index 00000000..f8ed583b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureParentSuite("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs
new file mode 100644
index 00000000..f7a49c8b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs
@@ -0,0 +1,16 @@
+using Allure.Net.Commons;
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnBaseClass
+{
+ [AllureSeverity(SeverityLevel.critical)]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs
new file mode 100644
index 00000000..54539a31
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSeverity(SeverityLevel.critical)]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs
new file mode 100644
index 00000000..2bd4d740
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSeverity(SeverityLevel.critical)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStepAttributes.cs
new file mode 100644
index 00000000..190374cc
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStepAttributes.cs
@@ -0,0 +1,54 @@
+using System.Threading.Tasks;
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyStepAttributes
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public async Task TestMethod()
+ {
+ this.Void();
+ this.Return();
+ await this.Async();
+ await this.AsyncReturn();
+ this.Named();
+ this.Parameters(1, "baz");
+ this.SkippedParameter(2);
+ this.RenamedParameter(3);
+ }
+
+ [AllureStep]
+ void Void() { }
+
+ [AllureStep]
+ int Return() => 1;
+
+ [AllureStep]
+ async Task Async()
+ {
+ await Task.Delay(1);
+ }
+
+ [AllureStep]
+ async Task AsyncReturn()
+ {
+ await Task.Delay(1);
+ return 1;
+ }
+
+ [AllureStep("Renamed")]
+ void Named() { }
+
+ [AllureStep]
+ void Parameters(int foo, string bar) { }
+
+ [AllureStep]
+ void SkippedParameter([Skip] int foo) { }
+
+ [AllureStep]
+ void RenamedParameter([Name("Bar")] int foo) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
new file mode 100644
index 00000000..4970add5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnBaseClass
+{
+ [AllureStory("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
new file mode 100644
index 00000000..75ca271a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureStory("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
new file mode 100644
index 00000000..6306444e
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureStory("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..f153d7cd
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnBaseClass
+{
+ [AllureSubSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
new file mode 100644
index 00000000..ece7d2f5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSubSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
new file mode 100644
index 00000000..813fcf29
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSubSuite("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..66e28277
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnBaseClass
+{
+ [AllureSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
new file mode 100644
index 00000000..9c647f11
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
new file mode 100644
index 00000000..5ef649ad
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSuite("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs
new file mode 100644
index 00000000..5980cb1a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs
@@ -0,0 +1,17 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyTagAttributes
+{
+ [AllureTag("foo")]
+ public class BaseClass { }
+
+ [AllureNUnit]
+ [AllureTag("bar")]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ [AllureTag("baz", "qux")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyTmsAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyTmsAttributes.cs
new file mode 100644
index 00000000..1f9d0b7a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyTmsAttributes.cs
@@ -0,0 +1,17 @@
+using Allure.NUnit.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyTmsAttributes
+{
+ [AllureTms("url-1")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureTms("name-2", "url-2")]
+ public class TestsClass : TestClassBase
+ {
+ [Test]
+ [AllureTms("url-3")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
new file mode 100644
index 00000000..357fa521
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
@@ -0,0 +1,20 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LinkAttributes
+{
+ [AllureLink("url-1")]
+ public interface IMetadata { }
+
+ [AllureLink("url-2", Title = "name-2")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureLink("url-3", Type = "type-3")]
+ public class TestsClass : TestClassBase, IMetadata
+ {
+ [Test]
+ [AllureLink("url-4", Title = "name-4", Type = "type-4")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs b/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs
new file mode 100644
index 00000000..05e3fb78
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs
@@ -0,0 +1,43 @@
+using System;
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using Allure.NUnit;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.MetaAttributes
+{
+ [AllureEpic("Foo")]
+ [AllureOwner("John Doe")]
+ [AttributeUsage(AttributeTargets.Interface)]
+ public class EpicOwnerAttribute : AllureMetaAttribute { }
+
+ [AllureFeature("Bar")]
+ [AllureTag("foo", "bar")]
+ [AttributeUsage(AttributeTargets.Class)]
+ public class FeatureTagsAttribute : AllureMetaAttribute { }
+
+ [AllureStory("Baz")]
+ [AllureLink("https://foo.bar/")]
+ [AttributeUsage(AttributeTargets.Class)]
+ public class StoryLinkAttribute : AllureMetaAttribute { }
+
+ [AllureSeverity(SeverityLevel.critical)]
+ [AllureSuite("Qux")]
+ [AttributeUsage(AttributeTargets.Method)]
+ public class SeveritySuiteAttribute : AllureMetaAttribute { }
+
+ [EpicOwner]
+ public interface IMetadata { }
+
+ [FeatureTags]
+ public class BaseClass { }
+
+ [AllureNUnit]
+ [StoryLink]
+ public class TestsClass : BaseClass, IMetadata
+ {
+ [Test]
+ [SeveritySuite]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTest.cs b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTest.cs
new file mode 100644
index 00000000..a25ff47b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTest.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitAuthorPropertyOnTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test(Author = "John Doe")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestCase.cs b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestCase.cs
new file mode 100644
index 00000000..590599ab
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestCase.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitAuthorPropertyOnTestCase
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TestCase(1, Author = "John Doe")]
+ public void TestMethod(int _) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestFixture.cs b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestFixture.cs
new file mode 100644
index 00000000..15f2b21e
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestFixture.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitAuthorPropertyOnTestFixture
+{
+ [AllureNUnit]
+ [TestFixture(Author = "John Doe")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs b/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs
new file mode 100644
index 00000000..a43c62df
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs
@@ -0,0 +1,13 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitCategoryAttributes
+{
+ [AllureNUnit]
+ [Category("foo")]
+ public class TestsClass
+ {
+ [Test]
+ [Category("bar")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeComposition.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeComposition.cs
new file mode 100644
index 00000000..e7ec5091
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeComposition.cs
@@ -0,0 +1,13 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionAttributeComposition
+{
+ [AllureNUnit]
+ [Description("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ [Description("Dolor Sit Amet")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnClass.cs
new file mode 100644
index 00000000..9e377100
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionAttributeOnClass
+{
+ [AllureNUnit]
+ [Description("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnMethod.cs
new file mode 100644
index 00000000..4b0b4b28
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [Description("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
new file mode 100644
index 00000000..1eed5853
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
@@ -0,0 +1,13 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyComposition
+{
+ [AllureNUnit]
+ [TestFixture(Description = "Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test(Description = "Dolor Sit Amet")]
+ [TestCase(1, Description = "Consectetur Adipiscing Elit")]
+ public void TestMethod(int _) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs
new file mode 100644
index 00000000..90075057
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test(Description = "Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestCase.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestCase.cs
new file mode 100644
index 00000000..759ddaca
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestCase.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TestCase(1, Description = "Lorem Ipsum")]
+ public void TestMethod(int _) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs
new file mode 100644
index 00000000..e1b55932
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnTestFixture
+{
+ [AllureNUnit]
+ [TestFixture(Description = "Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescription.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescription.cs
new file mode 100644
index 00000000..b207a1ff
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescription.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyWithAllureDescription
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test(Description = "Dolor Sit Amet")]
+ public void TestMethod()
+ {
+ AllureApi.SetDescription("Lorem Ipsum");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescriptionHtml.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescriptionHtml.cs
new file mode 100644
index 00000000..d497ff7a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescriptionHtml.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyWithAllureDescriptionHtml
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test(Description = "Dolor Sit Amet")]
+ public void TestMethod()
+ {
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NameAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/NameAttributeOnClass.cs
new file mode 100644
index 00000000..a54ca103
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NameAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyNameAttribute
+{
+ [AllureNUnit]
+ [AllureName("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NameAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/NameAttributeOnMethod.cs
new file mode 100644
index 00000000..721eaf76
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NameAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyNameAttribute
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureName("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs b/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs
deleted file mode 100644
index cce4d34d..00000000
--- a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Allure.Net.Commons;
-using NUnit.Framework;
-
-namespace Allure.NUnit.Tests.Samples.OneNUnitTestCaseWithOneParameter
-{
- [AllureNUnit]
- public class TestsClass
- {
- [TestCase("bar")]
- public void TestMethod(string foo) { }
- }
-}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnBaseClass.cs
new file mode 100644
index 00000000..b9a78cad
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.OwnerAttributeOnBaseClass
+{
+ [AllureOwner("John Doe")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnClass.cs
new file mode 100644
index 00000000..246275cf
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.OwnerAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureOwner("John Doe")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnInterface.cs
new file mode 100644
index 00000000..2b26baf1
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.OwnerAttributeOnInterface
+{
+ [AllureOwner("John Doe")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnMethod.cs
new file mode 100644
index 00000000..c41a629f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.OwnerAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureOwner("John Doe")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs b/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs
new file mode 100644
index 00000000..fb90cd56
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs
@@ -0,0 +1,20 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.ParameterAttributesOnTestCase
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TestCase("value-1", "ignored", "value-2", "value-3", "value-4", "value-5")]
+ public void TestMethod(
+ string name1,
+ [AllureParameter(Ignore = true)] string ignored,
+ [AllureParameter(Name = "name2", Mode = ParameterMode.Masked)] string renamed1,
+ [AllureParameter(Mode = ParameterMode.Hidden)] string name3,
+ [AllureParameter(Excluded = true)] string name4,
+ [AllureParameter(Name = "name5", Mode = ParameterMode.Masked, Excluded = true)] string renamed2
+ ) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
index 43640adb..49beef32 100644
--- a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
index bcfc91a5..d5e27573 100644
--- a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnInterface.cs
new file mode 100644
index 00000000..b955f714
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnInterface
+{
+ [AllureParentSuite("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
index 5bd44328..1e14a28c 100644
--- a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromSetUp.cs
new file mode 100644
index 00000000..60434c63
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetAllureIdFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetAllureId(1001);
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTearDown.cs
new file mode 100644
index 00000000..49362f54
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetAllureIdFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetAllureId(1001);
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/MaskedParameter.cs b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
similarity index 55%
rename from tests/Allure.NUnit.Tests/Samples/MaskedParameter.cs
rename to tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
index d56b9ace..9f178798 100644
--- a/tests/Allure.NUnit.Tests/Samples/MaskedParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
@@ -1,8 +1,7 @@
-using System;
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.MaskedParameter
+namespace Allure.NUnit.Tests.Samples.SetAllureIdFromTest
{
[AllureNUnit]
public class TestsClass
@@ -10,8 +9,7 @@ public class TestsClass
[Test]
public void TestMethod()
{
- AllureApi.AddTestParameter("foo", "bar", ParameterMode.Masked);
+ AllureApi.SetAllureId(1001);
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SetOwnerFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromSetUp.cs
new file mode 100644
index 00000000..0d7ed245
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetOwnerFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetOwner("John Doe");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTearDown.cs
new file mode 100644
index 00000000..78be46bb
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetOwnerFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetOwner("John Doe");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
similarity index 52%
rename from tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
rename to tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
index 256d56a5..ca209d4f 100644
--- a/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
@@ -1,8 +1,7 @@
using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.DefaultStepAttributes
+namespace Allure.NUnit.Tests.Samples.SetOwnerFromTest
{
[AllureNUnit]
public class TestsClass
@@ -10,11 +9,7 @@ public class TestsClass
[Test]
public void TestMethod()
{
- this.Foo();
+ AllureApi.SetOwner("John Doe");
}
-
- [AllureStep]
- void Foo() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs
new file mode 100644
index 00000000..46583b4c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetSeverityFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetSeverity(SeverityLevel.critical);
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs
new file mode 100644
index 00000000..267248b6
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetSeverityFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetSeverity(SeverityLevel.critical);
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs
new file mode 100644
index 00000000..a3d52293
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetSeverityFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.SetSeverity(SeverityLevel.critical);
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetTestNameFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromSetUp.cs
new file mode 100644
index 00000000..2043dd81
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetTestNameFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetTestName("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTearDown.cs
new file mode 100644
index 00000000..1868df04
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetTestNameFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetTestName("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTest.cs b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTest.cs
new file mode 100644
index 00000000..e567444d
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetTestNameFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetTestNameFromTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.SetTestName("Lorem Ipsum");
+ }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs
new file mode 100644
index 00000000..aed6b53b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs
@@ -0,0 +1,16 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnBaseClass
+{
+ [AllureSeverity(SeverityLevel.critical)]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs
new file mode 100644
index 00000000..3115211e
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSeverity(SeverityLevel.critical)]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs
new file mode 100644
index 00000000..4907d5e6
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs
@@ -0,0 +1,16 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnInterface
+{
+ [AllureSeverity(SeverityLevel.critical)]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs
new file mode 100644
index 00000000..ad7266e5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSeverity(SeverityLevel.critical)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SingleTescCase.cs b/tests/Allure.NUnit.Tests/Samples/SingleTescCase.cs
new file mode 100644
index 00000000..b8ed3824
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SingleTescCase.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LegacyNameAttribute
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TestCase(1)]
+ public void TestMethod(int _) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs
new file mode 100644
index 00000000..d333a53a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs
@@ -0,0 +1,53 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.StepAttributes
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public async Task TestMethod()
+ {
+ this.Void();
+ this.Return();
+ await this.Async();
+ await this.AsyncReturn();
+ this.Named();
+ this.Parameters(1, 2, 3, 4, 5);
+ }
+
+ [AllureStep]
+ void Void() { }
+
+ [AllureStep]
+ int Return() => 1;
+
+ [AllureStep]
+ async Task Async()
+ {
+ await Task.Delay(1);
+ }
+
+ [AllureStep]
+ async Task AsyncReturn()
+ {
+ await Task.Delay(1);
+ return 1;
+ }
+
+ [AllureStep("Renamed")]
+ void Named() { }
+
+ [AllureStep]
+ void Parameters(
+ int plain,
+ [AllureParameter(Ignore = true)] int ignored,
+ [AllureParameter(Name = "Bar")] int renamed,
+ [AllureParameter(Mode = ParameterMode.Masked)] int masked,
+ [AllureParameter(Mode = ParameterMode.Hidden)] int hidden
+ ) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
index b2d8459d..5068c3f0 100644
--- a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.StoryAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
index bf93a665..723f5298 100644
--- a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.StoryAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnInterface.cs
new file mode 100644
index 00000000..52896560
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.StoryAttributeOnInterface
+{
+ [AllureStory("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
index f726c050..97dd43d3 100644
--- a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.StoryAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
index 9699167c..08063af8 100644
--- a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
index 8a81d6ce..967f0873 100644
--- a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnInterface.cs
new file mode 100644
index 00000000..0feaaaba
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnInterface
+{
+ [AllureSubSuite("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
index f84c61ef..2a31c4be 100644
--- a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
index a515f59d..5200555f 100644
--- a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnBaseClass
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
index 356d3ab6..34e44e85 100644
--- a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnInterface.cs
new file mode 100644
index 00000000..00da3ee8
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnInterface
+{
+ [AllureSuite("foo")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
index 8eddbb5b..ce463b8c 100644
--- a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
@@ -1,5 +1,4 @@
-using Allure.Net.Commons;
-using Allure.NUnit.Attributes;
+using Allure.Net.Commons.Attributes;
using NUnit.Framework;
namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnMethod
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnBaseClass.cs
new file mode 100644
index 00000000..bfa9f0ce
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteHierarchyAttributeOnBaseClass
+{
+ [AllureSuiteHierarchy("foo", "bar", "baz")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnClass.cs
new file mode 100644
index 00000000..5cbf199d
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteHierarchyAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSuiteHierarchy("foo", "bar", "baz")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnInterface.cs
new file mode 100644
index 00000000..4cf2551f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnInterface.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteHierarchyAttributeOnInterface
+{
+ [AllureSuiteHierarchy("foo", "bar", "baz")]
+ public interface IMetadataInterface {}
+
+ [AllureNUnit]
+ public class TestsClass : IMetadataInterface
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnMethod.cs
new file mode 100644
index 00000000..4f333880
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteHierarchyAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSuiteHierarchy("foo", "bar", "baz")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs b/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs
new file mode 100644
index 00000000..95b94531
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs
@@ -0,0 +1,20 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.TagAttributes
+{
+ [AllureTag("foo")]
+ public interface IMetadata { }
+
+ [AllureTag("bar")]
+ public class BaseClass { }
+
+ [AllureNUnit]
+ [AllureTag("baz")]
+ public class TestsClass : BaseClass, IMetadata
+ {
+ [Test]
+ [AllureTag("qux", "qut")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/TmsItemAttributes.cs b/tests/Allure.NUnit.Tests/Samples/TmsItemAttributes.cs
new file mode 100644
index 00000000..ad36dc6a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/TmsItemAttributes.cs
@@ -0,0 +1,20 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.TmsItemAttributes
+{
+ [AllureTmsItem("url-1")]
+ public interface IMetadata { }
+
+ [AllureTmsItem("url-2", Title = "name-2")]
+ public class TestClassBase { }
+
+ [AllureNUnit]
+ [AllureTmsItem("url-3")]
+ public class TestsClass : TestClassBase, IMetadata
+ {
+ [Test]
+ [AllureTmsItem("url-4")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/SeverityTests.cs b/tests/Allure.NUnit.Tests/SeverityTests.cs
new file mode 100644
index 00000000..4e78fb3b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/SeverityTests.cs
@@ -0,0 +1,42 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class SeverityTests
+{
+ public static IEnumerable> GetSeveritySamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SetSeverityFromSetUp,
+ AllureSampleRegistry.SetSeverityFromTest,
+ AllureSampleRegistry.SetSeverityFromTearDown,
+ AllureSampleRegistry.SeverityAttributeOnClass,
+ AllureSampleRegistry.SeverityAttributeOnMethod,
+ AllureSampleRegistry.SeverityAttributeOnBaseClass,
+ AllureSampleRegistry.SeverityAttributeOnInterface,
+ AllureSampleRegistry.LegacySeverityAttributeOnClass,
+ AllureSampleRegistry.LegacySeverityAttributeOnMethod,
+ AllureSampleRegistry.LegacySeverityAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetSeveritySamples))]
+ public async Task CheckSuiteLabelsAreAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var labels = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(labels).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "severity" && (string)l["value"] == "critical";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/StepTests.cs b/tests/Allure.NUnit.Tests/StepTests.cs
index 2f5d1b22..9fd38a3c 100644
--- a/tests/Allure.NUnit.Tests/StepTests.cs
+++ b/tests/Allure.NUnit.Tests/StepTests.cs
@@ -5,22 +5,118 @@ namespace Allure.NUnit.Tests;
class StepTests
{
+ internal record class ParameterExpectations(string Name, string Value, string Mode = null)
+ {
+ public bool Check(JsonObject parameter)
+ => (string)parameter["name"] == this.Name
+ && (string)parameter["value"] == this.Value
+ && (this.Mode is null || (string)parameter["mode"] == this.Mode);
+ public static bool CheckAll(
+ List expectations,
+ JsonArray parameters
+ )
+ => parameters.Count == expectations.Count
+ && parameters
+ .Zip(expectations)
+ .All(static (p) => p.Second.Check(p.First.AsObject()));
+ }
+
+ internal record class StepExpectations(
+ string Name,
+ string Status,
+ List Parameters,
+ List Substeps
+ )
+ {
+ public bool Check(JsonObject step)
+ => (string)step["name"] == this.Name
+ && (string)step["status"] == this.Status
+ && (string)step["stage"] == "finished"
+ && step["parameters"].AsArray().Count == this.Parameters.Count
+ && ParameterExpectations.CheckAll(this.Parameters, step["parameters"].AsArray())
+ && step["steps"]
+ .AsArray()
+ .Select(static (n) => n.AsObject())
+ .All(this.Check);
+
+ public static bool CheckAll(
+ List expectations,
+ JsonArray steps
+ )
+ => steps.Count == expectations.Count
+ && steps
+ .Zip(expectations)
+ .All(static (p) => p.Second.Check(p.First.AsObject()));
+ }
+
[Test]
- public async Task CheckStepsFromAnnotatedMethodCalls()
+ public async Task StepAttributeWorks()
{
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.DefaultStepAttributes);
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.StepAttributes);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
var steps = results.TestResults[0]["steps"].AsArray().Cast().ToArray();
- await Assert.That(steps).Count().IsEqualTo(1);
+ await Assert.That(steps).Count().IsEqualTo(6);
- var step1 = steps[0];
- await Assert.That(step1).Satisfies(
- static (step) => (string)step["name"] == "Foo"
- && (string)step["status"] == "passed"
- && (string)step["stage"] == "finished"
- && step["steps"].AsArray().Count == 0
- && step["parameters"].AsArray().Count == 0
- );
+ await Assert.That(steps[0]).Satisfies(static (step) =>
+ new StepExpectations("Void", "passed", [], []).Check(step));
+
+ await Assert.That(steps[1]).Satisfies(static (step) =>
+ new StepExpectations("Return", "passed", [], []).Check(step));
+
+ await Assert.That(steps[2]).Satisfies(static (step) =>
+ new StepExpectations("Async", "passed", [], []).Check(step));
+
+ await Assert.That(steps[3]).Satisfies(static (step) =>
+ new StepExpectations("AsyncReturn", "passed", [], []).Check(step));
+
+ await Assert.That(steps[4]).Satisfies(static (step) =>
+ new StepExpectations("Renamed", "passed", [], []).Check(step));
+
+ await Assert.That(steps[5]).Satisfies(static (step) =>
+ new StepExpectations("Parameters", "passed", [
+ new("plain", "1"),
+ new("Bar", "3"),
+ new("masked", "4", "masked"),
+ new("hidden", "5", "hidden"),
+ ], []).Check(step));
+ }
+
+ [Test]
+ public async Task LegacyStepAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyStepAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var steps = results.TestResults[0]["steps"].AsArray().Cast().ToArray();
+ await Assert.That(steps).Count().IsEqualTo(8);
+
+ await Assert.That(steps[0]).Satisfies(static (step) =>
+ new StepExpectations("Void", "passed", [], []).Check(step));
+
+ await Assert.That(steps[1]).Satisfies(static (step) =>
+ new StepExpectations("Return", "passed", [], []).Check(step));
+
+ await Assert.That(steps[2]).Satisfies(static (step) =>
+ new StepExpectations("Async", "passed", [], []).Check(step));
+
+ await Assert.That(steps[3]).Satisfies(static (step) =>
+ new StepExpectations("AsyncReturn", "passed", [], []).Check(step));
+
+ await Assert.That(steps[4]).Satisfies(static (step) =>
+ new StepExpectations("Renamed", "passed", [], []).Check(step));
+
+ await Assert.That(steps[5]).Satisfies(static (step) =>
+ new StepExpectations(
+ "Parameters",
+ "passed",
+ [new("foo", "1"), new("bar", "\"baz\"")],
+ []).Check(step));
+
+ await Assert.That(steps[6]).Satisfies(static (step) =>
+ new StepExpectations("SkippedParameter", "passed", [], []).Check(step));
+
+ await Assert.That(steps[7]).Satisfies(static (step) =>
+ new StepExpectations("RenamedParameter", "passed", [new("Bar", "3")], []).Check(step));
}
}
diff --git a/tests/Allure.NUnit.Tests/StoryTests.cs b/tests/Allure.NUnit.Tests/StoryTests.cs
deleted file mode 100644
index 0898b5bd..00000000
--- a/tests/Allure.NUnit.Tests/StoryTests.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class StoryTests
-{
- public static IEnumerable> GetStorySamples()
- {
- IEnumerable samples = [
- AllureSampleRegistry.StoryAttributeOnClass,
- AllureSampleRegistry.StoryAttributeOnMethod,
- AllureSampleRegistry.StoryAttributeOnBaseClass,
- AllureSampleRegistry.AddStoryFromSetUp,
- AllureSampleRegistry.AddStoryFromTest,
- AllureSampleRegistry.AddStoryFromTearDown,
- ];
-
- return samples.Select(static (sample) =>
- new TestDataRow(sample, DisplayName: sample.Id));
- }
-
- [Test]
- [MethodDataSource(nameof(GetStorySamples))]
- public async Task CheckStoryIsAdded(AllureSampleRegistryEntry sample)
- {
- var results = await AllureSampleRunner.RunAsync(sample);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var nodes = results.TestResults[0]["labels"].AsArray().Cast();
- await Assert.That(nodes).Any(
- l =>
- {
- return (string)l["name"] == "story" && (string)l["value"] == "foo";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/SubSuiteTests.cs b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
deleted file mode 100644
index 78cbd896..00000000
--- a/tests/Allure.NUnit.Tests/SubSuiteTests.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class SubSuiteTests
-{
- public static IEnumerable> GetSubSuiteSamples()
- {
- IEnumerable samples = [
- AllureSampleRegistry.SubSuiteAttributeOnClass,
- AllureSampleRegistry.SubSuiteAttributeOnMethod,
- AllureSampleRegistry.SubSuiteAttributeOnBaseClass,
- AllureSampleRegistry.AddSubSuiteFromSetUp,
- AllureSampleRegistry.AddSubSuiteFromTest,
- AllureSampleRegistry.AddSubSuiteFromTearDown,
- ];
-
- return samples.Select(static (sample) =>
- new TestDataRow(sample, DisplayName: sample.Id));
- }
-
- [Test]
- [MethodDataSource(nameof(GetSubSuiteSamples))]
- public async Task CheckSubSuiteIsAdded(AllureSampleRegistryEntry sample)
- {
- var results = await AllureSampleRunner.RunAsync(sample);
-
- await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var nodes = results.TestResults[0]["labels"].AsArray().Cast();
- await Assert.That(nodes).Any(
- l =>
- {
- return (string)l["name"] == "subSuite" && (string)l["value"] == "foo";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/SuiteLabelTests.cs b/tests/Allure.NUnit.Tests/SuiteLabelTests.cs
new file mode 100644
index 00000000..1a381bdc
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/SuiteLabelTests.cs
@@ -0,0 +1,151 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class SuiteLabelTests
+{
+ public static IEnumerable> GetSuiteHierarchySamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SuiteHierarchyAttributeOnClass,
+ AllureSampleRegistry.SuiteHierarchyAttributeOnMethod,
+ AllureSampleRegistry.SuiteHierarchyAttributeOnBaseClass,
+ AllureSampleRegistry.SuiteHierarchyAttributeOnInterface,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetSuiteHierarchySamples))]
+ public async Task CheckSuiteLabelsAreAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "parentSuite" && (string)l["value"] == "foo";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "suite" && (string)l["value"] == "bar";
+ }
+ ).And.Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "subSuite" && (string)l["value"] == "baz";
+ }
+ );
+ }
+
+ public static IEnumerable> GetParentSuiteSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.ParentSuiteAttributeOnClass,
+ AllureSampleRegistry.ParentSuiteAttributeOnMethod,
+ AllureSampleRegistry.ParentSuiteAttributeOnBaseClass,
+ AllureSampleRegistry.ParentSuiteAttributeOnInterface,
+ AllureSampleRegistry.AddParentSuiteFromSetUp,
+ AllureSampleRegistry.AddParentSuiteFromTest,
+ AllureSampleRegistry.AddParentSuiteFromTearDown,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnClass,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetParentSuiteSamples))]
+ public async Task CheckParentSuiteIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "parentSuite" && (string)l["value"] == "foo";
+ }
+ );
+ }
+
+ public static IEnumerable> GetSuiteSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SuiteAttributeOnClass,
+ AllureSampleRegistry.SuiteAttributeOnMethod,
+ AllureSampleRegistry.SuiteAttributeOnBaseClass,
+ AllureSampleRegistry.SuiteAttributeOnInterface,
+ AllureSampleRegistry.AddSuiteFromSetUp,
+ AllureSampleRegistry.AddSuiteFromTest,
+ AllureSampleRegistry.AddSuiteFromTearDown,
+ AllureSampleRegistry.LegacySuiteAttributeOnClass,
+ AllureSampleRegistry.LegacySuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacySuiteAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetSuiteSamples))]
+ public async Task CheckSuiteIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "suite" && (string)l["value"] == "foo";
+ }
+ );
+ }
+
+ public static IEnumerable> GetSubSuiteSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SubSuiteAttributeOnClass,
+ AllureSampleRegistry.SubSuiteAttributeOnMethod,
+ AllureSampleRegistry.SubSuiteAttributeOnBaseClass,
+ AllureSampleRegistry.SubSuiteAttributeOnInterface,
+ AllureSampleRegistry.AddSubSuiteFromSetUp,
+ AllureSampleRegistry.AddSubSuiteFromTest,
+ AllureSampleRegistry.AddSubSuiteFromTearDown,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnClass,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnBaseClass,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetSubSuiteSamples))]
+ public async Task CheckSubSuiteIsAdded(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var nodes = results.TestResults[0]["labels"].AsArray().Cast();
+ await Assert.That(nodes).Any(
+ l =>
+ {
+ return (string)l["name"] == "subSuite" && (string)l["value"] == "foo";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/TagTests.cs b/tests/Allure.NUnit.Tests/TagTests.cs
new file mode 100644
index 00000000..274cc54b
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/TagTests.cs
@@ -0,0 +1,77 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class TagTests
+{
+ [Test]
+ public async Task AddTagsApiWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddTagsApiCalls);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var tags = results.TestResults[0]["labels"]
+ .AsArray()
+ .Cast()
+ .Where(static (l) => (string)l["name"] == "tag")
+ .Select(static (l) => (string)l["value"])
+ .ToArray();
+ await Assert.That(tags).IsEquivalentTo(
+ ["foo", "bar", "baz", "qux"],
+ TUnit.Assertions.Enums.CollectionOrdering.Matching
+ );
+ }
+
+ [Test]
+ public async Task TagAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.TagAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var tags = results.TestResults[0]["labels"]
+ .AsArray()
+ .Cast()
+ .Where(static (l) => (string)l["name"] == "tag")
+ .Select(static (l) => (string)l["value"]);
+ await Assert.That(tags).IsEquivalentTo(
+ ["foo", "bar", "baz", "qux", "qut"],
+ TUnit.Assertions.Enums.CollectionOrdering.Matching
+ );
+ }
+
+ [Test]
+ public async Task LegacyTagAttributeWorks()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyTagAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var tags = results.TestResults[0]["labels"]
+ .AsArray()
+ .Cast()
+ .Where(static (l) => (string)l["name"] == "tag")
+ .Select(static (l) => (string)l["value"]);
+ await Assert.That(tags).IsEquivalentTo(
+ ["baz", "qux", "bar", "foo"],
+ TUnit.Assertions.Enums.CollectionOrdering.Matching
+ );
+ }
+
+ [Test]
+ public async Task NUnitCategoriesAreConvertedToTags()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.NUnitCategoryAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var tags = results.TestResults[0]["labels"]
+ .AsArray()
+ .Cast()
+ .Where(static (l) => (string)l["name"] == "tag")
+ .Select(static (l) => (string)l["value"]);
+ Console.WriteLine(string.Join(", ", tags));
+ await Assert.That(tags).IsEquivalentTo(
+ ["foo", "bar"],
+ TUnit.Assertions.Enums.CollectionOrdering.Matching
+ );
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
index c8522a6c..4ecb326c 100644
--- a/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
+++ b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
@@ -168,6 +168,33 @@ await Task.Factory.StartNew(() =>
Assert.That(modifiedContext.HasTest, Is.False);
}
+ [Test]
+ public async Task AsyncContextCapturingTest()
+ {
+ var writer = new InMemoryResultsWriter();
+ var lifecycle = new AllureLifecycle(_ => writer);
+ AllureContext context = null;
+ await Task.Factory.StartNew(() =>
+ {
+ lifecycle.StartTestCase(new()
+ {
+ uuid = Guid.NewGuid().ToString(),
+ fullName = "test"
+ });
+ context = lifecycle.Context;
+ });
+
+ await lifecycle.RunInContextAsync(context, async () =>
+ {
+ lifecycle.StopTestCase();
+ await Task.Yield();
+ lifecycle.WriteTestCase();
+ });
+
+ Assert.That(writer.testResults, Is.Not.Empty);
+ Assert.That(lifecycle.Context.HasTest, Is.False);
+ }
+
[Test]
public async Task ContextCapturingHasNoEffectIfContextIsNull()
{
@@ -188,6 +215,27 @@ await Task.Factory.StartNew(() =>
}), Throws.InvalidOperationException);
}
+ [Test]
+ public async Task AsyncContextCapturingHasNoEffectIfContextIsNull()
+ {
+ var writer = new InMemoryResultsWriter();
+ var lifecycle = new AllureLifecycle(_ => writer);
+ await Task.Factory.StartNew(() =>
+ {
+ lifecycle.StartTestCase(new()
+ {
+ uuid = Guid.NewGuid().ToString(),
+ fullName = "test"
+ });
+ });
+
+ Assert.That(async () => await lifecycle.RunInContextAsync(null, async () =>
+ {
+ await Task.Delay(1);
+ lifecycle.StopTestCase();
+ }), Throws.InvalidOperationException);
+ }
+
[Test]
public void HistoryAndTestCaseIdsAreSetAfterStop()
{
diff --git a/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs b/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs
index bf3ec54f..4fa7ddfe 100644
--- a/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs
+++ b/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs
@@ -29,8 +29,8 @@ public void ParallelTestsAreIsolated()
() => this.AddTestWithSteps("test-2", "step-2-1", "step-2-2")
);
- this.AssertTestWithSteps("test-1", "step-1-1", "step-1-2");
- this.AssertTestWithSteps("test-2", "step-2-1", "step-2-2");
+ this.AssertTestWithSteps("test-1", false, "step-1-1", "step-1-2");
+ this.AssertTestWithSteps("test-2", false, "step-2-1", "step-2-2");
}
[Test]
@@ -42,9 +42,9 @@ await Task.WhenAll(
this.AddTestWithStepsAsync("test-3", "step-3-1", "step-3-2")
);
- this.AssertTestWithSteps("test-1", "step-1-1", "step-1-2");
- this.AssertTestWithSteps("test-2", "step-2-1", "step-2-2");
- this.AssertTestWithSteps("test-3", "step-3-1", "step-3-2");
+ this.AssertTestWithSteps("test-1", false, "step-1-1", "step-1-2");
+ this.AssertTestWithSteps("test-2", false, "step-2-1", "step-2-2");
+ this.AssertTestWithSteps("test-3", false, "step-3-1", "step-3-2");
}
[Test]
@@ -55,7 +55,7 @@ public void ParallelStepsOfTestAreIsolated()
() => this.AddStep("step-2")
));
- this.AssertTestWithSteps("test-1", "step-1", "step-2");
+ this.AssertTestWithSteps("test-1", true, "step-1", "step-2");
}
[Test]
@@ -67,7 +67,7 @@ await this.WrapInTestAsync("test-1", async () => await Task.WhenAll(
this.AddStepsAsync("step-3")
));
- this.AssertTestWithSteps("test-1", "step-1", "step-2", "step-3");
+ this.AssertTestWithSteps("test-1", true, "step-1", "step-2", "step-3");
}
[Test]
@@ -104,10 +104,11 @@ public void ContextCapturedBySubThreads()
this.AssertTestWithSteps(
"test",
- ("outer", new object[]
+ false,
+ ("outer", true, new object[]
{
- ("inner-1", new object[] { "inner-1-1", "inner-1-2" }),
- ("inner-2", new object[] { "inner-2-1", "inner-2-2" })
+ ("inner-1", false, new object[] { "inner-1-1", "inner-1-2" }),
+ ("inner-2", false, new object[] { "inner-2-1", "inner-2-2" })
})
);
}
@@ -142,10 +143,11 @@ await this.WrapInTestAsync(
this.AssertTestWithSteps(
"test",
- ("outer", new object[]
+ false,
+ ("outer", true, new object[]
{
- ("inner-1", new object[] { "inner-1-1", "inner-1-2" }),
- ("inner-2", new object[] { "inner-2-1", "inner-2-2" })
+ ("inner-1", false, new object[] { "inner-1-1", "inner-1-2" }),
+ ("inner-2", false, new object[] { "inner-2-1", "inner-2-2" })
})
);
}
@@ -294,31 +296,37 @@ async Task AddStepWithSubstepsAsync(string name, params object[] substeps)
this.lifecycle.StopStep();
}
- void AssertTestWithSteps(string testName, params object[] steps)
+ void AssertTestWithSteps(string testName, bool anyOrder, params object[] steps)
{
Assert.That(
this.writer.testResults.Select(tr => tr.name),
Contains.Item(testName)
);
var test = this.writer.testResults.Single(tr => tr.name == testName);
- this.AssertSteps(test.steps, steps);
+ this.AssertSteps(test.steps, anyOrder, steps);
}
- void AssertSteps(List actualSteps, params object[] steps)
+ void AssertSteps(List actualSteps, bool anyOrder, params object[] steps)
{
+ if (anyOrder)
+ {
+ actualSteps = actualSteps.OrderBy(static (sr) => sr.name).ToList();
+ }
+
var expectedCount = steps.Length;
Assert.That(actualSteps.Count, Is.EqualTo(expectedCount));
for (var i = 0; i < expectedCount; i++)
{
var actualStep = actualSteps[i];
var step = steps.ElementAt(i);
- if (!(step is (string expectedStepName, object[] substeps)))
+ if (!(step is (string expectedStepName, bool subStepsInAnyOrder, object[] substeps)))
{
expectedStepName = (string)step;
- substeps = Array.Empty();
+ substeps = [];
+ subStepsInAnyOrder = false;
}
Assert.That(actualStep.name, Is.EqualTo(expectedStepName));
- this.AssertSteps(actualStep.steps, substeps);
+ this.AssertSteps(actualStep.steps, subStepsInAnyOrder, substeps);
}
}
diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersExplicitTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersExplicitTests.cs
new file mode 100644
index 00000000..2fbd916e
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersExplicitTests.cs
@@ -0,0 +1,252 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests.CreateParametersTests.cs;
+
+class CreateParametersExplicitTests
+{
+ static readonly Dictionary emptyFormatters = [];
+
+ [Test]
+ public void EmptyNameSeqGivesEmptySeq()
+ {
+ var parameters = ModelFunctions.CreateParameters([], [new()], ["foo"], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void EmptyAttrSeqGivesEmptySeq()
+ {
+ var parameters = ModelFunctions.CreateParameters(["p1"], [], ["foo"], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void EmptyValueSeqGivesEmptySeq()
+ {
+ var parameters = ModelFunctions.CreateParameters(["p1"], [new()], [], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void NoAttribute()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["noAttribute"], [null], ["foo"], emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "noAttribute", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void EmptyAttribute()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["noEffect"],
+ [new()],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "noEffect", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void Ignored()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["ignored"],
+ [new(){ Ignore = true }],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void RenamedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["original"],
+ [new(){ Name = "New name" }],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "New name", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void MaskedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["masked"],
+ [new(){ Mode = ParameterMode.Masked }],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "masked",
+ value = "\"foo\"",
+ mode = ParameterMode.Masked
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void HiddenParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["hidden"],
+ [new(){ Mode = ParameterMode.Hidden }],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "hidden",
+ value = "\"foo\"",
+ mode = ParameterMode.Hidden
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ExcludedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["excluded"],
+ [new(){ Excluded = true }],
+ ["foo"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "excluded",
+ value = "\"foo\"",
+ excluded = true
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ class StringFormatterStub : TypeFormatter
+ {
+ public override string Format(string value) => "bar";
+ }
+
+ [Test]
+ public void FormatterUsedIfMatched()
+ {
+ var formatters = new Dictionary
+ {
+ { typeof(string), new StringFormatterStub() },
+ };
+
+ var parameters = ModelFunctions.CreateParameters(["foo"], [null], ["bar"], formatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter { name = "foo", value = "bar" }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ class StringFormatterDummy : TypeFormatter
+ {
+ public override string Format(string value) => throw new NotImplementedException();
+ }
+
+ [Test]
+ public void FormattingSkippedForIgnoredParameter()
+ {
+ var formatters = new Dictionary
+ {
+ { typeof(string), new StringFormatterDummy() },
+ };
+
+ var parameters = ModelFunctions.CreateParameters(
+ ["foo"],
+ [new(){ Ignore = true }],
+ ["bar"],
+ formatters
+ );
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void MultipleParameters()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ ["noAttribute", "ignored", "masked", "excluded"],
+ [
+ null,
+ new(){ Ignore = true },
+ new(){ Mode = ParameterMode.Masked },
+ new(){ Excluded = true },
+ ],
+ ["foo", "bar", "baz", "qux"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "noAttribute",
+ value = "\"foo\"",
+ },
+ new Parameter
+ {
+ name = "masked",
+ value = "\"baz\"",
+ mode = ParameterMode.Masked,
+ },
+ new Parameter
+ {
+ name = "excluded",
+ value = "\"qux\"",
+ excluded = true,
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs
new file mode 100644
index 00000000..435839e0
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs
@@ -0,0 +1,237 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests.CreateParametersTests.cs;
+
+class CreateParametersReflectionTests
+{
+ static CreateParametersReflectionTests()
+ {
+ var parameters
+ = typeof(CreateParametersReflectionTests)
+ .GetMethod(nameof(Target)).GetParameters();
+
+ NoAttribute = parameters[0];
+ NoEffect = parameters[1];
+ Ignored = parameters[2];
+ Renamed = parameters[3];
+ Masked = parameters[4];
+ Hidden = parameters[5];
+ Excluded = parameters[6];
+ }
+
+ public static void Target(
+ int noAttribute,
+ [AllureParameter] int noEffect,
+ [AllureParameter(Ignore = true)] int ignored,
+ [AllureParameter(Name = "New name")] int renamed,
+ [AllureParameter(Mode = ParameterMode.Masked)] int masked,
+ [AllureParameter(Mode = ParameterMode.Hidden)] int hidden,
+ [AllureParameter(Excluded = true)] int excluded
+ ) { }
+
+ static ParameterInfo NoAttribute;
+ static ParameterInfo NoEffect;
+ static ParameterInfo Ignored;
+ static ParameterInfo Renamed;
+ static ParameterInfo Masked;
+ static ParameterInfo Hidden;
+ static ParameterInfo Excluded;
+ static readonly Dictionary emptyFormatters = [];
+
+ [Test]
+ public void EmptyParameterInfoSeqGivesEmptySeq()
+ {
+ var parameters = ModelFunctions.CreateParameters([], ["foo"], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void EmptyValueSeqGivesEmptySeq()
+ {
+ var parameters = ModelFunctions.CreateParameters([], ["foo"], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void PlainParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([NoAttribute], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "noAttribute", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ParameterWithEmptyAttribute()
+ {
+ var parameters = ModelFunctions.CreateParameters([NoEffect], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "noEffect", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void IgnoredParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([Ignored], ["foo"], emptyFormatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void RenamedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([Renamed], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([new Parameter { name = "New name", value = "\"foo\"" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void MaskedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([Masked], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "masked",
+ value = "\"foo\"",
+ mode = ParameterMode.Masked
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void HiddenParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([Hidden], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "hidden",
+ value = "\"foo\"",
+ mode = ParameterMode.Hidden
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ExcludedParameter()
+ {
+ var parameters = ModelFunctions.CreateParameters([Excluded], ["foo"], emptyFormatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "excluded",
+ value = "\"foo\"",
+ excluded = true
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ class StringFormatterStub : TypeFormatter
+ {
+ public override string Format(string value) => "bar";
+ }
+
+ [Test]
+ public void FormatterUsedIfMatched()
+ {
+ var formatters = new Dictionary
+ {
+ { typeof(string), new StringFormatterStub() },
+ };
+
+ var parameters = ModelFunctions.CreateParameters([NoAttribute], ["foo"], formatters);
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "noAttribute",
+ value = "bar",
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ class StringFormatterDummy : TypeFormatter
+ {
+ public override string Format(string value) => throw new NotImplementedException();
+ }
+
+ [Test]
+ public void FormattingSkippedForIgnoredParameter()
+ {
+ var formatters = new Dictionary
+ {
+ { typeof(string), new StringFormatterDummy() },
+ };
+
+ var parameters = ModelFunctions.CreateParameters([Ignored], ["foo"], formatters);
+
+ Assert.That(parameters, Is.Empty);
+ }
+
+ [Test]
+ public void MultipleParameters()
+ {
+ var parameters = ModelFunctions.CreateParameters(
+ [NoAttribute, Ignored, Masked, Excluded],
+ ["foo", "bar", "baz", "qux"],
+ emptyFormatters
+ );
+
+ Assert.That(
+ parameters,
+ Is.EqualTo([
+ new Parameter
+ {
+ name = "noAttribute",
+ value = "\"foo\"",
+ },
+ new Parameter
+ {
+ name = "masked",
+ value = "\"baz\"",
+ mode = ParameterMode.Masked,
+ },
+ new Parameter
+ {
+ name = "excluded",
+ value = "\"qux\"",
+ excluded = true,
+ }
+ ]).UsingPropertiesComparer()
+ );
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/LinkHelperTests.cs b/tests/Allure.Net.Commons.Tests/LinkHelperTests.cs
index aadba412..72eeaaaf 100644
--- a/tests/Allure.Net.Commons.Tests/LinkHelperTests.cs
+++ b/tests/Allure.Net.Commons.Tests/LinkHelperTests.cs
@@ -38,7 +38,7 @@ public void UpdateLinksTest()
{
Assert.That(urls, Has.Exactly(1).Items.EqualTo("123456"));
Assert.That(urls, Has.Exactly(1).Items.EqualTo("Custom Url"));
- Assert.That(urls, Has.Exactly(1).Items.EqualTo("Empty Type"));
+ Assert.That(urls, Has.Exactly(1).Items.EqualTo("Empty%20Type"));
Assert.That(urls, Has.Exactly(1).Items.EqualTo("http://TMS.com/"));
Assert.That(urls, Has.Exactly(1).Items.EqualTo("http://Issue.com/"));
Assert.That(urls, Has.Exactly(1).Items.EqualTo("http://Issue.com/Issue%20URL"));
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AllureFacadeTests/AllureApiTestFixture.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AllureApiTestFixture.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/UserAPITests/AllureFacadeTests/AllureApiTestFixture.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AllureApiTestFixture.cs
index a4fab4da..3767cf7c 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AllureFacadeTests/AllureApiTestFixture.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AllureApiTestFixture.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons.Tests.AssertionHelpers;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.UserApiTests.AllureFacadeTests;
+namespace Allure.Net.Commons.Tests.UserApiTests;
class AllureApiTestFixture
{
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs
new file mode 100644
index 00000000..36f328ec
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs
@@ -0,0 +1,231 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+public class AfterFixtureTests
+{
+ [Test]
+ public void CreatesFixtureFromVoidMethodCall()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ VoidMethod
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(VoidMethod)));
+ }
+
+ [Test]
+ public void CreatesFixtureFromFunctionCall()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => MethodReturningInt()
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(MethodReturningInt)));
+ }
+
+ [Test]
+ public async Task CreateFixtureFromAsyncMethodCall()
+ {
+ var tc = new TestResultContainer();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithContainer(tc),
+ AsyncMethod
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(AsyncMethod)));
+ }
+
+ [Test]
+ public async Task CreateFixtureFromAsyncFunctionCall()
+ {
+ var tc = new TestResultContainer();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithContainer(tc),
+ AsyncMethodReturningInt
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(AsyncMethodReturningInt)));
+ }
+
+ [Test]
+ public void CreatesNamedFixture()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ NamedFixture
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo("Foo"));
+ }
+
+ [Test]
+ public void CreateFixtureWithParameters()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => FixtureWithParameters(1, "baz")
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(
+ fixture.parameters,
+ Is.EqualTo([
+ new Parameter { name = "foo", value = "1" },
+ new Parameter { name = "bar", value = "\"baz\"" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void InterpolatesParameterIntoFixtureName()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => Interpolation("bar")
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.name, Is.EqualTo("Foo \"bar\""));
+ }
+
+ [Test]
+ public void IgnoredParametersNotAdded()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => IgnoredParameter("bar")
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var fixture = tc.afters[0];
+ Assert.That(fixture.parameters, Is.Empty);
+ }
+
+ [Test]
+ public void AssignsCustomNameToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => RenamedParameter("baz")
+ );
+
+ Assert.That(tc.afters, Has.One.Items);
+ var parameter = tc.afters[0].parameters[0];
+ Assert.That(parameter.name, Is.EqualTo("bar"));
+ }
+
+ [Test]
+ public void UsesOriginalParameterNameForInterpolation()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => InterpolatedRenamedParameter("baz")
+ );
+
+ Assert.That(tc.afters[0].name, Is.EqualTo("\"baz\""));
+ }
+
+ [Test]
+ public void AppliesMaskedModeToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => MaskedParameter("foo")
+ );
+
+ Assert.That(tc.afters[0].parameters[0].mode, Is.EqualTo(ParameterMode.Masked));
+ }
+
+ [Test]
+ public void AppliesHiddenModeToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => HiddenParameter("foo")
+ );
+
+ Assert.That(tc.afters[0].parameters[0].mode, Is.EqualTo(ParameterMode.Hidden));
+ }
+
+ [AllureAfter]
+ static void VoidMethod() { }
+
+ [AllureAfter]
+ static int MethodReturningInt() => default;
+
+ [AllureAfter]
+ static async Task AsyncMethod()
+ {
+ await Task.Delay(1);
+ }
+
+ [AllureAfter]
+ static async Task AsyncMethodReturningInt()
+ {
+ await Task.Delay(1);
+ return 1;
+ }
+
+ [AllureAfter("Foo")]
+ static void NamedFixture() { }
+
+ [AllureAfter]
+ static void FixtureWithParameters(int foo, string bar) { }
+
+ [AllureAfter("Foo {foo}")]
+ static void Interpolation(string foo) { }
+
+ [AllureAfter]
+ static void IgnoredParameter([AllureParameter(Ignore = true)] string foo) { }
+
+ [AllureAfter]
+ static void RenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureAfter("{foo}")]
+ static void InterpolatedRenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureAfter]
+ static void MaskedParameter([AllureParameter(Mode = ParameterMode.Masked)] string foo) { }
+
+ [AllureAfter]
+ static void HiddenParameter([AllureParameter(Mode = ParameterMode.Hidden)] string foo) { }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs
new file mode 100644
index 00000000..e97c1175
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs
@@ -0,0 +1,24 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class AllureIdAttributeTests
+{
+ [Test]
+ public void AllureIdCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureIdAttribute(1001);
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("ALLURE_ID"));
+ Assert.That(attr.Value, Is.EqualTo("1001"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "ALLURE_ID", value = "1001" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentFileTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentFileTests.cs
new file mode 100644
index 00000000..08a8da2e
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentFileTests.cs
@@ -0,0 +1,245 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
+using Allure.Net.Commons.Tests.UserApiTests;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class AttachmentFileTests : AllureApiTestFixture
+{
+ TestResult testResult;
+ DirectoryInfo dir;
+
+ [SetUp]
+ public void SetUpContext()
+ {
+ this.lifecycle.AddTypeFormatter(new InterpolationStub.TF());
+ this.lifecycle.AddTypeFormatter(new InterpolationDummy.TF());
+ this.testResult = new() {
+ uuid = IdFunctions.CreateUUID(),
+ fullName = "foo",
+ };
+ this.lifecycle.StartTestCase(this.testResult);
+ this.dir = Directory.CreateTempSubdirectory("allure-");
+ }
+
+ [TearDown]
+ public void DeleteFiles()
+ {
+ this.dir.Delete(true);
+ }
+
+ FileInfo CreateFile(string name = null, byte[] content = null)
+ {
+ name ??= Guid.NewGuid().ToString();
+ content ??= [];
+ var path = Path.Combine(this.dir.FullName, name);
+ File.WriteAllBytes(path, content);
+ return new FileInfo(path);
+ }
+
+ [Test]
+ public void CreatesAttachmentFromStringPath()
+ {
+ this.AttachByStringPath();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("foo"));
+ Assert.That(attachment.type, Is.Null);
+ Assert.That(attachment.source, Does.Not.Contain("."));
+ Assert.That(this.writer.attachments, Contains.Item((attachment.source, new byte[]{ 1, 2, 3 })));
+ }
+
+ [Test]
+ public void CreatesAttachmentFromFileInfo()
+ {
+ this.AttachByFileInfo();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("foo"));
+ Assert.That(attachment.type, Is.Null);
+ Assert.That(attachment.source, Does.Not.Contain("."));
+ Assert.That(this.writer.attachments, Contains.Item((attachment.source, new byte[]{ 1, 2, 3 })));
+ }
+
+ [Test]
+ public void NoEffectIfNull()
+ {
+ Assert.That(this.AttachByNull, Throws.Nothing);
+
+ Assert.That(this.testResult.attachments, Is.Empty);
+ Assert.That(this.writer.attachments, Is.Empty);
+ }
+
+ [Test]
+ public void ThrowsIfTypeNotSupported()
+ {
+ Assert.That(
+ this.AttachByInt,
+ Throws.InstanceOf()
+ .With.Message.EqualTo(
+ "Can't create an Allure file attachment from System.Int32. "
+ + "A string or System.IO.FileInfo was expected."
+ )
+ );
+ }
+
+ [Test]
+ public void UsesFileExtension()
+ {
+ this.AttachWithExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.EndWith(".bar"));
+ }
+
+ [Test]
+ public void UsesContentTypeAndOriginalExtension()
+ {
+ this.AttachWithContentTypeAndExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.type, Is.EqualTo("application/json"));
+ Assert.That(attachment.source, Does.EndWith(".bar"));
+ }
+
+ [Test]
+ public void SetsExtensionFromContentTypeIfNotPresent()
+ {
+ this.AttachWithContentTypeAndNoExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.EndWith(".json"));
+ }
+
+ [Test]
+ public void UsesExplicitName()
+ {
+ this.AttachWithName();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("Foo"));
+ }
+
+ [Test]
+ public void InterpolatesArgumentsIntoName()
+ {
+ this.AttachWithInterpolation(1, "foo");
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("1 \"foo\""));
+ }
+
+ [Test]
+ public void UsesTypeFormatters()
+ {
+ this.AttachWithCustomFormatter(new());
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public async Task SupportsAsyncFunctions()
+ {
+ await this.AttachViaTask();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ new byte[]{ 1, 2, 3 })));
+ }
+
+ [Test]
+ public async Task SupportsValueTask()
+ {
+ await this.AttachViaValueTask();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ new byte[]{ 1, 2, 3 })));
+ }
+
+ [Test]
+ public void NoEffectIfNoContextActive()
+ {
+ this.lifecycle.StopTestCase();
+ this.lifecycle.WriteTestCase();
+
+ Assert.That(() => this.AttachWithFailedFormatter(new()), Throws.Nothing);
+ }
+
+ [AllureAttachmentFile]
+ string AttachByStringPath() => this.CreateFile("foo", [1,2,3]).FullName;
+
+ [AllureAttachmentFile]
+ FileInfo AttachByFileInfo() => this.CreateFile("foo", [1,2,3]);
+
+ [AllureAttachmentFile]
+ string AttachByNull() => null;
+
+ [AllureAttachmentFile]
+ int AttachByInt() => 1;
+
+ [AllureAttachmentFile]
+ FileInfo AttachWithExtension() => this.CreateFile("foo.bar");
+
+ [AllureAttachmentFile(ContentType = "application/json")]
+ FileInfo AttachWithContentTypeAndExtension() => this.CreateFile("foo.bar");
+
+ [AllureAttachmentFile(ContentType = "application/json")]
+ FileInfo AttachWithContentTypeAndNoExtension() => this.CreateFile("foo");
+
+ [AllureAttachmentFile("Foo")]
+ FileInfo AttachWithName() => this.CreateFile();
+
+ [AllureAttachmentFile("{arg1} {arg2}")]
+ FileInfo AttachWithInterpolation(int arg1, string arg2) => this.CreateFile();
+
+ [AllureAttachmentFile]
+ async Task AttachViaTask()
+ {
+ await Task.Yield();
+ return this.CreateFile("foo.baz", [1, 2, 3]);
+ }
+
+ [AllureAttachmentFile]
+ async ValueTask AttachViaValueTask()
+ {
+ await Task.Yield();
+ return this.CreateFile("foo.baz", [1, 2, 3]);
+ }
+
+ class InterpolationStub
+ {
+ public class TF : TypeFormatter
+ {
+ public override string Format(InterpolationStub value) => "foo";
+ }
+ }
+
+ [AllureAttachmentFile("{arg}")]
+ FileInfo AttachWithCustomFormatter(InterpolationStub arg) => this.CreateFile();
+
+ class InterpolationDummy
+ {
+ public class TF : TypeFormatter
+ {
+ public override string Format(InterpolationDummy value)
+ => throw new NotImplementedException();
+ }
+ }
+
+ [AllureAttachmentFile("{arg}")]
+ FileInfo AttachWithFailedFormatter(InterpolationDummy arg) => this.CreateFile();
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
new file mode 100644
index 00000000..f888715b
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -0,0 +1,331 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
+using Allure.Net.Commons.Tests.UserApiTests;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class AttachmentTests : AllureApiTestFixture
+{
+ TestResult testResult;
+
+ [SetUp]
+ public void SetUpContext()
+ {
+ this.lifecycle.AddTypeFormatter(new InterpolationStub.TF());
+ this.lifecycle.AddTypeFormatter(new InterpolationDummy.TF());
+ this.testResult = new() {
+ uuid = IdFunctions.CreateUUID(),
+ fullName = "foo",
+ };
+ this.lifecycle.StartTestCase(this.testResult);
+ }
+
+ [Test]
+ public void CreatesAttachmentFromByteArray()
+ {
+ AttachByteArray();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo(nameof(AttachByteArray)));
+ Assert.That(attachment.type, Is.Null);
+ Assert.That(attachment.source, Does.Not.Contain("."));
+ Assert.That(this.writer.attachments, Contains.Item((attachment.source, new byte[]{ 1, 2, 3 })));
+ }
+
+ [Test]
+ public void CreatesAttachmentFromString()
+ {
+ AttachString();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo(nameof(AttachString)));
+ Assert.That(attachment.type, Is.EqualTo("text/plain"));
+ Assert.That(attachment.source, Does.EndWith(".txt"));
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ "Lorem Ipsum"u8.ToArray())));
+ }
+
+ [Test]
+ public void CreatesAttachmentFromStream()
+ {
+ using var stream = AttachStream();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo(nameof(AttachStream)));
+ Assert.That(attachment.type, Is.Null);
+ Assert.That(attachment.source, Does.Not.Contain("."));
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ new byte[]{ 1, 2, 3 })));
+ Assert.That(stream.Position, Is.Zero);
+ }
+
+ [Test]
+ public void ThrowsIfStreamCanNotRead()
+ {
+ Assert.That(
+ AttachNonReadableStream,
+ Throws.InstanceOf()
+ .With.Message.EqualTo(
+ $"Can't create an Allure attachment from {typeof(NonReadableStream).FullName}: "
+ + "this stream does not support the read operation."
+ )
+ );
+ }
+
+ [Test]
+ public void ThrowsIfStreamCanNotSeek()
+ {
+ Assert.That(
+ AttachNonSeekableStream,
+ Throws.InstanceOf()
+ .With.Message.EqualTo(
+ $"Can't create an Allure attachment from {typeof(NonSeekableStream).FullName}: "
+ + "this stream does not support the seek operation."
+ )
+ );
+ }
+
+ [Test]
+ public void ThrowsIfTypeNotSupported()
+ {
+ Assert.That(
+ AttachInt,
+ Throws.InstanceOf()
+ .With.Message.EqualTo(
+ "Can't create an Allure attachment from System.Int32. "
+ + "A string, byte[], or stream was expected."
+ )
+ );
+ }
+
+ [Test]
+ public void UsesEncodingToConvertStrings()
+ {
+ AttachEncoding();
+
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ this.testResult.attachments[0].source,
+ new byte[]
+ {
+ 0x4c, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x20, 0x00,
+ 0x49, 0x00, 0x70, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6D, 0x00
+ })));
+ }
+
+ [Test]
+ public void UsesContentType()
+ {
+ AttachJson();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.type, Is.EqualTo("application/json"));
+ Assert.That(attachment.source, Does.EndWith(".json"));
+ }
+
+ [Test]
+ public void UsesExtension()
+ {
+ AttachExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.EndWith(".foo"));
+ }
+
+ [Test]
+ public void AddsDotBeforeExtension()
+ {
+ AttachExtensionNoDot();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.EndWith(".foo"));
+ }
+
+ [Test]
+ public void DoesntAddDotBeforeExtensionIfAlreadyStartsWithDot()
+ {
+ AttachExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.Not.EndWith("..foo"));
+ }
+
+ [Test]
+ public void AppendsNothingIfExtensionIsEmpty()
+ {
+ AttachEmptyExtension();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.source, Does.Not.Contains("."));
+ }
+
+ [Test]
+ public void UsesExplicitName()
+ {
+ AttachName();
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("Foo"));
+ }
+
+ [Test]
+ public void InterpolatesArgumentsIntoName()
+ {
+ AttachInterpolatedName(1, "foo");
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("1 \"foo\""));
+ }
+
+ [Test]
+ public void UsesTypeFormatters()
+ {
+ AttachCustomFormatter(new());
+
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public async Task SupportsAsyncFunctions()
+ {
+ await AttachStringAsync();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo(nameof(AttachStringAsync)));
+ Assert.That(attachment.type, Is.EqualTo("text/plain"));
+ Assert.That(attachment.source, Does.EndWith(".txt"));
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ "Lorem Ipsum"u8.ToArray())));
+ }
+
+ [Test]
+ public async Task SupportsValueTask()
+ {
+ await AttachStringValueTask();
+
+ Assert.That(this.testResult.attachments, Has.One.Items);
+ var attachment = this.testResult.attachments[0];
+ Assert.That(attachment.name, Is.EqualTo(nameof(AttachStringValueTask)));
+ Assert.That(attachment.type, Is.EqualTo("text/plain"));
+ Assert.That(attachment.source, Does.EndWith(".txt"));
+ Assert.That(
+ this.writer.attachments,
+ Contains.Item((
+ attachment.source,
+ "Lorem Ipsum"u8.ToArray())));
+ }
+
+ [Test]
+ public void NoEffectIfNoContextActive()
+ {
+ this.lifecycle.StopTestCase();
+ this.lifecycle.WriteTestCase();
+
+ Assert.That(() => AttachFailedFormatter(new()), Throws.Nothing);
+ }
+
+ [AllureAttachment]
+ static byte[] AttachByteArray() => [1, 2, 3];
+
+ [AllureAttachment]
+ static string AttachString() => "Lorem Ipsum";
+
+ [AllureAttachment]
+ static Stream AttachStream() => new MemoryStream([1, 2, 3]);
+
+ class NonSeekableStream(byte[] buffer) : MemoryStream(buffer)
+ {
+ public override bool CanSeek => false;
+ }
+
+ [AllureAttachment]
+ static Stream AttachNonSeekableStream() => new NonSeekableStream([]);
+
+ class NonReadableStream(byte[] buffer) : MemoryStream(buffer)
+ {
+ public override bool CanRead => false;
+ }
+
+ [AllureAttachment]
+ static Stream AttachNonReadableStream() => new NonReadableStream([]);
+
+ [AllureAttachment]
+ static int AttachInt() => 1;
+
+ [AllureAttachment(Encoding = "UTF-16")]
+ static string AttachEncoding() => "Lorem Ipsum";
+
+ [AllureAttachment(ContentType = "application/json")]
+ static byte[] AttachJson() => [];
+
+ [AllureAttachment(Extension = ".foo")]
+ static byte[] AttachExtension() => [];
+
+ [AllureAttachment(Extension = "foo")]
+ static byte[] AttachExtensionNoDot() => [];
+
+ [AllureAttachment(Extension = "")]
+ static byte[] AttachEmptyExtension() => [];
+
+ [AllureAttachment("Foo")]
+ static byte[] AttachName() => [];
+
+ [AllureAttachment("{arg1} {arg2}")]
+ static byte[] AttachInterpolatedName(int arg1, string arg2) => [];
+
+ [AllureAttachment]
+ static async Task AttachStringAsync()
+ {
+ await Task.Yield();
+ return "Lorem Ipsum";
+ }
+
+ [AllureAttachment]
+ static async ValueTask AttachStringValueTask()
+ {
+ await Task.Yield();
+ return "Lorem Ipsum";
+ }
+
+ class InterpolationStub
+ {
+ public class TF : TypeFormatter
+ {
+ public override string Format(InterpolationStub value) => "foo";
+ }
+ }
+
+ [AllureAttachment("{arg}")]
+ static byte[] AttachCustomFormatter(InterpolationStub arg) => [];
+
+ class InterpolationDummy
+ {
+ public class TF : TypeFormatter
+ {
+ public override string Format(InterpolationDummy value)
+ => throw new NotImplementedException();
+ }
+ }
+
+ [AllureAttachment("{arg}")]
+ static byte[] AttachFailedFormatter(InterpolationDummy arg) => [];
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
new file mode 100644
index 00000000..f7187f08
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
@@ -0,0 +1,503 @@
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Sdk;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class AttributeApplicationTests
+{
+ [Test]
+ public void DirectMethodAttributesAreApplied()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
+
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Foo epic" },
+ new Label { name = "feature", value = "Foo feature" },
+ new Label { name = "story", value = "Foo story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void DirectMethodAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
+
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Foo epic" },
+ new Label { name = "feature", value = "Foo feature" },
+ new Label { name = "story", value = "Foo story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AbstractBaseAttributesAreApplies()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
+
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Bar epic" },
+ new Label { name = "feature", value = "Bar feature" },
+ new Label { name = "story", value = "Bar story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AbstractBaseAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
+
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Bar epic" },
+ new Label { name = "feature", value = "Bar feature" },
+ new Label { name = "story", value = "Bar story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void VirtualBaseAttributesAreApplies()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
+
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Baz epic" },
+ new Label { name = "feature", value = "Baz feature" },
+ new Label { name = "story", value = "Baz story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void VirtualBaseAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
+
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Baz epic" },
+ new Label { name = "feature", value = "Baz feature" },
+ new Label { name = "story", value = "Baz story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AppliesBaseBeforeOverride()
+ {
+ TestResult tr = new();
+ var method = typeof(AttributeApplicationOrderChild)
+ .GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
+
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
+
+ Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
+ }
+
+ [Test]
+ public void ReturnsBaseBeforeOverride()
+ {
+ TestResult tr = new();
+ var method = typeof(AttributeApplicationOrderChild)
+ .GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
+
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
+ }
+
+ [Test]
+ public void DirectTypeAttributesAreApplied()
+ {
+ TestResult tr = new();
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(ClassWithAttrs), tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void DirectTypeAttributesAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(ClassWithAttrs));
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromBaseClassAreApplied()
+ {
+ TestResult tr = new();
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(InheritedFromClassAttributes), tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromBaseClassAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromClassAttributes));
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromInterfaceAreApplied()
+ {
+ TestResult tr = new();
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(InheritedFromInterfaceAttributes), tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromInterfaceAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromInterfaceAttributes));
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromDifferentSourcesAreCombined()
+ {
+ TestResult tr = new();
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(MultiSourceAttributes), tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ new Label { name = "epic", value = "Direct epic" },
+ new Label { name = "feature", value = "Direct feature" },
+ new Label { name = "story", value = "Direct story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AttributesFromDifferentSourcesAreCombinedWhenReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(MultiSourceAttributes));
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ new Label { name = "epic", value = "Direct epic" },
+ new Label { name = "feature", value = "Direct feature" },
+ new Label { name = "story", value = "Direct story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void CheckTypeAttributeApplicationOrder()
+ {
+ TestResult tr = new();
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(AttributeApplicationOrderChild), tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
+ }
+
+ [Test]
+ public void CheckTypeAttributeReturnOrder()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(AttributeApplicationOrderChild));
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
+ }
+
+ [Test]
+ public void AppliesAllAttributesToMethodAndItsTypeAtOnce()
+ {
+ TestResult tr = new();
+ var method = typeof(ApplyAllInherited)
+ .GetMethod(nameof(ApplyAllInherited.TargetMethod));
+
+ AllureApiAttribute.ApplyAllAttributes(method, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ new Label { name = "epic", value = "Derived epic" },
+ new Label { name = "feature", value = "Derived feature" },
+ new Label { name = "story", value = "Derived story" },
+ new Label { name = "epic", value = "Base method epic" },
+ new Label { name = "feature", value = "Base method feature" },
+ new Label { name = "story", value = "Base method story" },
+ new Label { name = "epic", value = "Derived method epic" },
+ new Label { name = "feature", value = "Derived method feature" },
+ new Label { name = "story", value = "Derived method story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ReturnsAllAttributesToMethodAndItsTypeAtOnce()
+ {
+ TestResult tr = new();
+ var method = typeof(ApplyAllInherited)
+ .GetMethod(nameof(ApplyAllInherited.TargetMethod));
+
+ var attrs = AllureApiAttribute.GetAllAttributes(method);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "Interface epic" },
+ new Label { name = "feature", value = "Interface feature" },
+ new Label { name = "story", value = "Interface story" },
+ new Label { name = "epic", value = "Base epic" },
+ new Label { name = "feature", value = "Base feature" },
+ new Label { name = "story", value = "Base story" },
+ new Label { name = "epic", value = "Derived epic" },
+ new Label { name = "feature", value = "Derived feature" },
+ new Label { name = "story", value = "Derived story" },
+ new Label { name = "epic", value = "Base method epic" },
+ new Label { name = "feature", value = "Base method feature" },
+ new Label { name = "story", value = "Base method story" },
+ new Label { name = "epic", value = "Derived method epic" },
+ new Label { name = "feature", value = "Derived method feature" },
+ new Label { name = "story", value = "Derived method story" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void AllureNameFromTypeNotApplied()
+ {
+ TestResult tr = new();
+ var type = typeof(WithAllureNameOnType);
+ var method = type.GetMethod(nameof(WithAllureNameOnType.TargetMethod));
+
+ AllureApiAttribute.ApplyTypeAttributes(typeof(WithAllureNameOnType), tr);
+ AllureApiAttribute.ApplyAllAttributes(method, tr);
+
+ Assert.That(tr.name, Is.Null);
+ }
+
+ #region Types to check attribute application to methods
+
+ abstract class MethodsWithAttrsBase
+ {
+ [AllureEpic("Bar epic")]
+ [AllureFeature("Bar feature")]
+ [AllureStory("Bar story")]
+ public abstract void Bar();
+
+ [AllureEpic("Baz epic")]
+ [AllureFeature("Baz feature")]
+ [AllureStory("Baz story")]
+ public virtual void Baz() { }
+ }
+
+ class MethodsWithAttrs : MethodsWithAttrsBase
+ {
+ [AllureEpic("Foo epic")]
+ [AllureFeature("Foo feature")]
+ [AllureStory("Foo story")]
+ public static void Foo() { }
+
+ public override void Bar() { }
+
+ public override void Baz() { }
+ }
+
+ #endregion
+
+ #region Types to check attribute application to types
+
+ [AllureEpic("Base epic")]
+ [AllureFeature("Base feature")]
+ [AllureStory("Base story")]
+ class ClassWithAttrs { }
+
+ class InheritedFromClassAttributes : ClassWithAttrs { }
+
+ [AllureEpic("Interface epic")]
+ [AllureFeature("Interface feature")]
+ [AllureStory("Interface story")]
+ interface IInterfaceWithAttributes { }
+
+ class InheritedFromInterfaceAttributes : IInterfaceWithAttributes { }
+
+ [AllureEpic("Direct epic")]
+ [AllureFeature("Direct feature")]
+ [AllureStory("Direct story")]
+ class MultiSourceAttributes : ClassWithAttrs, IInterfaceWithAttributes { }
+
+ [AllureName("Foo")]
+ class WithAllureNameOnType
+ {
+ public static void TargetMethod() { }
+ }
+
+ #endregion
+
+ #region Types to check attribute application to method and type
+
+ [AllureEpic("Interface epic")]
+ [AllureFeature("Interface feature")]
+ [AllureStory("Interface story")]
+ interface IApplyAllInterface { }
+
+ [AllureEpic("Base epic")]
+ [AllureFeature("Base feature")]
+ [AllureStory("Base story")]
+ class ApplyAllBase
+ {
+ [AllureEpic("Base method epic")]
+ [AllureFeature("Base method feature")]
+ [AllureStory("Base method story")]
+ public virtual void TargetMethod() { }
+ }
+
+ [AllureEpic("Derived epic")]
+ [AllureFeature("Derived feature")]
+ [AllureStory("Derived story")]
+ class ApplyAllInherited : ApplyAllBase, IApplyAllInterface
+ {
+ [AllureEpic("Derived method epic")]
+ [AllureFeature("Derived method feature")]
+ [AllureStory("Derived method story")]
+ public override void TargetMethod() { }
+ }
+
+ #endregion
+
+ #region Types to check the attribute application order
+
+ [AllureDescription("foo", Append = true)]
+ interface IAttributeApplicationOrder { }
+
+ [AllureDescription("bar", Append = true)]
+ class AttributeApplicationOrderBase
+ {
+ [AllureDescription("baz", Append = true)]
+ public virtual void TargetMethod() { }
+ }
+
+ [AllureDescription("qux", Append = true)]
+ class AttributeApplicationOrderChild : AttributeApplicationOrderBase, IAttributeApplicationOrder
+ {
+ [AllureDescription("qut", Append = true)]
+ public override void TargetMethod() { }
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs
new file mode 100644
index 00000000..1d0abcaa
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs
@@ -0,0 +1,81 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class BddHierarchyAttributeTests
+{
+ [AllureBddHierarchy("foo")]
+ class TargetBase { }
+
+ [AllureBddHierarchy("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CantBeInherited()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(1).Items);
+ }
+
+ [Test]
+ public void SingleFeatureCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Epic, Is.Null);
+ Assert.That(attr.Feature, Is.EqualTo("foo"));
+ Assert.That(attr.Story, Is.Null);
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "feature", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void EpicAndFeatureCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo", "bar");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Epic, Is.EqualTo("foo"));
+ Assert.That(attr.Feature, Is.EqualTo("bar"));
+ Assert.That(attr.Story, Is.Null);
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "foo" },
+ new Label { name = "feature", value = "bar" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void EpicFeatureAndStoryCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo", "bar", "baz");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Epic, Is.EqualTo("foo"));
+ Assert.That(attr.Feature, Is.EqualTo("bar"));
+ Assert.That(attr.Story, Is.EqualTo("baz"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "epic", value = "foo" },
+ new Label { name = "feature", value = "bar" },
+ new Label { name = "story", value = "baz" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs
new file mode 100644
index 00000000..9e317c90
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs
@@ -0,0 +1,276 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+public class BeforeFixtureTests
+{
+ [Test]
+ public void CreatesFixtureFromVoidMethodCall()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ VoidMethod
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(VoidMethod)));
+ }
+
+ [Test]
+ public void CreatesFixtureFromFunctionCall()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => MethodReturningInt()
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(MethodReturningInt)));
+ }
+
+ [Test]
+ public async Task CreateFixtureFromAsyncMethodCall()
+ {
+ var tc = new TestResultContainer();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithContainer(tc),
+ AsyncMethod
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(AsyncMethod)));
+ }
+
+ [Test]
+ public async Task CreateFixtureFromAsyncFunctionCall()
+ {
+ var tc = new TestResultContainer();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithContainer(tc),
+ AsyncMethodReturningInt
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo(nameof(AsyncMethodReturningInt)));
+ }
+
+ [Test]
+ public void CreatesNamedFixture()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ NamedFixture
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo("Foo"));
+ }
+
+ [Test]
+ public void CreateFixtureWithParameters()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => FixtureWithParameters(1, "baz")
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(
+ fixture.parameters,
+ Is.EqualTo([
+ new Parameter { name = "foo", value = "1" },
+ new Parameter { name = "bar", value = "\"baz\"" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void InterpolatesParameterIntoFixtureName()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => Interpolation("bar")
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo("Foo \"bar\""));
+ }
+
+ [Test]
+ public void IgnoredParametersNotAdded()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => IgnoredParameter("bar")
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.parameters, Is.Empty);
+ }
+
+ [Test]
+ public void AssignsCustomNameToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => RenamedParameter("baz")
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var parameter = tc.befores[0].parameters[0];
+ Assert.That(parameter.name, Is.EqualTo("bar"));
+ }
+
+ [Test]
+ public void UsesOriginalParameterNameForInterpolation()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => InterpolatedRenamedParameter("baz")
+ );
+
+ Assert.That(tc.befores[0].name, Is.EqualTo("\"baz\""));
+ }
+
+ [Test]
+ public void AppliesMaskedModeToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => MaskedParameter("foo")
+ );
+
+ Assert.That(tc.befores[0].parameters[0].mode, Is.EqualTo(ParameterMode.Masked));
+ }
+
+ [Test]
+ public void AppliesHiddenModeToParameter()
+ {
+ var tc = new TestResultContainer();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ () => HiddenParameter("foo")
+ );
+
+ Assert.That(tc.befores[0].parameters[0].mode, Is.EqualTo(ParameterMode.Hidden));
+ }
+
+ [Test]
+ public void CanBeAppliedOnParameterlessConstructor()
+ {
+ var tc = new TestResultContainer();
+
+ _ = AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ static () => _ = new Stub()
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo("Stub.ctor"));
+ }
+
+ [Test]
+ public void CanBeAppliedOnParameterizedConstructor()
+ {
+ var tc = new TestResultContainer();
+
+ _ = AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithContainer(tc),
+ static () => _ = new Stub(1)
+ );
+
+ Assert.That(tc.befores, Has.One.Items);
+ var fixture = tc.befores[0];
+ Assert.That(fixture.name, Is.EqualTo("Foo"));
+ Assert.That(
+ fixture.parameters,
+ Is.EqualTo([
+ new Parameter { name = "foo", value = "1", excluded = false},
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [AllureBefore]
+ static void VoidMethod() { }
+
+ [AllureBefore]
+ static int MethodReturningInt() => default;
+
+ [AllureBefore]
+ static async Task AsyncMethod()
+ {
+ await Task.Delay(1);
+ }
+
+ [AllureBefore]
+ static async Task AsyncMethodReturningInt()
+ {
+ await Task.Delay(1);
+ return 1;
+ }
+
+ class Stub
+ {
+ [AllureBefore]
+ public Stub() { }
+
+ [AllureBefore("Foo")]
+ public Stub(int foo) { }
+ }
+
+ [AllureBefore("Foo")]
+ static void NamedFixture() { }
+
+ [AllureBefore]
+ static void FixtureWithParameters(int foo, string bar) { }
+
+ [AllureBefore("Foo {foo}")]
+ static void Interpolation(string foo) { }
+
+ [AllureBefore]
+ static void IgnoredParameter([AllureParameter(Ignore = true)] string foo) { }
+
+ [AllureBefore]
+ static void RenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureBefore("{foo}")]
+ static void InterpolatedRenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureBefore]
+ static void MaskedParameter([AllureParameter(Mode = ParameterMode.Masked)] string foo) { }
+
+ [AllureBefore]
+ static void HiddenParameter([AllureParameter(Mode = ParameterMode.Hidden)] string foo) { }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs
new file mode 100644
index 00000000..e5c63fa0
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs
@@ -0,0 +1,83 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class DescriptionAttributeTests
+{
+ [AllureDescription("foo")]
+ class TargetBase { }
+
+ [AllureDescription("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void SetsTestDescription()
+ {
+ TestResult tr = new();
+ var attr = new AllureDescriptionAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.MarkdownText, Is.EqualTo("foo"));
+ Assert.That(tr.description, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void AppendsTestDescription()
+ {
+ TestResult tr = new() { description = "foo" };
+
+ new AllureDescriptionAttribute("bar")
+ {
+ Append = true,
+ }.Apply(tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo\n\nbar"));
+ }
+
+ [Test]
+ public void OmitsSeparatorWhenAppendingToNullDescription()
+ {
+ TestResult tr = new();
+
+ new AllureDescriptionAttribute("foo")
+ {
+ Append = true,
+ }.Apply(tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void OmitsSeparatorWhenAppendingToEmptyDescription()
+ {
+ TestResult tr = new(){ description = "" };
+
+ new AllureDescriptionAttribute("foo")
+ {
+ Append = true,
+ }.Apply(tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void DoesNothingIfDescriptionIsNull()
+ {
+ TestResult tr = new() { description = "foo" };
+
+ new AllureDescriptionAttribute(null).Apply(tr);
+
+ Assert.That(tr.description, Is.EqualTo("foo"));
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs
new file mode 100644
index 00000000..9ee4c7d3
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs
@@ -0,0 +1,70 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class DescriptionHtmlAttributeTests
+{
+ [AllureDescription("foo")]
+ class TargetBase { }
+
+ [AllureDescription("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void SetsTestDescription()
+ {
+ TestResult tr = new();
+ var attr = new AllureDescriptionHtmlAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.HtmlText, Is.EqualTo("foo"));
+ Assert.That(tr.descriptionHtml, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void AppendsTestDescription()
+ {
+ TestResult tr = new() { descriptionHtml = "foo
" };
+
+ new AllureDescriptionHtmlAttribute("bar
")
+ {
+ Append = true,
+ }.Apply(tr);
+
+ Assert.That(tr.descriptionHtml, Is.EqualTo("foo
bar
"));
+ }
+
+ [Test]
+ public void NoThrowIfCurrentValueIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureDescriptionHtmlAttribute("foo")
+ {
+ Append = true,
+ }.Apply(tr);
+
+ Assert.That(tr.descriptionHtml, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void DoesNothingIfValueIsNull()
+ {
+ TestResult tr = new() { descriptionHtml = "foo" };
+
+ new AllureDescriptionHtmlAttribute(null).Apply(tr);
+
+ Assert.That(tr.descriptionHtml, Is.EqualTo("foo"));
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs
new file mode 100644
index 00000000..01efa466
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class EpicAttributeTests
+{
+ [AllureEpic("foo")]
+ class TargetBase { }
+
+ [AllureEpic("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void EpicCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureEpicAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("epic"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "epic", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs
new file mode 100644
index 00000000..309abbb8
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class FeatureAttributeTests
+{
+ [AllureFeature("foo")]
+ class TargetBase { }
+
+ [AllureFeature("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void FeatureCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureFeatureAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("feature"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "feature", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs
new file mode 100644
index 00000000..26960f94
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs
@@ -0,0 +1,65 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class IssueAttributeTests
+{
+ [AllureIssue("foo")]
+ class TargetBase { }
+
+ [AllureIssue("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void UrlOnlyIssueCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureIssueAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.IdOrUrl, Is.EqualTo("foo"));
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void IssueWithTitleCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureIssueAttribute("foo")
+ {
+ Title = "bar",
+ }.Apply(tr);
+
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void DoesNothingIfUrlIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureIssueAttribute(null).Apply(tr);
+
+ Assert.That(tr.links, Is.Empty);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs
new file mode 100644
index 00000000..482d1f34
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs
@@ -0,0 +1,69 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class LabelAttributeTests
+{
+ [AllureLabel("foo", "bar")]
+ class TargetBase { }
+
+ [AllureLabel("baz", "qux")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void ItAddsLabelToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureLabelAttribute("foo", "bar");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("foo"));
+ Assert.That(attr.Value, Is.EqualTo("bar"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "foo", value = "bar" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void DoesNothingIfNameIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureLabelAttribute(null, "foo").Apply(tr);
+
+ Assert.That(tr.labels, Is.Empty);
+ }
+
+ [Test]
+ public void DoesNothingIfNameIsNullEmpty()
+ {
+ TestResult tr = new();
+
+ new AllureLabelAttribute("", "foo").Apply(tr);
+
+ Assert.That(tr.labels, Is.Empty);
+ }
+
+ [Test]
+ public void DoesNothingIfValueIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureLabelAttribute("foo", null).Apply(tr);
+
+ Assert.That(tr.labels, Is.Empty);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs
new file mode 100644
index 00000000..3a1237e3
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs
@@ -0,0 +1,83 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class LinkAttributeTests
+{
+ [AllureLink("foo")]
+ class TargetBase { }
+
+ [AllureLink("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void UrlOnlyLinkCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureLinkAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Url, Is.EqualTo("foo"));
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void LinkWithUrlAndTitleCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureLinkAttribute("foo")
+ {
+ Title = "bar",
+ }.Apply(tr);
+
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void LinkWithUrlTitleAndTypeCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureLinkAttribute("foo")
+ {
+ Title = "bar",
+ Type = "baz",
+ }.Apply(tr);
+
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "baz" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void DoesNothingIfUrlIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureLinkAttribute(null).Apply(tr);
+
+ Assert.That(tr.links, Is.Empty);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs
new file mode 100644
index 00000000..272b7c6c
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs
@@ -0,0 +1,36 @@
+using System;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+
+class MetaAttributeTests
+{
+ [AllureTag("foo")]
+ [AllureSuite("bar")]
+ [AllureIssue("foo", Title = "bar")]
+ [AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+ class FooAttribute : AllureMetaAttribute { }
+
+ [Test]
+ public void AttributesOfTheMetaAttributeAreApplied()
+ {
+ TestResult tr = new();
+
+ new FooAttribute().Apply(tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([
+ new Label { name = "tag", value = "foo" },
+ new Label { name = "suite", value = "bar" },
+ ]).UsingPropertiesComparer()
+ );
+ Assert.That(
+ tr.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs
new file mode 100644
index 00000000..d961fa31
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs
@@ -0,0 +1,42 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class NameAttributeTests
+{
+ [AllureName("foo")]
+ class TargetBase { }
+
+ [AllureName("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CantBeInherited()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(1).Items);
+ }
+
+ [Test]
+ public void ItSetsTestName()
+ {
+ TestResult tr = new();
+
+ new AllureNameAttribute("foo").Apply(tr);
+
+ Assert.That(tr.name, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void DoesNothingIfNameIsNull()
+ {
+ TestResult tr = new() { name = "foo" };
+
+ new AllureNameAttribute(null).Apply(tr);
+
+ Assert.That(tr.name, Is.EqualTo("foo"));
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs
new file mode 100644
index 00000000..51f1db4b
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs
@@ -0,0 +1,50 @@
+using System.Linq;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class OwnerAttributeTests
+{
+ [AllureOwner("John Doe")]
+ class TargetBase { }
+
+ [AllureOwner("Jane Doe")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void OwnerOfTheMostDerivedClassQueried()
+ {
+ TestResult tr = new();
+ var attrs = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(attrs, Has.Exactly(1).Items);
+
+ attrs.Single().Apply(tr);
+ var owners = tr.labels.FindAll(static (l) => l.name == "owner");
+
+ Assert.That(
+ owners,
+ Is.EqualTo([new Label { name = "owner", value = "Jane Doe" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void OwnerCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureOwnerAttribute("John Doe");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("owner"));
+ Assert.That(attr.Value, Is.EqualTo("John Doe"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "owner", value = "John Doe" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs
new file mode 100644
index 00000000..0c720971
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class ParentSuiteAttributeTests
+{
+ [AllureParentSuite("foo")]
+ class TargetBase { }
+
+ [AllureParentSuite("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
+ [Test]
+ public void ParentSuiteCanBeAddedToTest()
+ {
+ TestResult tr = new();
+ var attr = new AllureParentSuiteAttribute("foo");
+
+ attr.Apply(tr);
+
+ Assert.That(attr.Name, Is.EqualTo("parentSuite"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "parentSuite", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs
new file mode 100644
index 00000000..2354fc0e
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs
@@ -0,0 +1,50 @@
+using System.Linq;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
+
+class SeverityAttributeTests
+{
+ [AllureSeverity(SeverityLevel.normal)]
+ class TargetBase { }
+
+ [AllureSeverity(SeverityLevel.blocker)]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void SeverityOfTheMostDerivedClassQueried()
+ {
+ TestResult tr = new();
+ var attrs = typeof(TargetDerived).GetCustomAttributes