From 2f5ec58cfc652bfe080d19185ec2d1bc2afecb3a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Tue, 27 Jan 2026 01:41:51 +0700
Subject: [PATCH 01/80] feat(commons): metadata attribute API
---
.../Attributes/AllureBddHierarchy.cs | 65 +++++++++++++++++++
.../Attributes/AllureDescriptionAttribute.cs | 22 +++++++
.../Attributes/AllureIssueAttribute.cs | 26 ++++++++
.../Attributes/AllureLabelAttribute.cs | 17 +++++
.../Attributes/AllureLabelAttributes.cs | 55 ++++++++++++++++
.../Attributes/AllureLinkAttribute.cs | 34 ++++++++++
.../Attributes/AllureMetaAttribute.cs | 28 ++++++++
.../Attributes/AllureNameAttribute.cs | 21 ++++++
.../Attributes/AllureSuiteHierarchy.cs | 65 +++++++++++++++++++
.../Attributes/AllureTagAttribute.cs | 18 +++++
.../Attributes/AllureTmsItemAttribute.cs | 26 ++++++++
.../Sdk/AllureMetadataAttribute.cs | 29 +++++++++
.../DescriptionAttributeTests.cs | 26 ++++++++
.../AttributeTests/EpicAttributeTests.cs | 30 +++++++++
.../AttributeTests/FeatureAttributeTests.cs | 30 +++++++++
.../AttributeTests/IssueAttributeTests.cs | 47 ++++++++++++++
.../AttributeTests/LabelAttributeTests.cs | 30 +++++++++
.../AttributeTests/LinkAttributeTests.cs | 65 +++++++++++++++++++
.../AttributeTests/MetaAttributeTests.cs | 43 ++++++++++++
.../AttributeTests/NameAttributeTests.cs | 26 ++++++++
.../ParentSuiteAttributeTests.cs | 30 +++++++++
.../AttributeTests/StoryAttributeTests.cs | 30 +++++++++
.../AttributeTests/SubSuiteAttributeTests.cs | 30 +++++++++
.../AttributeTests/SuiteAttributeTests.cs | 30 +++++++++
.../SuiteHierarchyAttributeTests.cs | 63 ++++++++++++++++++
.../AttributeTests/TagAttributeTests.cs | 47 ++++++++++++++
.../AttributeTests/TmsItemAttributeTests.cs | 47 ++++++++++++++
27 files changed, 980 insertions(+)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
create mode 100644 src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
new file mode 100644
index 00000000..cf4d91cc
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
@@ -0,0 +1,65 @@
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies the whole BDD hierarchy at once.
+///
+public class AllureBddHierarchyAttribute : AllureMetadataAttribute
+{
+ string? Epic { get; init; }
+ string? Feature { get; init; }
+ 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;
+ }
+
+ ///
+ protected internal 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/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
new file mode 100644
index 00000000..20514a03
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a description.
+///
+/// A description text. Markdown is supported.
+[AttributeUsage(
+ AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
+ AllowMultiple = false,
+ Inherited = true
+)]
+public class AllureDescriptionAttribute(string description) : AllureMetadataAttribute
+{
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.description = description;
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
new file mode 100644
index 00000000..27aa9b50
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -0,0 +1,26 @@
+using Allure.Net.Commons.Sdk;
+
+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.
+///
+public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
+{
+ string Title { get; set; }
+
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.links.Add(new()
+ {
+ url = issueIdOrUrl,
+ 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..cceccac4
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -0,0 +1,17 @@
+using Allure.Net.Commons.Sdk;
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a custom label.
+///
+/// A label's name.
+/// A label's value.
+public class AllureLabelAttribute(string name, string value) : AllureMetadataAttribute
+{
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.labels.Add(new() { name = name, value = value });
+ }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
new file mode 100644
index 00000000..36180f3f
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
@@ -0,0 +1,55 @@
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a parentSuite label.
+///
+public class AllureParentSuiteAttribute(string parentSuite)
+ : AllureLabelAttribute(LabelName.PARENT_SUITE, parentSuite);
+
+///
+/// Applies a suite label.
+///
+public class AllureSuiteAttribute(string suite)
+ : AllureLabelAttribute(LabelName.SUITE, suite);
+
+///
+/// Applies a subSuite label.
+///
+public class AllureSubSuiteAttribute(string subSuite)
+ : AllureLabelAttribute(LabelName.SUB_SUITE, subSuite);
+
+///
+/// Applies an epic label.
+///
+public class AllureEpicAttribute(string epic)
+ : AllureLabelAttribute(LabelName.EPIC, epic);
+
+///
+/// Applies a feature label.
+///
+public class AllureFeatureAttribute(string feature)
+ : AllureLabelAttribute(LabelName.FEATURE, feature);
+
+///
+/// Applies a story label.
+///
+public class AllureStoryAttribute(string story)
+ : AllureLabelAttribute(LabelName.STORY, story);
+
+///
+/// Applies an Allure ID.
+///
+public class AllureId(string id)
+ : AllureLabelAttribute(LabelName.ALLURE_ID, id);
+
+///
+/// Applies an owner label.
+///
+public class AllureOwner(string owner)
+ : AllureLabelAttribute(LabelName.OWNER, owner);
+
+///
+/// Applies a severity label.
+///
+public class AllureSeverity(SeverityLevel severity)
+ : AllureLabelAttribute(LabelName.SEVERITY, severity.ToString());
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
new file mode 100644
index 00000000..843211e3
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -0,0 +1,34 @@
+using Allure.Net.Commons.Sdk;
+
+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.
+///
+public class AllureLinkAttribute(string url) : AllureMetadataAttribute
+{
+ ///
+ /// A display text of the link.
+ ///
+ public string Title { get; set; }
+
+ ///
+ /// A type of the link.
+ ///
+ public string Type { get; set; }
+
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.links.Add(new()
+ {
+ url = 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..4da74f9b
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using Allure.Net.Commons.Sdk;
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies all the attributes applied to its subclass. Allows reducing boilerplate code.
+///
+public abstract class AllureMetaAttribute : AllureMetadataAttribute
+{
+ private readonly AllureMetadataAttribute[] attributes;
+
+ public AllureMetaAttribute()
+ {
+ this.attributes = [
+ ..this.GetType().GetCustomAttributes(true),
+ ];
+ }
+
+ ///
+ sealed protected internal 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..47738400
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -0,0 +1,21 @@
+using System;
+using Allure.Net.Commons.Sdk;
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies a display name.
+///
+[AttributeUsage(
+ AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
+ AllowMultiple = false,
+ Inherited = true
+)]
+public class AllureNameAttribute(string name) : AllureMetadataAttribute
+{
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.name = name;
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
new file mode 100644
index 00000000..67c252b7
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
@@ -0,0 +1,65 @@
+using Allure.Net.Commons.Sdk;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies the whole suite hierarchy at once.
+///
+public class AllureSuiteHierarchyAttribute : AllureMetadataAttribute
+{
+ string? ParentSuite { get; init; }
+ string? Suite { get; init; }
+ 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;
+ }
+
+ ///
+ protected internal 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..2d0c84bb
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -0,0 +1,18 @@
+using System.Linq;
+using Allure.Net.Commons.Sdk;
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Applies tags.
+///
+public class AllureTagAttribute(string tag, params string[] moreTags)
+ : AllureMetadataAttribute
+{
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.labels.Add(Label.Tag(tag));
+ testResult.labels.AddRange(moreTags.Select(Label.Tag));
+ }
+}
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
new file mode 100644
index 00000000..2af8d64a
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -0,0 +1,26 @@
+using Allure.Net.Commons.Sdk;
+
+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.
+///
+public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttribute
+{
+ string Title { get; set; }
+
+ ///
+ protected internal override void Apply(TestResult testResult)
+ {
+ testResult.links.Add(new()
+ {
+ url = tmsItemIdOrUrl,
+ name = this.Title,
+ type = LinkType.TMS_ITEM,
+ });
+ }
+}
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
new file mode 100644
index 00000000..a0daddb0
--- /dev/null
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Allure.Net.Commons.Sdk;
+
+///
+/// A base class for attributes that apply metadata to test results.
+///
+[AttributeUsage(
+ AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
+ AllowMultiple = true,
+ Inherited = true
+)]
+public abstract class AllureMetadataAttribute : Attribute
+{
+ internal void Apply(AllureContext context)
+ {
+ if (context.HasTest)
+ {
+ this.Apply(context.CurrentTest);
+ }
+ }
+
+ ///
+ /// Applies the metadata denoted by the attribute to a test result.
+ /// It's only called if a test is running.
+ ///
+ /// A test result to apply the metadata to.
+ protected internal abstract void Apply(TestResult testResult);
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
new file mode 100644
index 00000000..6b7bd223
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
@@ -0,0 +1,26 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class DescriptionAttributeTests
+{
+ [Test]
+ public void SetsTestDescription()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureDescriptionAttribute("foo").Apply(ctx);
+
+ Assert.That(ctx.CurrentTest.description, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureDescriptionAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
new file mode 100644
index 00000000..1587e97c
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class EpicAttributeTests
+{
+ [Test]
+ public void EpicCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureEpicAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "epic", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureEpicAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
new file mode 100644
index 00000000..7cca87e7
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class FeatureAttributeTests
+{
+ [Test]
+ public void FeatureCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureFeatureAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "feature", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureFeatureAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
new file mode 100644
index 00000000..f92c28d7
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
@@ -0,0 +1,47 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class IssueAttributeTests
+{
+ [Test]
+ public void UrlOnlyIssueCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureIssueAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void IssueWithTitleCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureIssueAttribute("foo")
+ {
+ Title = "bar",
+ }.Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureIssueAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
new file mode 100644
index 00000000..9c4da3ac
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class LabelAttributeTests
+{
+ [Test]
+ public void ItAddsLabelToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureLabelAttribute("foo", "bar").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "foo", value = "bar" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureLabelAttribute("foo", "bar");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
new file mode 100644
index 00000000..9bfa3e71
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
@@ -0,0 +1,65 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class LinkAttributeTests
+{
+ [Test]
+ public void UrlOnlyLinkCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureLinkAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void LinkWithUrlAndTitleCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureLinkAttribute("foo")
+ {
+ Title = "bar",
+ }.Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void LinkWithUrlTitleAndTypeCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureLinkAttribute("foo")
+ {
+ Title = "bar",
+ Type = "baz",
+ }.Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "baz" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureLinkAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
new file mode 100644
index 00000000..075774aa
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
@@ -0,0 +1,43 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+
+class MetaAttributeTests
+{
+ [AllureTag("foo")]
+ [AllureSuite("bar")]
+ [AllureIssue("foo", Title = "bar")]
+ class FooAttribute : AllureMetaAttribute { }
+
+ [Test]
+ public void AttributesOfTheMetaAttributeAreApplied()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new FooAttribute().Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([
+ new Label { name = "tag", value = "foo" },
+ new Label { name = "suite", value = "bar" },
+ ]).UsingPropertiesComparer()
+ );
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new FooAttribute();
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
new file mode 100644
index 00000000..40c7f299
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
@@ -0,0 +1,26 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class NameAttributeTests
+{
+ [Test]
+ public void ItSetsTestName()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureNameAttribute("foo").Apply(ctx);
+
+ Assert.That(ctx.CurrentTest.name, Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureNameAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
new file mode 100644
index 00000000..3cc98c93
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class ParentSuiteAttributeTests
+{
+ [Test]
+ public void ParentSuiteCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureParentSuiteAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "parentSuite", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureParentSuiteAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
new file mode 100644
index 00000000..2a7aca8d
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class StoryAttributeTests
+{
+ [Test]
+ public void StoryCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureStoryAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "story", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureStoryAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
new file mode 100644
index 00000000..a896cb35
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class SubSuiteAttributeTests
+{
+ [Test]
+ public void SubSuiteCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureSubSuiteAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "subSuite", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureSubSuiteAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
new file mode 100644
index 00000000..d90f5a62
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
@@ -0,0 +1,30 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class SuiteAttributeTests
+{
+ [Test]
+ public void SuiteCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureSuiteAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureSuiteAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
new file mode 100644
index 00000000..8cdf7015
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
@@ -0,0 +1,63 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class SuiteHierarchyAttributeTests
+{
+ [Test]
+ public void SingleSuiteCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureSuiteHierarchyAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void TwoLevelSuiteHierarchyCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureSuiteHierarchyAttribute("foo", "bar").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([
+ new Label { name = "parentSuite", value = "foo" },
+ new Label { name = "suite", value = "bar" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ThreeLevelSuiteHierarchyCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureSuiteHierarchyAttribute("foo", "bar", "baz").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([
+ new Label { name = "parentSuite", value = "foo" },
+ new Label { name = "suite", value = "bar" },
+ new Label { name = "subSuite", value = "baz" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureSuiteHierarchyAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
new file mode 100644
index 00000000..0240be67
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
@@ -0,0 +1,47 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class TagAttributeTests
+{
+ [Test]
+ public void ItAddsSingleTagToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureTagAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([new Label { name = "tag", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void ItAddsMultipleTagsToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureTagAttribute("foo", "bar", "baz").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.labels,
+ Is.EquivalentTo([
+ new Label { name = "tag", value = "foo" },
+ new Label { name = "tag", value = "bar" },
+ new Label { name = "tag", value = "baz" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureTagAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
new file mode 100644
index 00000000..0c13b3e6
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
@@ -0,0 +1,47 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class TmsItemAttributeTests
+{
+ [Test]
+ public void UrlOnlyTmsItemCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureTmsItemAttribute("foo").Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", type = "tms" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void TmsItemWithTitleCanBeAddedToTest()
+ {
+ var ctx = new AllureContext().WithTestContext(new());
+
+ new AllureTmsItemAttribute("foo")
+ {
+ Title = "bar",
+ }.Apply(ctx);
+
+ Assert.That(
+ ctx.CurrentTest.links,
+ Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "tms" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void NoEffectIfNoTestIsRunning()
+ {
+ var ctx = new AllureContext();
+ var attr = new AllureTmsItemAttribute("foo");
+
+ Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ }
+}
From 035d514f01c6ceef4c93d035e55a9e448c4d8823 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Tue, 27 Jan 2026 03:40:26 +0700
Subject: [PATCH 02/80] feat(commons): add RunInContextAsync
---
src/Allure.Net.Commons/AllureLifecycle.cs | 37 +++++++++++++++
.../AllureLifeCycleTest.cs | 46 +++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/src/Allure.Net.Commons/AllureLifecycle.cs b/src/Allure.Net.Commons/AllureLifecycle.cs
index d553e050..ed521b2d 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,42 @@ 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;
+ }
+
+ var originalContext = this.Context;
+ try
+ {
+ this.Context = context;
+ await asyncAction();
+ }
+ finally
+ {
+ this.Context = originalContext;
+ }
+ }
+
///
/// 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/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
index c8522a6c..b0f77bb9 100644
--- a/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
+++ b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
@@ -168,6 +168,31 @@ 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.Delay(1);
+ lifecycle.WriteTestCase();
+ });
+
+ Assert.That(writer.testResults, Is.Not.Empty);
+ }
+
[Test]
public async Task ContextCapturingHasNoEffectIfContextIsNull()
{
@@ -188,6 +213,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()
{
From ade6125c757a976f4bc53ddedc5d0dd3cfc2b9b6 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Tue, 27 Jan 2026 03:42:15 +0700
Subject: [PATCH 03/80] fix(commons): invalid member access modifier on some
link attrs
---
src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs | 5 ++++-
src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
index 27aa9b50..f3e79b12 100644
--- a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -11,7 +11,10 @@ namespace Allure.Net.Commons.Attributes;
///
public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
{
- string Title { get; set; }
+ ///
+ /// A display text of the issue link.
+ ///
+ public string Title { get; set; }
///
protected internal override void Apply(TestResult testResult)
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
index 2af8d64a..4759287d 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -11,7 +11,10 @@ namespace Allure.Net.Commons.Attributes;
///
public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttribute
{
- string Title { get; set; }
+ ///
+ /// A display text of the TMS item link.
+ ///
+ public string Title { get; set; }
///
protected internal override void Apply(TestResult testResult)
From 847f83284e76a6f9f6ee0288fe146b16452e9541 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Tue, 27 Jan 2026 03:42:39 +0700
Subject: [PATCH 04/80] feat(commons): add step and parameter attributes
---
.../Attributes/AllureParameterAttribute.cs | 23 ++
.../Attributes/AllureStepAttribute.cs | 22 ++
.../Steps/AllureStepParameterHelper.cs | 13 +-
.../AttributeTests/StepTests.cs | 200 ++++++++++++++++++
4 files changed, 256 insertions(+), 2 deletions(-)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
new file mode 100644
index 00000000..d9099c97
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
@@ -0,0 +1,23 @@
+using System;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Controls how Allure treats test and step parameters created from method arguments.
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class AllureParameterAttribute : Attribute
+{
+ ///
+ /// If set to true, the argument will be precluded from the report.
+ ///
+ public bool Ignore { get; init; }
+
+ ///
+ /// A display name of the parameter. If set to null,
+ /// the source name of the parameter will be used.
+ ///
+ public string? Name { get; init; }
+}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
new file mode 100644
index 00000000..bfd595e3
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
@@ -0,0 +1,22 @@
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// Wraps each call of the method in an Allure step.
+///
+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/Steps/AllureStepParameterHelper.cs b/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
index 22f910c8..e0c23aa7 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
@@ -146,8 +147,8 @@ IReadOnlyDictionary formatters
{
return metadata.GetParameters()
.Select(x => (
- name: x.GetCustomAttribute()?.Name ?? x.Name,
- skip: x.GetCustomAttribute() != null))
+ name: GetCustomParameterName(x) ?? x.Name,
+ skip: ShouldParameterBeIgnored(x)))
.Zip(args,
(parameter, value) => parameter.skip
? null
@@ -160,6 +161,14 @@ IReadOnlyDictionary formatters
.ToList();
}
+ 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;
+
private static bool TrySplit(string s, char separator, out string[] parts)
{
parts = s.Split(separator);
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
new file mode 100644
index 00000000..39add60d
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
@@ -0,0 +1,200 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Steps;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+public class StepTests
+{
+ [Test]
+ public void CreatesStepFromVoidMethodCall()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ VoidMethod
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo(nameof(VoidMethod)));
+ }
+
+ [Test]
+ public void CreatesStepFromFunctionCall()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => MethodReturningInt()
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo(nameof(MethodReturningInt)));
+ }
+
+ [Test]
+ public async Task CreatesStepFromAsyncMethodCall()
+ {
+ var tr = new TestResult();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithTestContext(tr),
+ AsyncMethod
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo(nameof(AsyncMethod)));
+ }
+
+ [Test]
+ public async Task CreatesStepFromAsyncFunctionCall()
+ {
+ var tr = new TestResult();
+
+ await AllureLifecycle.Instance.RunInContextAsync(
+ new AllureContext().WithTestContext(tr),
+ AsyncMethodReturningInt
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo(nameof(AsyncMethodReturningInt)));
+ }
+
+ [Test]
+ public void CreatesNamedStep()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ NamedStep
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo("Foo"));
+ }
+
+ [Test]
+ public void CreatesStepWithParameters()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => StepWithParameters(1, "baz")
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(
+ step.parameters,
+ Is.EqualTo([
+ new Parameter { name = "foo", value = "1" },
+ new Parameter { name = "bar", value = "\"baz\"" },
+ ]).UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void InterpolatesParameterIntoStepName()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => Interpolation("bar")
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.name, Is.EqualTo("Foo \"bar\""));
+ }
+
+ [Test]
+ public void DoesntAddIgnoredParameters()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => IgnoredParameter("bar")
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var step = tr.steps[0];
+ Assert.That(step.parameters, Is.Empty);
+ }
+
+ [Test]
+ public void AssignsCustomNameToParameter()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => RenamedParameter("baz")
+ );
+
+ Assert.That(tr.steps, Has.One.Items);
+ var parameter = tr.steps[0].parameters[0];
+ Assert.That(parameter.name, Is.EqualTo("bar"));
+ }
+
+ [Test]
+ public void UsesOriginalParameterNameForInterpolation()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => InterpolatedRenamedParameter("baz")
+ );
+
+ Assert.That(tr.steps[0].name, Is.EqualTo("\"baz\""));
+ }
+
+ [AllureStep]
+ static void VoidMethod() { }
+
+ [AllureStep]
+ static int MethodReturningInt() => default;
+
+ [AllureStep]
+ static async Task AsyncMethod()
+ {
+ await Task.Delay(1);
+ }
+
+ [AllureStep]
+ static async Task AsyncMethodReturningInt()
+ {
+ await Task.Delay(1);
+ return 1;
+ }
+
+ [AllureStep("Foo")]
+ static void NamedStep() { }
+
+ [AllureStep]
+ static void StepWithParameters(int foo, string bar) { }
+
+ [AllureStep("Foo {foo}")]
+ static void Interpolation(string foo) { }
+
+ [AllureStep]
+ static void IgnoredParameter([AllureParameter(Ignore = true)] string foo) { }
+
+ [AllureStep]
+ static void RenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureStep("{foo}")]
+ static void InterpolatedRenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+}
\ No newline at end of file
From 1576d6f30fd760845b19658e12530502a44a32d6 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Tue, 27 Jan 2026 18:14:49 +0700
Subject: [PATCH 05/80] feat(commons): simplify attributes api
---
.../Attributes/AllureBddHierarchy.cs | 2 +-
.../Attributes/AllureDescriptionAttribute.cs | 2 +-
.../Attributes/AllureIssueAttribute.cs | 2 +-
.../Attributes/AllureLabelAttribute.cs | 2 +-
.../Attributes/AllureLinkAttribute.cs | 2 +-
.../Attributes/AllureMetaAttribute.cs | 2 +-
.../Attributes/AllureNameAttribute.cs | 2 +-
.../Attributes/AllureSuiteHierarchy.cs | 2 +-
.../Attributes/AllureTagAttribute.cs | 2 +-
.../Attributes/AllureTmsItemAttribute.cs | 2 +-
.../Sdk/AllureMetadataAttribute.cs | 14 ++--------
.../DescriptionAttributeTests.cs | 15 +++--------
.../AttributeTests/EpicAttributeTests.cs | 15 +++--------
.../AttributeTests/FeatureAttributeTests.cs | 15 +++--------
.../AttributeTests/IssueAttributeTests.cs | 21 +++++----------
.../AttributeTests/LabelAttributeTests.cs | 15 +++--------
.../AttributeTests/LinkAttributeTests.cs | 27 +++++++------------
.../AttributeTests/MetaAttributeTests.cs | 17 +++---------
.../AttributeTests/NameAttributeTests.cs | 15 +++--------
.../ParentSuiteAttributeTests.cs | 15 +++--------
.../AttributeTests/StoryAttributeTests.cs | 15 +++--------
.../AttributeTests/SubSuiteAttributeTests.cs | 15 +++--------
.../AttributeTests/SuiteAttributeTests.cs | 15 +++--------
.../SuiteHierarchyAttributeTests.cs | 27 +++++++------------
.../AttributeTests/TagAttributeTests.cs | 21 +++++----------
.../AttributeTests/TmsItemAttributeTests.cs | 21 +++++----------
26 files changed, 79 insertions(+), 224 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
index cf4d91cc..d5c30d0a 100644
--- a/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
@@ -43,7 +43,7 @@ public AllureBddHierarchyAttribute(string feature)
}
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
var labels = testResult.labels;
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
index 20514a03..5a295a8f 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -15,7 +15,7 @@ namespace Allure.Net.Commons.Attributes;
public class AllureDescriptionAttribute(string description) : AllureMetadataAttribute
{
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.description = description;
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
index f3e79b12..30da41bf 100644
--- a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -17,7 +17,7 @@ public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
public string Title { get; set; }
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.links.Add(new()
{
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
index cceccac4..2ecd4375 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -10,7 +10,7 @@ namespace Allure.Net.Commons.Attributes;
public class AllureLabelAttribute(string name, string value) : AllureMetadataAttribute
{
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.labels.Add(new() { name = name, value = value });
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
index 843211e3..675608da 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -22,7 +22,7 @@ public class AllureLinkAttribute(string url) : AllureMetadataAttribute
public string Type { get; set; }
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.links.Add(new()
{
diff --git a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
index 4da74f9b..d94d8f12 100644
--- a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -18,7 +18,7 @@ public AllureMetaAttribute()
}
///
- sealed protected internal override void Apply(TestResult testResult)
+ sealed public override void Apply(TestResult testResult)
{
foreach (var attr in this.attributes)
{
diff --git a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
index 47738400..bbc891b3 100644
--- a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -14,7 +14,7 @@ namespace Allure.Net.Commons.Attributes;
public class AllureNameAttribute(string name) : AllureMetadataAttribute
{
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.name = name;
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
index 67c252b7..1024de60 100644
--- a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
@@ -43,7 +43,7 @@ public AllureSuiteHierarchyAttribute(string suite)
}
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
var labels = testResult.labels;
diff --git a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
index 2d0c84bb..f0482406 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -10,7 +10,7 @@ public class AllureTagAttribute(string tag, params string[] moreTags)
: AllureMetadataAttribute
{
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.labels.Add(Label.Tag(tag));
testResult.labels.AddRange(moreTags.Select(Label.Tag));
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
index 4759287d..945ce72e 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -17,7 +17,7 @@ public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttri
public string Title { get; set; }
///
- protected internal override void Apply(TestResult testResult)
+ public override void Apply(TestResult testResult)
{
testResult.links.Add(new()
{
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index a0daddb0..01edfd6e 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -12,18 +12,8 @@ namespace Allure.Net.Commons.Sdk;
)]
public abstract class AllureMetadataAttribute : Attribute
{
- internal void Apply(AllureContext context)
- {
- if (context.HasTest)
- {
- this.Apply(context.CurrentTest);
- }
- }
-
///
- /// Applies the metadata denoted by the attribute to a test result.
- /// It's only called if a test is running.
+ /// Applies the attribute to a test result.
///
- /// A test result to apply the metadata to.
- protected internal abstract void Apply(TestResult testResult);
+ public abstract void Apply(TestResult testResult);
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
index 6b7bd223..14a57f00 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
@@ -8,19 +8,10 @@ class DescriptionAttributeTests
[Test]
public void SetsTestDescription()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureDescriptionAttribute("foo").Apply(ctx);
+ new AllureDescriptionAttribute("foo").Apply(tr);
- Assert.That(ctx.CurrentTest.description, Is.EqualTo("foo"));
- }
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureDescriptionAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ Assert.That(tr.description, Is.EqualTo("foo"));
}
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
index 1587e97c..c4ea897b 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
@@ -8,23 +8,14 @@ class EpicAttributeTests
[Test]
public void EpicCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureEpicAttribute("foo").Apply(ctx);
+ new AllureEpicAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "epic", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureEpicAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
index 7cca87e7..3ae4f5c5 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
@@ -8,23 +8,14 @@ class FeatureAttributeTests
[Test]
public void FeatureCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureFeatureAttribute("foo").Apply(ctx);
+ new AllureFeatureAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "feature", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureFeatureAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
index f92c28d7..7f558c76 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
@@ -8,12 +8,12 @@ class IssueAttributeTests
[Test]
public void UrlOnlyIssueCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureIssueAttribute("foo").Apply(ctx);
+ new AllureIssueAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", type = "issue" }])
.UsingPropertiesComparer()
);
@@ -22,26 +22,17 @@ public void UrlOnlyIssueCanBeAddedToTest()
[Test]
public void IssueWithTitleCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
new AllureIssueAttribute("foo")
{
Title = "bar",
- }.Apply(ctx);
+ }.Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureIssueAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
index 9c4da3ac..28482dfe 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
@@ -8,23 +8,14 @@ class LabelAttributeTests
[Test]
public void ItAddsLabelToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureLabelAttribute("foo", "bar").Apply(ctx);
+ new AllureLabelAttribute("foo", "bar").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "foo", value = "bar" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureLabelAttribute("foo", "bar");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
index 9bfa3e71..455e1ef3 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
@@ -8,12 +8,12 @@ class LinkAttributeTests
[Test]
public void UrlOnlyLinkCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureLinkAttribute("foo").Apply(ctx);
+ new AllureLinkAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo" }])
.UsingPropertiesComparer()
);
@@ -22,15 +22,15 @@ public void UrlOnlyLinkCanBeAddedToTest()
[Test]
public void LinkWithUrlAndTitleCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
new AllureLinkAttribute("foo")
{
Title = "bar",
- }.Apply(ctx);
+ }.Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", name = "bar" }])
.UsingPropertiesComparer()
);
@@ -39,27 +39,18 @@ public void LinkWithUrlAndTitleCanBeAddedToTest()
[Test]
public void LinkWithUrlTitleAndTypeCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
new AllureLinkAttribute("foo")
{
Title = "bar",
Type = "baz",
- }.Apply(ctx);
+ }.Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "baz" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureLinkAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
index 075774aa..99809826 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
@@ -14,30 +14,21 @@ class FooAttribute : AllureMetaAttribute { }
[Test]
public void AttributesOfTheMetaAttributeAreApplied()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new FooAttribute().Apply(ctx);
+ new FooAttribute().Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([
new Label { name = "tag", value = "foo" },
new Label { name = "suite", value = "bar" },
]).UsingPropertiesComparer()
);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "issue" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new FooAttribute();
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
index 40c7f299..2a246cc1 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
@@ -8,19 +8,10 @@ class NameAttributeTests
[Test]
public void ItSetsTestName()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureNameAttribute("foo").Apply(ctx);
+ new AllureNameAttribute("foo").Apply(tr);
- Assert.That(ctx.CurrentTest.name, Is.EqualTo("foo"));
- }
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureNameAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
+ Assert.That(tr.name, Is.EqualTo("foo"));
}
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
index 3cc98c93..970e104d 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -8,23 +8,14 @@ class ParentSuiteAttributeTests
[Test]
public void ParentSuiteCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureParentSuiteAttribute("foo").Apply(ctx);
+ new AllureParentSuiteAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "parentSuite", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureParentSuiteAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
index 2a7aca8d..3a01fb2c 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
@@ -8,23 +8,14 @@ class StoryAttributeTests
[Test]
public void StoryCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureStoryAttribute("foo").Apply(ctx);
+ new AllureStoryAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "story", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureStoryAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
index a896cb35..be2e51ec 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
@@ -8,23 +8,14 @@ class SubSuiteAttributeTests
[Test]
public void SubSuiteCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureSubSuiteAttribute("foo").Apply(ctx);
+ new AllureSubSuiteAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "subSuite", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureSubSuiteAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
index d90f5a62..6cf4a088 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
@@ -8,23 +8,14 @@ class SuiteAttributeTests
[Test]
public void SuiteCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureSuiteAttribute("foo").Apply(ctx);
+ new AllureSuiteAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureSuiteAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
index 8cdf7015..fa60dfbf 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
@@ -8,12 +8,12 @@ class SuiteHierarchyAttributeTests
[Test]
public void SingleSuiteCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureSuiteHierarchyAttribute("foo").Apply(ctx);
+ new AllureSuiteHierarchyAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
.UsingPropertiesComparer()
);
@@ -22,12 +22,12 @@ public void SingleSuiteCanBeAddedToTest()
[Test]
public void TwoLevelSuiteHierarchyCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureSuiteHierarchyAttribute("foo", "bar").Apply(ctx);
+ new AllureSuiteHierarchyAttribute("foo", "bar").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([
new Label { name = "parentSuite", value = "foo" },
new Label { name = "suite", value = "bar" },
@@ -38,12 +38,12 @@ public void TwoLevelSuiteHierarchyCanBeAddedToTest()
[Test]
public void ThreeLevelSuiteHierarchyCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureSuiteHierarchyAttribute("foo", "bar", "baz").Apply(ctx);
+ new AllureSuiteHierarchyAttribute("foo", "bar", "baz").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([
new Label { name = "parentSuite", value = "foo" },
new Label { name = "suite", value = "bar" },
@@ -51,13 +51,4 @@ public void ThreeLevelSuiteHierarchyCanBeAddedToTest()
]).UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureSuiteHierarchyAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
index 0240be67..43324307 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
@@ -8,12 +8,12 @@ class TagAttributeTests
[Test]
public void ItAddsSingleTagToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureTagAttribute("foo").Apply(ctx);
+ new AllureTagAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([new Label { name = "tag", value = "foo" }])
.UsingPropertiesComparer()
);
@@ -22,12 +22,12 @@ public void ItAddsSingleTagToTest()
[Test]
public void ItAddsMultipleTagsToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureTagAttribute("foo", "bar", "baz").Apply(ctx);
+ new AllureTagAttribute("foo", "bar", "baz").Apply(tr);
Assert.That(
- ctx.CurrentTest.labels,
+ tr.labels,
Is.EquivalentTo([
new Label { name = "tag", value = "foo" },
new Label { name = "tag", value = "bar" },
@@ -35,13 +35,4 @@ public void ItAddsMultipleTagsToTest()
]).UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureTagAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
index 0c13b3e6..3f725e2b 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
@@ -8,12 +8,12 @@ class TmsItemAttributeTests
[Test]
public void UrlOnlyTmsItemCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
- new AllureTmsItemAttribute("foo").Apply(ctx);
+ new AllureTmsItemAttribute("foo").Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", type = "tms" }])
.UsingPropertiesComparer()
);
@@ -22,26 +22,17 @@ public void UrlOnlyTmsItemCanBeAddedToTest()
[Test]
public void TmsItemWithTitleCanBeAddedToTest()
{
- var ctx = new AllureContext().WithTestContext(new());
+ TestResult tr = new();
new AllureTmsItemAttribute("foo")
{
Title = "bar",
- }.Apply(ctx);
+ }.Apply(tr);
Assert.That(
- ctx.CurrentTest.links,
+ tr.links,
Is.EquivalentTo([new Link { url = "foo", name = "bar", type = "tms" }])
.UsingPropertiesComparer()
);
}
-
- [Test]
- public void NoEffectIfNoTestIsRunning()
- {
- var ctx = new AllureContext();
- var attr = new AllureTmsItemAttribute("foo");
-
- Assert.That(() => attr.Apply(ctx), Throws.Nothing);
- }
}
From edb193da3a1b521bb6c5ad237704c37e88428e7a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 13:55:41 +0700
Subject: [PATCH 06/80] feat(commons): iteration 2 on metadata attributes
---
...rchy.cs => AllureBddHierarchyAttribute.cs} | 2 +
.../Attributes/AllureDescriptionAttribute.cs | 38 ++++++++--
.../Attributes/AllureEpicAttribute.cs | 12 ++++
.../Attributes/AllureFeatureAttribute.cs | 12 ++++
src/Allure.Net.Commons/Attributes/AllureId.cs | 12 ++++
.../Attributes/AllureIssueAttribute.cs | 11 ++-
.../Attributes/AllureLabelAttribute.cs | 9 +++
.../Attributes/AllureLabelAttributes.cs | 55 ---------------
.../Attributes/AllureLinkAttribute.cs | 13 +++-
.../Attributes/AllureMetaAttribute.cs | 6 +-
.../Attributes/AllureNameAttribute.cs | 11 ++-
.../Attributes/AllureOwner.cs | 12 ++++
.../Attributes/AllureParameterAttribute.cs | 5 +-
.../Attributes/AllureParentSuiteAttribute.cs | 12 ++++
.../Attributes/AllureSeverity.cs | 12 ++++
.../Attributes/AllureStepAttribute.cs | 5 ++
.../Attributes/AllureStoryAttribute.cs | 12 ++++
.../Attributes/AllureSubSuiteAttribute.cs | 12 ++++
.../Attributes/AllureSuiteAttribute.cs | 12 ++++
...hy.cs => AllureSuiteHierarchyAttribute.cs} | 2 +
.../Attributes/AllureTagAttribute.cs | 17 ++++-
.../Attributes/AllureTmsItemAttribute.cs | 11 ++-
.../Sdk/AllureMetadataAttribute.cs | 16 ++++-
.../BddHierarchyAttributeTests.cs | 69 +++++++++++++++++++
.../DescriptionAttributeTests.cs | 65 +++++++++++++++++
.../AttributeTests/EpicAttributeTests.cs | 15 ++++
.../AttributeTests/FeatureAttributeTests.cs | 15 ++++
.../AttributeTests/IssueAttributeTests.cs | 25 +++++++
.../AttributeTests/LabelAttributeTests.cs | 45 ++++++++++++
.../AttributeTests/LinkAttributeTests.cs | 25 +++++++
.../AttributeTests/MetaAttributeTests.cs | 3 +
.../AttributeTests/NameAttributeTests.cs | 25 +++++++
.../ParentSuiteAttributeTests.cs | 15 ++++
.../AttributeTests/StoryAttributeTests.cs | 15 ++++
.../AttributeTests/SubSuiteAttributeTests.cs | 15 ++++
.../AttributeTests/SuiteAttributeTests.cs | 15 ++++
.../SuiteHierarchyAttributeTests.cs | 15 ++++
.../AttributeTests/TagAttributeTests.cs | 35 ++++++++++
.../AttributeTests/TmsItemAttributeTests.cs | 25 +++++++
39 files changed, 656 insertions(+), 75 deletions(-)
rename src/Allure.Net.Commons/Attributes/{AllureBddHierarchy.cs => AllureBddHierarchyAttribute.cs} (94%)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureEpicAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureFeatureAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureId.cs
delete mode 100644 src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureOwner.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureParentSuiteAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureSeverity.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureStoryAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureSubSuiteAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureSuiteAttribute.cs
rename src/Allure.Net.Commons/Attributes/{AllureSuiteHierarchy.cs => AllureSuiteHierarchyAttribute.cs} (94%)
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
similarity index 94%
rename from src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
rename to src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
index d5c30d0a..39e2cdc5 100644
--- a/src/Allure.Net.Commons/Attributes/AllureBddHierarchy.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
@@ -1,3 +1,4 @@
+using System;
using Allure.Net.Commons.Sdk;
#nullable enable
@@ -7,6 +8,7 @@ namespace Allure.Net.Commons.Attributes;
///
/// Applies the whole BDD hierarchy at once.
///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
public class AllureBddHierarchyAttribute : AllureMetadataAttribute
{
string? Epic { get; init; }
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
index 5a295a8f..46c38f6e 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -1,22 +1,48 @@
using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
/// Applies a description.
///
/// A description text. Markdown is supported.
-[AttributeUsage(
- AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
- AllowMultiple = false,
- Inherited = true
-)]
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureDescriptionAttribute(string description) : AllureMetadataAttribute
{
+ ///
+ /// 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/structs before derived classes/structs.
+ /// - Classes/structs before methods.
+ /// - Base methods before method overrides.
+ ///
+ ///
+ public bool Append { get; init; }
+
///
public override void Apply(TestResult testResult)
{
- testResult.description = description;
+ if (description is null)
+ {
+ return;
+ }
+
+ if (this.Append && !string.IsNullOrEmpty(testResult.description))
+ {
+ testResult.description += $"\n\n{description}";
+ }
+ else
+ {
+ testResult.description = description;
+ }
}
}
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/AllureId.cs b/src/Allure.Net.Commons/Attributes/AllureId.cs
new file mode 100644
index 00000000..dcc56e6e
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureId.cs
@@ -0,0 +1,12 @@
+using System;
+
+#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 AllureId(string id)
+ : AllureLabelAttribute(LabelName.ALLURE_ID, id);
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
index 30da41bf..f047c8e7 100644
--- a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -1,5 +1,8 @@
+using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
@@ -9,16 +12,22 @@ namespace Allure.Net.Commons.Attributes;
/// 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) : AllureMetadataAttribute
{
///
/// A display text of the issue link.
///
- public string Title { get; set; }
+ public string? Title { get; set; }
///
public override void Apply(TestResult testResult)
{
+ if (issueIdOrUrl is null)
+ {
+ return;
+ }
+
testResult.links.Add(new()
{
url = issueIdOrUrl,
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
index 2ecd4375..c3da1756 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -1,5 +1,8 @@
+using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
@@ -7,11 +10,17 @@ namespace Allure.Net.Commons.Attributes;
///
/// A label's name.
/// A label's value.
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureLabelAttribute(string name, string value) : AllureMetadataAttribute
{
///
public override void Apply(TestResult testResult)
{
+ if (string.IsNullOrEmpty(name) || value is null)
+ {
+ return;
+ }
+
testResult.labels.Add(new() { name = name, value = value });
}
}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
deleted file mode 100644
index 36180f3f..00000000
--- a/src/Allure.Net.Commons/Attributes/AllureLabelAttributes.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-namespace Allure.Net.Commons.Attributes;
-
-///
-/// Applies a parentSuite label.
-///
-public class AllureParentSuiteAttribute(string parentSuite)
- : AllureLabelAttribute(LabelName.PARENT_SUITE, parentSuite);
-
-///
-/// Applies a suite label.
-///
-public class AllureSuiteAttribute(string suite)
- : AllureLabelAttribute(LabelName.SUITE, suite);
-
-///
-/// Applies a subSuite label.
-///
-public class AllureSubSuiteAttribute(string subSuite)
- : AllureLabelAttribute(LabelName.SUB_SUITE, subSuite);
-
-///
-/// Applies an epic label.
-///
-public class AllureEpicAttribute(string epic)
- : AllureLabelAttribute(LabelName.EPIC, epic);
-
-///
-/// Applies a feature label.
-///
-public class AllureFeatureAttribute(string feature)
- : AllureLabelAttribute(LabelName.FEATURE, feature);
-
-///
-/// Applies a story label.
-///
-public class AllureStoryAttribute(string story)
- : AllureLabelAttribute(LabelName.STORY, story);
-
-///
-/// Applies an Allure ID.
-///
-public class AllureId(string id)
- : AllureLabelAttribute(LabelName.ALLURE_ID, id);
-
-///
-/// Applies an owner label.
-///
-public class AllureOwner(string owner)
- : AllureLabelAttribute(LabelName.OWNER, owner);
-
-///
-/// Applies a severity label.
-///
-public class AllureSeverity(SeverityLevel severity)
- : AllureLabelAttribute(LabelName.SEVERITY, severity.ToString());
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
index 675608da..71d035c7 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -1,5 +1,8 @@
+using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
@@ -9,21 +12,27 @@ namespace Allure.Net.Commons.Attributes;
/// 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) : AllureMetadataAttribute
{
///
/// A display text of the link.
///
- public string Title { get; set; }
+ public string? Title { get; set; }
///
/// A type of the link.
///
- public string Type { get; set; }
+ public string? Type { get; set; }
///
public override void Apply(TestResult testResult)
{
+ if (url is null)
+ {
+ return;
+ }
+
testResult.links.Add(new()
{
url = url,
diff --git a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
index d94d8f12..e3a3b923 100644
--- a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -1,11 +1,15 @@
+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. Allows reducing boilerplate code.
+/// Applies all the attributes applied to its subclass, serving as a shortcut for them.
///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public abstract class AllureMetaAttribute : AllureMetadataAttribute
{
private readonly AllureMetadataAttribute[] attributes;
diff --git a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
index bbc891b3..a0e2d332 100644
--- a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -1,21 +1,26 @@
using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
-/// Applies a display name.
+/// Applies a display name to a test or a class.
///
[AttributeUsage(
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
AllowMultiple = false,
- Inherited = true
+ Inherited = false
)]
public class AllureNameAttribute(string name) : AllureMetadataAttribute
{
///
public override void Apply(TestResult testResult)
{
- testResult.name = name;
+ if (name is not null)
+ {
+ testResult.name = name;
+ }
}
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureOwner.cs b/src/Allure.Net.Commons/Attributes/AllureOwner.cs
new file mode 100644
index 00000000..858ee11f
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureOwner.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 AllureOwner(string owner)
+ : AllureLabelAttribute(LabelName.OWNER, owner);
diff --git a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
index d9099c97..ceeef026 100644
--- a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
@@ -7,7 +7,7 @@ namespace Allure.Net.Commons.Attributes;
///
/// Controls how Allure treats test and step parameters created from method arguments.
///
-[AttributeUsage(AttributeTargets.Parameter)]
+[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public class AllureParameterAttribute : Attribute
{
///
@@ -16,8 +16,7 @@ public class AllureParameterAttribute : Attribute
public bool Ignore { get; init; }
///
- /// A display name of the parameter. If set to null,
- /// the source name of the parameter will be used.
+ /// A display name of the parameter. If unset, the source name of the parameter will be used.
///
public string? Name { get; init; }
}
\ 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/AllureSeverity.cs b/src/Allure.Net.Commons/Attributes/AllureSeverity.cs
new file mode 100644
index 00000000..a2c17087
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureSeverity.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 AllureSeverity(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
index bfd595e3..7083030e 100644
--- a/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureStepAttribute.cs
@@ -1,8 +1,13 @@
+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
{
///
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/AllureSuiteHierarchy.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
similarity index 94%
rename from src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
rename to src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
index 1024de60..d2d7cded 100644
--- a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchy.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
@@ -1,3 +1,4 @@
+using System;
using Allure.Net.Commons.Sdk;
#nullable enable
@@ -7,6 +8,7 @@ namespace Allure.Net.Commons.Attributes;
///
/// Applies the whole suite hierarchy at once.
///
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
public class AllureSuiteHierarchyAttribute : AllureMetadataAttribute
{
string? ParentSuite { get; init; }
diff --git a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
index f0482406..cf6a839d 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -1,18 +1,31 @@
+using System;
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)
: AllureMetadataAttribute
{
///
public override void Apply(TestResult testResult)
{
- testResult.labels.Add(Label.Tag(tag));
- testResult.labels.AddRange(moreTags.Select(Label.Tag));
+ if (!string.IsNullOrEmpty(tag))
+ {
+ testResult.labels.Add(Label.Tag(tag));
+ }
+
+ testResult.labels.AddRange(
+ moreTags
+ .Where(static (v) =>
+ !string.IsNullOrEmpty(v))
+ .Select(Label.Tag)
+ );
}
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
index 945ce72e..9fe2b45d 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -1,5 +1,8 @@
+using System;
using Allure.Net.Commons.Sdk;
+#nullable enable
+
namespace Allure.Net.Commons.Attributes;
///
@@ -9,16 +12,22 @@ namespace Allure.Net.Commons.Attributes;
/// 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) : AllureMetadataAttribute
{
///
/// A display text of the TMS item link.
///
- public string Title { get; set; }
+ public string? Title { get; set; }
///
public override void Apply(TestResult testResult)
{
+ if (tmsItemIdOrUrl is null)
+ {
+ return;
+ }
+
testResult.links.Add(new()
{
url = tmsItemIdOrUrl,
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index 01edfd6e..b8d7d853 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -1,17 +1,31 @@
using System;
+#nullable enable
+
namespace Allure.Net.Commons.Sdk;
///
/// A base class for attributes that apply metadata to test results.
///
[AttributeUsage(
- AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
+ AttributeTargets.Class
+ | AttributeTargets.Struct
+ | AttributeTargets.Method
+ | AttributeTargets.Interface,
AllowMultiple = true,
Inherited = true
)]
public abstract class AllureMetadataAttribute : 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.
///
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
new file mode 100644
index 00000000..e41d4370
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
@@ -0,0 +1,69 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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();
+
+ new AllureBddHierarchyAttribute("foo").Apply(tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "feature", value = "foo" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void EpicAndFeatureCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureBddHierarchyAttribute("foo", "bar").Apply(tr);
+
+ 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();
+
+ new AllureBddHierarchyAttribute("foo", "bar", "baz").Apply(tr);
+
+ 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/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
index 14a57f00..1bccb2f0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
@@ -1,10 +1,26 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Sdk;
using NUnit.Framework;
namespace Allure.Net.Commons.Tests.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()
{
@@ -14,4 +30,53 @@ public void SetsTestDescription()
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/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
index c4ea897b..7a342837 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
index 3ae4f5c5..dfeade70 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
index 7f558c76..b3f0621f 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
@@ -35,4 +50,14 @@ public void IssueWithTitleCanBeAddedToTest()
.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/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
index 28482dfe..4325afeb 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
@@ -18,4 +33,34 @@ public void ItAddsLabelToTest()
.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/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
index 455e1ef3..5547e3b4 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
@@ -53,4 +68,14 @@ public void LinkWithUrlTitleAndTypeCanBeAddedToTest()
.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/AttributeTests/MetaAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
index 99809826..ce072c9b 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -9,6 +11,7 @@ class MetaAttributeTests
[AllureTag("foo")]
[AllureSuite("bar")]
[AllureIssue("foo", Title = "bar")]
+ [AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
class FooAttribute : AllureMetaAttribute { }
[Test]
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
index 2a246cc1..b7130ae5 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
@@ -14,4 +29,14 @@ public void ItSetsTestName()
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/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
index 970e104d..27fb91d8 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.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()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
index 3a01fb2c..867c6817 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class StoryAttributeTests
{
+ [AllureStory("foo")]
+ class TargetBase { }
+
+ [AllureStory("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
[Test]
public void StoryCanBeAddedToTest()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
index be2e51ec..13fe48f7 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class SubSuiteAttributeTests
{
+ [AllureSubSuite("foo")]
+ class TargetBase { }
+
+ [AllureSubSuite("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
[Test]
public void SubSuiteCanBeAddedToTest()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
index 6cf4a088..9d23fe96 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class SuiteAttributeTests
{
+ [AllureSuite("foo")]
+ class TargetBase { }
+
+ [AllureSuite("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
[Test]
public void SuiteCanBeAddedToTest()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
index fa60dfbf..7d07f723 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class SuiteHierarchyAttributeTests
{
+ [AllureSuiteHierarchy("foo")]
+ class TargetBase { }
+
+ [AllureSuiteHierarchy("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CantBeInherited()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(1).Items);
+ }
+
[Test]
public void SingleSuiteCanBeAddedToTest()
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
index 43324307..73a066a5 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class TagAttributeTests
{
+ [AllureTag("foo")]
+ class TargetBase { }
+
+ [AllureTag("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
[Test]
public void ItAddsSingleTagToTest()
{
@@ -35,4 +50,24 @@ public void ItAddsMultipleTagsToTest()
]).UsingPropertiesComparer()
);
}
+
+ [Test]
+ public void NullTagsAreIgnored()
+ {
+ TestResult tr = new();
+
+ new AllureTagAttribute(null, null, null).Apply(tr);
+
+ Assert.That(tr.labels, Is.Empty);
+ }
+
+ [Test]
+ public void EmptyTagsAreIgnored()
+ {
+ TestResult tr = new();
+
+ new AllureTagAttribute("", "", "").Apply(tr);
+
+ Assert.That(tr.labels, Is.Empty);
+ }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
index 3f725e2b..9604f095 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
@@ -1,3 +1,4 @@
+using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
@@ -5,6 +6,20 @@ namespace Allure.Net.Commons.Tests.AttributeTests;
class TmsItemAttributeTests
{
+ [AllureTmsItem("foo")]
+ class TargetBase { }
+
+ [AllureTmsItem("bar")]
+ class TargetDerived : TargetBase { }
+
+ [Test]
+ public void CanBeQueriedFromBaseAndInheritedClasses()
+ {
+ var typeAttributes = typeof(TargetDerived).GetCustomAttributes();
+
+ Assert.That(typeAttributes, Has.Exactly(2).Items);
+ }
+
[Test]
public void UrlOnlyTmsItemCanBeAddedToTest()
{
@@ -35,4 +50,14 @@ public void TmsItemWithTitleCanBeAddedToTest()
.UsingPropertiesComparer()
);
}
+
+ [Test]
+ public void DoesNothingIfUrlIsNull()
+ {
+ TestResult tr = new();
+
+ new AllureTmsItemAttribute(null).Apply(tr);
+
+ Assert.That(tr.links, Is.Empty);
+ }
}
From f9489a71540d0637d989a122fae98455f8ca8870 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 14:54:56 +0700
Subject: [PATCH 07/80] feat(commons): add attrs application functions
---
.../Sdk/AllureMetadataAttribute.cs | 65 ++++
.../AttributeApplicationTests.cs | 294 ++++++++++++++++++
2 files changed, 359 insertions(+)
create mode 100644 tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index b8d7d853..1e6274ed 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using System.Reflection;
#nullable enable
@@ -30,4 +32,67 @@ public const AttributeTargets ALLURE_METADATA_TARGETS
/// Applies the attribute to a test result.
///
public abstract void Apply(TestResult testResult);
+
+ ///
+ /// Applies metadata attributes of a and its base methods to
+ /// .
+ ///
+ public static void ApplyMethodAttributes(TestResult testResult, MethodInfo method)
+ {
+ var methodAttributes
+ = method
+ .GetCustomAttributes()
+ .Reverse();
+
+ foreach (var attr in methodAttributes)
+ {
+ attr.Apply(testResult);
+ }
+ }
+
+ ///
+ /// Applies metadata attributes of a , its base types, and implemented
+ /// interfaces to .
+ ///
+ public static void ApplyTypeAttributes(TestResult testResult, Type type)
+ {
+ var methodAttributes = type.GetCustomAttributes(true);
+
+ var interfaceAttributes
+ = type
+ .GetInterfaces()
+ .SelectMany(static (iFace) =>
+ iFace.GetCustomAttributes(true));
+
+ var allAttributes
+ = methodAttributes
+ .Concat(interfaceAttributes)
+ .Reverse();
+
+ foreach (var attr in allAttributes)
+ {
+ attr.Apply(testResult);
+ }
+ }
+
+ ///
+ /// Applies metadata attributes of a and its declaring type
+ /// to a test result.
+ ///
+ ///
+ /// Some applications are order-dependent (e.g., the application of
+ /// ). Here are the rules that define the
+ /// order:
+ ///
+ /// - Interfaces are handled before classes/structs.
+ /// - Base classes/structs are handled before derived classes/structs.
+ /// - Classes/structs are handled before methods
+ /// - Base methods are handled before methods overrides.
+ ///
+ ///
+ public static void ApplyAllAttributes(TestResult testResult, MethodInfo method)
+ {
+ ApplyTypeAttributes(testResult, method.DeclaringType);
+ ApplyMethodAttributes(testResult, method);
+ }
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs
new file mode 100644
index 00000000..4b70defd
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs
@@ -0,0 +1,294 @@
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
+using Allure.Net.Commons.Sdk;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests;
+
+class AttributeApplicationTests
+{
+ [Test]
+ public void DirectMethodAttributesAreApplied()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
+
+ AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+
+ 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));
+
+ AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+
+ 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));
+
+ AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+
+ 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));
+
+ AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+
+ Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
+ }
+
+ [Test]
+ public void DirectTypeAttributesAreApplied()
+ {
+ TestResult tr = new();
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(ClassWithAttrs));
+
+ 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();
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromClassAttributes));
+
+ 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();
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromInterfaceAttributes));
+
+ 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();
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(MultiSourceAttributes));
+
+ 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();
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(AttributeApplicationOrderChild));
+
+ Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
+ }
+
+ [Test]
+ public void ApplyAllAttributesToMethodAndItsTypeAtOnce()
+ {
+ TestResult tr = new();
+ var method = typeof(ApplyAllInherited)
+ .GetMethod(nameof(ApplyAllInherited.TargetMethod));
+
+ AllureMetadataAttribute.ApplyAllAttributes(tr, method);
+
+ 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()
+ );
+ }
+
+ #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 { }
+
+ #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
From ed6a6a4d2f54648d7a4fb023891361887742a03a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 15:03:36 +0700
Subject: [PATCH 08/80] test(nunit): rename legacy attr tests
---
tests/Allure.NUnit.Tests/CustomLabelTests.cs | 6 +++---
tests/Allure.NUnit.Tests/EpicTests.cs | 6 +++---
tests/Allure.NUnit.Tests/FeatureTests.cs | 6 +++---
tests/Allure.NUnit.Tests/ParameterTests.cs | 6 +++---
tests/Allure.NUnit.Tests/ParentSuiteTests.cs | 6 +++---
.../{ExcludedParameter.cs => AddExcludedParameter.cs} | 0
.../Samples/{HiddenParameter.cs => AddHiddenParameter.cs} | 0
.../Samples/{MaskedParameter.cs => AddMaskedParameter.cs} | 0
...buteOnBaseClass.cs => LegacyEpicAttributeOnBaseClass.cs} | 0
...picAttributeOnClass.cs => LegacyEpicAttributeOnClass.cs} | 0
...cAttributeOnMethod.cs => LegacyEpicAttributeOnMethod.cs} | 0
...eOnBaseClass.cs => LegacyFeatureAttributeOnBaseClass.cs} | 0
...AttributeOnClass.cs => LegacyFeatureAttributeOnClass.cs} | 0
...tributeOnMethod.cs => LegacyFeatureAttributeOnMethod.cs} | 0
...uteOnBaseClass.cs => LegacyLabelAttributeOnBaseClass.cs} | 0
...elAttributeOnClass.cs => LegacyLabelAttributeOnClass.cs} | 0
...AttributeOnMethod.cs => LegacyLabelAttributeOnMethod.cs} | 0
...aseClass.cs => LegacyParentSuiteAttributeOnBaseClass.cs} | 0
...ibuteOnClass.cs => LegacyParentSuiteAttributeOnClass.cs} | 0
...uteOnMethod.cs => LegacyParentSuiteAttributeOnMethod.cs} | 0
...uteOnBaseClass.cs => LegacyStoryAttributeOnBaseClass.cs} | 0
...ryAttributeOnClass.cs => LegacyStoryAttributeOnClass.cs} | 0
...AttributeOnMethod.cs => LegacyStoryAttributeOnMethod.cs} | 0
...OnBaseClass.cs => LegacySubSuiteAttributeOnBaseClass.cs} | 0
...ttributeOnClass.cs => LegacySubSuiteAttributeOnClass.cs} | 0
...ributeOnMethod.cs => LegacySubSuiteAttributeOnMethod.cs} | 0
...uteOnBaseClass.cs => LegacySuiteAttributeOnBaseClass.cs} | 0
...teAttributeOnClass.cs => LegacySuiteAttributeOnClass.cs} | 0
...AttributeOnMethod.cs => LegacySuiteAttributeOnMethod.cs} | 0
tests/Allure.NUnit.Tests/StoryTests.cs | 6 +++---
tests/Allure.NUnit.Tests/SubSuiteTests.cs | 6 +++---
tests/Allure.NUnit.Tests/SuiteTests.cs | 6 +++---
32 files changed, 24 insertions(+), 24 deletions(-)
rename tests/Allure.NUnit.Tests/Samples/{ExcludedParameter.cs => AddExcludedParameter.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{HiddenParameter.cs => AddHiddenParameter.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{MaskedParameter.cs => AddMaskedParameter.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{EpicAttributeOnBaseClass.cs => LegacyEpicAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{EpicAttributeOnClass.cs => LegacyEpicAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{EpicAttributeOnMethod.cs => LegacyEpicAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{FeatureAttributeOnBaseClass.cs => LegacyFeatureAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{FeatureAttributeOnClass.cs => LegacyFeatureAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{FeatureAttributeOnMethod.cs => LegacyFeatureAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{LabelAttributeOnBaseClass.cs => LegacyLabelAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{LabelAttributeOnClass.cs => LegacyLabelAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{LabelAttributeOnMethod.cs => LegacyLabelAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{ParentSuiteAttributeOnBaseClass.cs => LegacyParentSuiteAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{ParentSuiteAttributeOnClass.cs => LegacyParentSuiteAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{ParentSuiteAttributeOnMethod.cs => LegacyParentSuiteAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{StoryAttributeOnBaseClass.cs => LegacyStoryAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{StoryAttributeOnClass.cs => LegacyStoryAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{StoryAttributeOnMethod.cs => LegacyStoryAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SubSuiteAttributeOnBaseClass.cs => LegacySubSuiteAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SubSuiteAttributeOnClass.cs => LegacySubSuiteAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SubSuiteAttributeOnMethod.cs => LegacySubSuiteAttributeOnMethod.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SuiteAttributeOnBaseClass.cs => LegacySuiteAttributeOnBaseClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SuiteAttributeOnClass.cs => LegacySuiteAttributeOnClass.cs} (100%)
rename tests/Allure.NUnit.Tests/Samples/{SuiteAttributeOnMethod.cs => LegacySuiteAttributeOnMethod.cs} (100%)
diff --git a/tests/Allure.NUnit.Tests/CustomLabelTests.cs b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
index dcb158cb..d967ad28 100644
--- a/tests/Allure.NUnit.Tests/CustomLabelTests.cs
+++ b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
@@ -8,9 +8,9 @@ class CustomLabelTests
public static IEnumerable> GetCustomLabelSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LabelAttributeOnClass,
- AllureSampleRegistry.LabelAttributeOnMethod,
- AllureSampleRegistry.LabelAttributeOnBaseClass,
+ AllureSampleRegistry.LegacyLabelAttributeOnClass,
+ AllureSampleRegistry.LegacyLabelAttributeOnMethod,
+ AllureSampleRegistry.LegacyLabelAttributeOnBaseClass,
AllureSampleRegistry.AddLabelFromSetUp,
AllureSampleRegistry.AddLabelFromTest,
AllureSampleRegistry.AddLabelFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/EpicTests.cs b/tests/Allure.NUnit.Tests/EpicTests.cs
index 9c8048c0..e75b138d 100644
--- a/tests/Allure.NUnit.Tests/EpicTests.cs
+++ b/tests/Allure.NUnit.Tests/EpicTests.cs
@@ -8,9 +8,9 @@ class EpicTests
public static IEnumerable> GetEpicSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.EpicAttributeOnClass,
- AllureSampleRegistry.EpicAttributeOnMethod,
- AllureSampleRegistry.EpicAttributeOnBaseClass,
+ AllureSampleRegistry.LegacyEpicAttributeOnClass,
+ AllureSampleRegistry.LegacyEpicAttributeOnMethod,
+ AllureSampleRegistry.LegacyEpicAttributeOnBaseClass,
AllureSampleRegistry.AddEpicFromSetUp,
AllureSampleRegistry.AddEpicFromTest,
AllureSampleRegistry.AddEpicFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/FeatureTests.cs b/tests/Allure.NUnit.Tests/FeatureTests.cs
index 7ba02bb1..6c6d2804 100644
--- a/tests/Allure.NUnit.Tests/FeatureTests.cs
+++ b/tests/Allure.NUnit.Tests/FeatureTests.cs
@@ -8,9 +8,9 @@ class FeatureTests
public static IEnumerable> GetFeatureSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.FeatureAttributeOnClass,
- AllureSampleRegistry.FeatureAttributeOnMethod,
- AllureSampleRegistry.FeatureAttributeOnBaseClass,
+ AllureSampleRegistry.LegacyFeatureAttributeOnClass,
+ AllureSampleRegistry.LegacyFeatureAttributeOnMethod,
+ AllureSampleRegistry.LegacyFeatureAttributeOnBaseClass,
AllureSampleRegistry.AddFeatureFromSetUp,
AllureSampleRegistry.AddFeatureFromTest,
AllureSampleRegistry.AddFeatureFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/ParameterTests.cs b/tests/Allure.NUnit.Tests/ParameterTests.cs
index 722de25b..42c6f25b 100644
--- a/tests/Allure.NUnit.Tests/ParameterTests.cs
+++ b/tests/Allure.NUnit.Tests/ParameterTests.cs
@@ -34,7 +34,7 @@ await Assert.That(nodes).ContainsOnly(
[Test]
public async Task CheckMaskedParameter()
{
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.MaskedParameter);
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddMaskedParameter);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
@@ -47,7 +47,7 @@ await Assert.That(parameters).HasSingleItem().And.All(
[Test]
public async Task CheckHiddenParameter()
{
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.HiddenParameter);
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddHiddenParameter);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
@@ -60,7 +60,7 @@ await Assert.That(parameters).HasSingleItem().And.All(
[Test]
public async Task CheckExcludedParameter()
{
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.ExcludedParameter);
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddExcludedParameter);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(2);
diff --git a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
index 0463b822..8fd8ddcc 100644
--- a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
@@ -8,9 +8,9 @@ class ParentSuiteTests
public static IEnumerable> GetParentSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.ParentSuiteAttributeOnClass,
- AllureSampleRegistry.ParentSuiteAttributeOnMethod,
- AllureSampleRegistry.ParentSuiteAttributeOnBaseClass,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnClass,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacyParentSuiteAttributeOnBaseClass,
AllureSampleRegistry.AddParentSuiteFromSetUp,
AllureSampleRegistry.AddParentSuiteFromTest,
AllureSampleRegistry.AddParentSuiteFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/Samples/ExcludedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/ExcludedParameter.cs
rename to tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/HiddenParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/HiddenParameter.cs
rename to tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/MaskedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/MaskedParameter.cs
rename to tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
similarity index 100%
rename from tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
diff --git a/tests/Allure.NUnit.Tests/StoryTests.cs b/tests/Allure.NUnit.Tests/StoryTests.cs
index 0898b5bd..d98c89d8 100644
--- a/tests/Allure.NUnit.Tests/StoryTests.cs
+++ b/tests/Allure.NUnit.Tests/StoryTests.cs
@@ -8,9 +8,9 @@ class StoryTests
public static IEnumerable> GetStorySamples()
{
IEnumerable samples = [
- AllureSampleRegistry.StoryAttributeOnClass,
- AllureSampleRegistry.StoryAttributeOnMethod,
- AllureSampleRegistry.StoryAttributeOnBaseClass,
+ AllureSampleRegistry.LegacyStoryAttributeOnClass,
+ AllureSampleRegistry.LegacyStoryAttributeOnMethod,
+ AllureSampleRegistry.LegacyStoryAttributeOnBaseClass,
AllureSampleRegistry.AddStoryFromSetUp,
AllureSampleRegistry.AddStoryFromTest,
AllureSampleRegistry.AddStoryFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/SubSuiteTests.cs b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
index 78cbd896..b082142b 100644
--- a/tests/Allure.NUnit.Tests/SubSuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
@@ -8,9 +8,9 @@ class SubSuiteTests
public static IEnumerable> GetSubSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.SubSuiteAttributeOnClass,
- AllureSampleRegistry.SubSuiteAttributeOnMethod,
- AllureSampleRegistry.SubSuiteAttributeOnBaseClass,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnClass,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacySubSuiteAttributeOnBaseClass,
AllureSampleRegistry.AddSubSuiteFromSetUp,
AllureSampleRegistry.AddSubSuiteFromTest,
AllureSampleRegistry.AddSubSuiteFromTearDown,
diff --git a/tests/Allure.NUnit.Tests/SuiteTests.cs b/tests/Allure.NUnit.Tests/SuiteTests.cs
index 53e23b74..b6772836 100644
--- a/tests/Allure.NUnit.Tests/SuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/SuiteTests.cs
@@ -8,9 +8,9 @@ class SuiteTests
public static IEnumerable> GetSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.SuiteAttributeOnClass,
- AllureSampleRegistry.SuiteAttributeOnMethod,
- AllureSampleRegistry.SuiteAttributeOnBaseClass,
+ AllureSampleRegistry.LegacySuiteAttributeOnClass,
+ AllureSampleRegistry.LegacySuiteAttributeOnMethod,
+ AllureSampleRegistry.LegacySuiteAttributeOnBaseClass,
AllureSampleRegistry.AddSuiteFromSetUp,
AllureSampleRegistry.AddSuiteFromTest,
AllureSampleRegistry.AddSuiteFromTearDown,
From ac6f261b38a9eef62d3ecd96226dff84102d4c75 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 15:27:25 +0700
Subject: [PATCH 09/80] test(nunit): fix sample namespaces and formatting
---
tests/Allure.NUnit.Tests/Samples/AddEpicFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddEpicFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddEpicFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs | 3 +--
tests/Allure.NUnit.Tests/Samples/AddFeatureFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddFeatureFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddFeatureFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs | 4 +---
tests/Allure.NUnit.Tests/Samples/AddLabelFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddLabelFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddLabelFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs | 4 +---
tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromSetUp.cs | 1 -
.../Allure.NUnit.Tests/Samples/AddParentSuiteFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddParentSuiteFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddStoryFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddStoryFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddStoryFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSubSuiteFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSuiteFromSetUp.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSuiteFromTearDown.cs | 1 -
tests/Allure.NUnit.Tests/Samples/AddSuiteFromTest.cs | 1 -
tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs | 2 --
.../Samples/LegacyEpicAttributeOnBaseClass.cs | 4 +---
.../Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs | 4 +---
.../Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs | 4 +---
.../Samples/LegacyFeatureAttributeOnBaseClass.cs | 4 +---
.../Samples/LegacyFeatureAttributeOnClass.cs | 4 +---
.../Samples/LegacyFeatureAttributeOnMethod.cs | 4 +---
.../Samples/LegacyLabelAttributeOnBaseClass.cs | 4 +---
.../Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs | 4 +---
.../Samples/LegacyLabelAttributeOnMethod.cs | 4 +---
.../Samples/LegacyParentSuiteAttributeOnBaseClass.cs | 4 +---
.../Samples/LegacyParentSuiteAttributeOnClass.cs | 4 +---
.../Samples/LegacyParentSuiteAttributeOnMethod.cs | 4 +---
.../Samples/LegacyStoryAttributeOnBaseClass.cs | 4 +---
.../Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs | 4 +---
.../Samples/LegacyStoryAttributeOnMethod.cs | 4 +---
.../Samples/LegacySubSuiteAttributeOnBaseClass.cs | 4 +---
.../Samples/LegacySubSuiteAttributeOnClass.cs | 4 +---
.../Samples/LegacySubSuiteAttributeOnMethod.cs | 4 +---
.../Samples/LegacySuiteAttributeOnBaseClass.cs | 4 +---
.../Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs | 4 +---
.../Samples/LegacySuiteAttributeOnMethod.cs | 4 +---
.../Samples/OneNUnitTestCaseWithOneParameter.cs | 1 -
50 files changed, 24 insertions(+), 98 deletions(-)
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/AddExcludedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs
index bd9f2009..b2de9c9e 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.ExcludedParameter
+namespace Allure.NUnit.Tests.Samples.AddExcludedParameter
{
[AllureNUnit]
public class TestsClass
@@ -15,4 +15,3 @@ public void TestMethod(int _)
}
}
}
-
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/AddHiddenParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs
index d3bd1c20..88cc4467 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.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.AddHiddenParameter
{
[AllureNUnit]
public class TestsClass
@@ -14,4 +13,3 @@ public void TestMethod()
}
}
}
-
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/AddMaskedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs
index d56b9ace..02efc9ad 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.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.AddMaskedParameter
{
[AllureNUnit]
public class TestsClass
@@ -14,4 +13,3 @@ public void TestMethod()
}
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs
index 059ee425..9281692a 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs
@@ -16,4 +16,3 @@ public void SetUp()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs
index 18cad2be..3fbdfced 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs
@@ -16,4 +16,3 @@ public void TearDown()
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs
index 6d8afcbf..5cdc5480 100644
--- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs
+++ b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs
@@ -13,4 +13,3 @@ public void TestMethod()
}
}
}
-
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/DefaultStepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
index 256d56a5..e417906a 100644
--- a/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
+++ b/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
@@ -1,4 +1,3 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
@@ -17,4 +16,3 @@ public void TestMethod()
void Foo() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
index 3302b12b..b804c315 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.EpicAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnBaseClass
{
[AllureEpic("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
index 6c45d1ca..2992045f 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.EpicAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnClass
{
[AllureNUnit]
[AllureEpic("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
index a94c2cea..0db370e6 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.EpicAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacyEpicAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
index 58e0d1e6..f3034efb 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnBaseClass
{
[AllureFeature("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
index d2607b69..c2c224e8 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnClass
{
[AllureNUnit]
[AllureFeature("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
index b2dda642..a1410735 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacyFeatureAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
index 3f10acd8..9cfe3847 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.LabelAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnBaseClass
{
[AllureLabel("foo", "bar")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
index 45772662..80f6cc1a 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.LabelAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnClass
{
[AllureNUnit]
[AllureLabel("foo", "bar")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
index 2c1b8643..869d676d 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyLabelAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.LabelAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacyLabelAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
index 43640adb..63220b7c 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnBaseClass
{
[AllureParentSuite("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
index bcfc91a5..e6c4fff8 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnClass
{
[AllureNUnit]
[AllureParentSuite("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
index 5bd44328..f8ed583b 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyParentSuiteAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacyParentSuiteAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
index b2d8459d..4970add5 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.StoryAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnBaseClass
{
[AllureStory("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
index bf93a665..75ca271a 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.StoryAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnClass
{
[AllureNUnit]
[AllureStory("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
index f726c050..6306444e 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.StoryAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacyStoryAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
index 9699167c..f153d7cd 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnBaseClass
{
[AllureSubSuite("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
index 8a81d6ce..ece7d2f5 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnClass
{
[AllureNUnit]
[AllureSubSuite("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
index f84c61ef..813fcf29 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySubSuiteAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacySubSuiteAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
index a515f59d..66e28277 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnBaseClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnBaseClass
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnBaseClass
{
[AllureSuite("foo")]
public class BaseClass {}
@@ -14,4 +13,3 @@ public class TestsClass : BaseClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
index 356d3ab6..9c647f11 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnClass.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnClass
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnClass
{
[AllureNUnit]
[AllureSuite("foo")]
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
index 8eddbb5b..5ef649ad 100644
--- a/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LegacySuiteAttributeOnMethod.cs
@@ -1,8 +1,7 @@
-using Allure.Net.Commons;
using Allure.NUnit.Attributes;
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnMethod
+namespace Allure.NUnit.Tests.Samples.LegacySuiteAttributeOnMethod
{
[AllureNUnit]
public class TestsClass
@@ -12,4 +11,3 @@ public class TestsClass
public void TestMethod() { }
}
}
-
diff --git a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs b/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs
index cce4d34d..81e7d0bd 100644
--- a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs
+++ b/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs
@@ -10,4 +10,3 @@ public class TestsClass
public void TestMethod(string foo) { }
}
}
-
From 93ac6a7ebece7500dcdfbceedf7859df0f2f6a76 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 17:59:43 +0700
Subject: [PATCH 10/80] test(commons): move attr application tests
---
.../AttributeApplicationTests.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
rename tests/Allure.Net.Commons.Tests/{FunctionTests/ModelFunctionTests => AttributeTests}/AttributeApplicationTests.cs (98%)
diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
similarity index 98%
rename from tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs
rename to tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
index 4b70defd..fd1071d9 100644
--- a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
@@ -1,9 +1,8 @@
using Allure.Net.Commons.Attributes;
-using Allure.Net.Commons.Functions;
using Allure.Net.Commons.Sdk;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests;
+namespace Allure.Net.Commons.Tests.AttributeTests;
class AttributeApplicationTests
{
From e97d56c7d6d5f1911344b551afe410eb73be9a9e Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 18:00:22 +0700
Subject: [PATCH 11/80] feat(commons): add html description attr
---
.../AllureDescriptionHtmlAttribute.cs | 54 +++++++++++++++
.../DescriptionHtmlAttributeTests.cs | 69 +++++++++++++++++++
2 files changed, 123 insertions(+)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
new file mode 100644
index 00000000..b3e4a2b5
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
@@ -0,0 +1,54 @@
+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 HTML markup.
+[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
+public class AllureDescriptionHtmlAttribute(string descriptionHtml) : AllureMetadataAttribute
+{
+ ///
+ /// 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/structs before derived classes/structs.
+ /// - Classes/structs before methods.
+ /// - Base methods before method overrides.
+ ///
+ ///
+ public bool Append { get; init; }
+
+ ///
+ public override void Apply(TestResult testResult)
+ {
+ if (descriptionHtml is null)
+ {
+ return;
+ }
+
+ if (this.Append && testResult.descriptionHtml is not null)
+ {
+ testResult.descriptionHtml += descriptionHtml;
+ }
+ else
+ {
+ testResult.descriptionHtml = descriptionHtml;
+ }
+ }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
new file mode 100644
index 00000000..c22405ad
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
@@ -0,0 +1,69 @@
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Sdk;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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();
+
+ new AllureDescriptionHtmlAttribute("foo").Apply(tr);
+
+ 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
From 22b7907146291aaec87f79c9646e830eba158b2a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 21:21:48 +0700
Subject: [PATCH 12/80] fix(commons): rename some attribute classes
---
.../Attributes/{AllureId.cs => AllureIdAttribute.cs} | 7 +++++--
.../Attributes/{AllureOwner.cs => AllureOwnerAttribute.cs} | 2 +-
.../{AllureSeverity.cs => AllureSeverityAttribute.cs} | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
rename src/Allure.Net.Commons/Attributes/{AllureId.cs => AllureIdAttribute.cs} (56%)
rename src/Allure.Net.Commons/Attributes/{AllureOwner.cs => AllureOwnerAttribute.cs} (85%)
rename src/Allure.Net.Commons/Attributes/{AllureSeverity.cs => AllureSeverityAttribute.cs} (82%)
diff --git a/src/Allure.Net.Commons/Attributes/AllureId.cs b/src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs
similarity index 56%
rename from src/Allure.Net.Commons/Attributes/AllureId.cs
rename to src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs
index dcc56e6e..5047d6c6 100644
--- a/src/Allure.Net.Commons/Attributes/AllureId.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIdAttribute.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
#nullable enable
@@ -8,5 +9,7 @@ namespace Allure.Net.Commons.Attributes;
/// Sets an Allure ID. Can only be applied to methods.
///
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
-public class AllureId(string id)
- : AllureLabelAttribute(LabelName.ALLURE_ID, id);
+public class AllureIdAttribute(int id)
+ : AllureLabelAttribute(
+ LabelName.ALLURE_ID,
+ Convert.ToString(id, CultureInfo.InvariantCulture));
diff --git a/src/Allure.Net.Commons/Attributes/AllureOwner.cs b/src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs
similarity index 85%
rename from src/Allure.Net.Commons/Attributes/AllureOwner.cs
rename to src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs
index 858ee11f..55a20257 100644
--- a/src/Allure.Net.Commons/Attributes/AllureOwner.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureOwnerAttribute.cs
@@ -8,5 +8,5 @@ namespace Allure.Net.Commons.Attributes;
/// Applies an owner label.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
-public class AllureOwner(string owner)
+public class AllureOwnerAttribute(string owner)
: AllureLabelAttribute(LabelName.OWNER, owner);
diff --git a/src/Allure.Net.Commons/Attributes/AllureSeverity.cs b/src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs
similarity index 82%
rename from src/Allure.Net.Commons/Attributes/AllureSeverity.cs
rename to src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs
index a2c17087..a921a64e 100644
--- a/src/Allure.Net.Commons/Attributes/AllureSeverity.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureSeverityAttribute.cs
@@ -8,5 +8,5 @@ namespace Allure.Net.Commons.Attributes;
/// Applies a severity label.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
-public class AllureSeverity(SeverityLevel severity)
+public class AllureSeverityAttribute(SeverityLevel severity)
: AllureLabelAttribute(LabelName.SEVERITY, severity.ToString());
From 91cb2b5c12acda5947549a48e0b0633aa830376d Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 21:22:30 +0700
Subject: [PATCH 13/80] test(commons): add allure-id, owner, and severity tests
---
.../AttributeTests/AllureIdAttributeTests.cs | 21 +++++++++
.../AttributeTests/OwnerAttributeTests.cs | 47 +++++++++++++++++++
.../AttributeTests/SeverityAttributeTests.cs | 47 +++++++++++++++++++
3 files changed, 115 insertions(+)
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
new file mode 100644
index 00000000..4bb6aa77
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
@@ -0,0 +1,21 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.AttributeTests;
+
+class AllureIdAttributeTests
+{
+ [Test]
+ public void AllureIdCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureIdAttribute(1001).Apply(tr);
+
+ 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/AttributeTests/OwnerAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
new file mode 100644
index 00000000..190695f4
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
@@ -0,0 +1,47 @@
+using System.Linq;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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();
+
+ new AllureOwnerAttribute("John Doe").Apply(tr);
+
+ 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/AttributeTests/SeverityAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
new file mode 100644
index 00000000..fcfbb8fd
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
@@ -0,0 +1,47 @@
+using System.Linq;
+using System.Reflection;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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();
+
+ Assert.That(attrs, Has.Exactly(1).Items);
+
+ attrs.Single().Apply(tr);
+ var severities = tr.labels.FindAll(static (l) => l.name == "severity");
+
+ Assert.That(
+ severities,
+ Is.EqualTo([new Label { name = "severity", value = "blocker" }])
+ .UsingPropertiesComparer()
+ );
+ }
+
+ [Test]
+ public void SeverityCanBeAddedToTest()
+ {
+ TestResult tr = new();
+
+ new AllureSeverityAttribute(SeverityLevel.critical).Apply(tr);
+
+ Assert.That(
+ tr.labels,
+ Is.EquivalentTo([new Label { name = "severity", value = "critical" }])
+ .UsingPropertiesComparer()
+ );
+ }
+}
\ No newline at end of file
From b21b64bd1da536d85d224aeeab7cfdb54c52085a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 21:24:55 +0700
Subject: [PATCH 14/80] fix(nunit): reverse nunit description application
---
src/Allure.NUnit/Core/AllureNUnitHelper.cs | 76 +++++++++++++++-------
1 file changed, 52 insertions(+), 24 deletions(-)
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index e6b0eeb9..2d673863 100644
--- a/src/Allure.NUnit/Core/AllureNUnitHelper.cs
+++ b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
@@ -366,22 +366,48 @@ internal static void ApplyDefaultSuiteHierarchy(ITest test)
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}");
+ }
+ }
+
+ void ApplyNUnitAuthors()
+ {
+ foreach (var p in EnumerateTestProperties(PropertyNames.Author))
+ {
+ AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Owner(p)));
}
+ }
- foreach (var p in GetTestProperties(PropertyNames.Category))
+ void ApplyNUnitCategories()
+ {
+ foreach (var p in EnumerateTestProperties(PropertyNames.Category))
{
- AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Tag(p))
- );
+ AllureLifecycle.UpdateTestCase(x => x.labels.Add(Label.Tag(p)));
}
}
@@ -402,30 +428,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}";
From 21336955552b980170c6750ec179de400fd1f37d Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 28 Jan 2026 21:28:16 +0700
Subject: [PATCH 15/80] test(nunit): a bunch of tests on Allure API
---
.../Allure.NUnit.Tests.csproj | 2 +-
tests/Allure.NUnit.Tests/BddHierarchyTests.cs | 46 +++++++
tests/Allure.NUnit.Tests/CustomLabelTests.cs | 10 +-
tests/Allure.NUnit.Tests/DescriptionTests.cs | 114 ++++++++++++++++++
tests/Allure.NUnit.Tests/EpicTests.cs | 10 +-
tests/Allure.NUnit.Tests/FeatureTests.cs | 10 +-
tests/Allure.NUnit.Tests/ParentSuiteTests.cs | 10 +-
.../Samples/AddDescriptionFromSetUp.cs | 18 +++
.../Samples/AddDescriptionFromTearDown.cs | 18 +++
.../Samples/AddDescriptionFromTest.cs | 15 +++
.../Samples/AddDescriptionHtmlFromSetUp.cs | 18 +++
.../Samples/AddDescriptionHtmlFromTearDown.cs | 18 +++
.../Samples/AddDescriptionHtmlFromTest.cs | 15 +++
.../BddHierarchyAttributeOnBaseClass.cs | 15 +++
.../Samples/BddHierarchyAttributeOnClass.cs | 13 ++
.../BddHierarchyAttributeOnInterface.cs | 15 +++
.../Samples/BddHierarchyAttributeOnMethod.cs | 13 ++
.../Samples/DefaultStepAttributes.cs | 18 ---
.../DescriptionAttributeOnBaseClass.cs | 15 +++
.../Samples/DescriptionAttributeOnClass.cs | 13 ++
.../DescriptionAttributeOnInterface.cs | 15 +++
.../Samples/DescriptionAttributeOnMethod.cs | 13 ++
.../DescriptionHtmlAttributeOnBaseClass.cs | 15 +++
.../DescriptionHtmlAttributeOnClass.cs | 13 ++
.../DescriptionHtmlAttributeOnInterface.cs | 15 +++
.../DescriptionHtmlAttributeOnMethod.cs | 13 ++
.../Samples/EpicAttributeOnBaseClass.cs | 15 +++
.../Samples/EpicAttributeOnClass.cs | 13 ++
.../Samples/EpicAttributeOnInterface.cs | 15 +++
.../Samples/EpicAttributeOnMethod.cs | 13 ++
.../Samples/FeatureAttributeOnBaseClass.cs | 15 +++
.../Samples/FeatureAttributeOnClass.cs | 13 ++
.../Samples/FeatureAttributeOnInterface.cs | 15 +++
.../Samples/FeatureAttributeOnMethod.cs | 13 ++
.../Samples/LabelAttributeOnBaseClass.cs | 15 +++
.../Samples/LabelAttributeOnClass.cs | 13 ++
.../Samples/LabelAttributeOnInterface.cs | 15 +++
.../Samples/LabelAttributeOnMethod.cs | 13 ++
.../Samples/LegacyDescriptionAttribute.cs | 13 ++
.../Samples/LegacyDescriptionAttributeHtml.cs | 13 ++
.../Samples/LegacyStepAttributes.cs | 54 +++++++++
.../NUnitDescriptionAttributeComposition.cs | 13 ++
.../NUnitDescriptionAttributeOnClass.cs | 12 ++
.../NUnitDescriptionAttributeOnMethod.cs | 12 ++
.../NUnitDescriptionPropertyComposition.cs | 12 ++
.../NUnitDescriptionPropertyOnClass.cs | 12 ++
.../NUnitDescriptionPropertyOnMethod.cs | 11 ++
...escriptionPropertyWithAllureDescription.cs | 15 +++
...iptionPropertyWithAllureDescriptionHtml.cs | 15 +++
.../ParentSuiteAttributeOnBaseClass.cs | 15 +++
.../Samples/ParentSuiteAttributeOnClass.cs | 13 ++
.../ParentSuiteAttributeOnInterface.cs | 15 +++
.../Samples/ParentSuiteAttributeOnMethod.cs | 13 ++
.../Samples/StepAttributes.cs | 54 +++++++++
.../Samples/StoryAttributeOnBaseClass.cs | 15 +++
.../Samples/StoryAttributeOnClass.cs | 13 ++
.../Samples/StoryAttributeOnInterface.cs | 15 +++
.../Samples/StoryAttributeOnMethod.cs | 13 ++
.../Samples/SubSuiteAttributeOnBaseClass.cs | 15 +++
.../Samples/SubSuiteAttributeOnClass.cs | 13 ++
.../Samples/SubSuiteAttributeOnInterface.cs | 15 +++
.../Samples/SubSuiteAttributeOnMethod.cs | 13 ++
.../Samples/SuiteAttributeOnBaseClass.cs | 15 +++
.../Samples/SuiteAttributeOnClass.cs | 13 ++
.../Samples/SuiteAttributeOnInterface.cs | 15 +++
.../Samples/SuiteAttributeOnMethod.cs | 13 ++
.../SuiteHierarchyAttributeOnBaseClass.cs | 15 +++
.../Samples/SuiteHierarchyAttributeOnClass.cs | 13 ++
.../SuiteHierarchyAttributeOnInterface.cs | 15 +++
.../SuiteHierarchyAttributeOnMethod.cs | 13 ++
tests/Allure.NUnit.Tests/StepTests.cs | 96 +++++++++++++--
tests/Allure.NUnit.Tests/StoryTests.cs | 10 +-
tests/Allure.NUnit.Tests/SubSuiteTests.cs | 10 +-
.../Allure.NUnit.Tests/SuiteHierarchyTests.cs | 46 +++++++
tests/Allure.NUnit.Tests/SuiteTests.cs | 10 +-
75 files changed, 1295 insertions(+), 51 deletions(-)
create mode 100644 tests/Allure.NUnit.Tests/BddHierarchyTests.cs
create mode 100644 tests/Allure.NUnit.Tests/DescriptionTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromSetUp.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTearDown.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
delete mode 100644 tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/DescriptionHtmlAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/EpicAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LabelAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttribute.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyDescriptionAttributeHtml.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyStepAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeComposition.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescription.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyWithAllureDescriptionHtml.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/StepAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/StoryAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SuiteHierarchyAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
diff --git a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
index 6c0fd7b6..e58dd346 100644
--- a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
+++ b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/tests/Allure.NUnit.Tests/BddHierarchyTests.cs b/tests/Allure.NUnit.Tests/BddHierarchyTests.cs
new file mode 100644
index 00000000..dba2e6c1
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/BddHierarchyTests.cs
@@ -0,0 +1,46 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class BddHierarchyTests
+{
+ 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";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/CustomLabelTests.cs b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
index d967ad28..0503051d 100644
--- a/tests/Allure.NUnit.Tests/CustomLabelTests.cs
+++ b/tests/Allure.NUnit.Tests/CustomLabelTests.cs
@@ -8,12 +8,16 @@ class CustomLabelTests
public static IEnumerable> GetCustomLabelSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacyLabelAttributeOnClass,
- AllureSampleRegistry.LegacyLabelAttributeOnMethod,
- AllureSampleRegistry.LegacyLabelAttributeOnBaseClass,
+ 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..6b40fcdd
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/DescriptionTests.cs
@@ -0,0 +1,114 @@
+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.NUnitDescriptionPropertyOnMethod,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnClass,
+ 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 CheckHtmkDescriptionIsAdded(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");
+ }
+
+ public static IEnumerable> GetNUnitDescriptionCompositionSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.NUnitDescriptionAttributeComposition,
+ AllureSampleRegistry.NUnitDescriptionPropertyComposition,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetNUnitDescriptionCompositionSamples))]
+ public async Task NUnitDescriptionAttributeCompose(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\n\nDolor Sit Amet");
+ }
+
+ [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/EpicTests.cs b/tests/Allure.NUnit.Tests/EpicTests.cs
index e75b138d..58823054 100644
--- a/tests/Allure.NUnit.Tests/EpicTests.cs
+++ b/tests/Allure.NUnit.Tests/EpicTests.cs
@@ -8,12 +8,16 @@ class EpicTests
public static IEnumerable> GetEpicSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacyEpicAttributeOnClass,
- AllureSampleRegistry.LegacyEpicAttributeOnMethod,
- AllureSampleRegistry.LegacyEpicAttributeOnBaseClass,
+ 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) =>
diff --git a/tests/Allure.NUnit.Tests/FeatureTests.cs b/tests/Allure.NUnit.Tests/FeatureTests.cs
index 6c6d2804..fa3924d8 100644
--- a/tests/Allure.NUnit.Tests/FeatureTests.cs
+++ b/tests/Allure.NUnit.Tests/FeatureTests.cs
@@ -8,12 +8,16 @@ class FeatureTests
public static IEnumerable> GetFeatureSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacyFeatureAttributeOnClass,
- AllureSampleRegistry.LegacyFeatureAttributeOnMethod,
- AllureSampleRegistry.LegacyFeatureAttributeOnBaseClass,
+ 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) =>
diff --git a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
index 8fd8ddcc..b85f1b07 100644
--- a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
@@ -8,12 +8,16 @@ class ParentSuiteTests
public static IEnumerable> GetParentSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacyParentSuiteAttributeOnClass,
- AllureSampleRegistry.LegacyParentSuiteAttributeOnMethod,
- AllureSampleRegistry.LegacyParentSuiteAttributeOnBaseClass,
+ 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) =>
diff --git a/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
new file mode 100644
index 00000000..35676315
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromSetUp.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromSetUp
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ AllureApi.SetDescription("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
new file mode 100644
index 00000000..66c9ae10
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTearDown.cs
@@ -0,0 +1,18 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromTearDown
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ AllureApi.SetDescription("Lorem Ipsum");
+ }
+
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
new file mode 100644
index 00000000..1b7b79f9
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ 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/AddDescriptionHtmlFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
new file mode 100644
index 00000000..37c4186a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/AddDescriptionHtmlFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionHtmlFromTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
+ }
+ }
+}
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/DefaultStepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
deleted file mode 100644
index e417906a..00000000
--- a/tests/Allure.NUnit.Tests/Samples/DefaultStepAttributes.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Allure.NUnit.Attributes;
-using NUnit.Framework;
-
-namespace Allure.NUnit.Tests.Samples.DefaultStepAttributes
-{
- [AllureNUnit]
- public class TestsClass
- {
- [Test]
- public void TestMethod()
- {
- this.Foo();
- }
-
- [AllureStep]
- void Foo() { }
- }
-}
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
new file mode 100644
index 00000000..540cc06a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.EpicAttributeOnBaseClass
+{
+ [AllureEpic("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
new file mode 100644
index 00000000..8b57de13
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.EpicAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureEpic("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..410232c5
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/EpicAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.EpicAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureEpic("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
new file mode 100644
index 00000000..61491b25
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnBaseClass
+{
+ [AllureFeature("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
new file mode 100644
index 00000000..0946e61a
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureFeature("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..eba7a297
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/FeatureAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.FeatureAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureFeature("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
new file mode 100644
index 00000000..bd1a34aa
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LabelAttributeOnBaseClass
+{
+ [AllureLabel("foo", "bar")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
new file mode 100644
index 00000000..3cca54c6
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LabelAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureLabel("foo", "bar")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..4c0e7921
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/LabelAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.LabelAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureLabel("foo", "bar")]
+ 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/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/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..38f3b229
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyComposition
+{
+ [AllureNUnit]
+ [TestFixture(Description = "Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test(Description = "Dolor Sit Amet")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs
new file mode 100644
index 00000000..64ba2b37
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs
@@ -0,0 +1,12 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnClass
+{
+ [AllureNUnit]
+ [TestFixture(Description = "Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs
new file mode 100644
index 00000000..67c43115
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs
@@ -0,0 +1,11 @@
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test(Description = "Lorem Ipsum")]
+ 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/ParentSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..49beef32
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnBaseClass
+{
+ [AllureParentSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
new file mode 100644
index 00000000..d5e27573
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureParentSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..1e14a28c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/ParentSuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.ParentSuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureParentSuite("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs
new file mode 100644
index 00000000..95ba38b4
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs
@@ -0,0 +1,54 @@
+using System.Threading.Tasks;
+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, "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([AllureParameter(Ignore = true)] int foo) { }
+
+ [AllureStep]
+ void RenamedParameter([AllureParameter(Name = "Bar")] int foo) { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
new file mode 100644
index 00000000..5068c3f0
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.StoryAttributeOnBaseClass
+{
+ [AllureStory("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
new file mode 100644
index 00000000..723f5298
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.StoryAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureStory("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..97dd43d3
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/StoryAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.StoryAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureStory("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..08063af8
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnBaseClass
+{
+ [AllureSubSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
new file mode 100644
index 00000000..967f0873
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSubSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..2a31c4be
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SubSuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SubSuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSubSuite("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
new file mode 100644
index 00000000..5200555f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnBaseClass.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnBaseClass
+{
+ [AllureSuite("foo")]
+ public class BaseClass {}
+
+ [AllureNUnit]
+ public class TestsClass : BaseClass
+ {
+ [Test]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
new file mode 100644
index 00000000..34e44e85
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnClass.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnClass
+{
+ [AllureNUnit]
+ [AllureSuite("foo")]
+ public class TestsClass
+ {
+ [Test]
+ 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
new file mode 100644
index 00000000..ce463b8c
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SuiteAttributeOnMethod.cs
@@ -0,0 +1,13 @@
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SuiteAttributeOnMethod
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ [AllureSuite("foo")]
+ 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/StepTests.cs b/tests/Allure.NUnit.Tests/StepTests.cs
index 2f5d1b22..b365fe2f 100644
--- a/tests/Allure.NUnit.Tests/StepTests.cs
+++ b/tests/Allure.NUnit.Tests/StepTests.cs
@@ -5,22 +5,96 @@ namespace Allure.NUnit.Tests;
class StepTests
{
+ record class ParameterExpectations(string Name, string Value)
+ {
+ public bool Check(JsonObject parameter)
+ => (string)parameter["name"] == this.Name
+ && (string)parameter["value"] == this.Value;
+ public static bool CheckAll(
+ List expectations,
+ JsonArray parameters
+ )
+ => parameters.Count == expectations.Count
+ && parameters
+ .Zip(expectations)
+ .All(static (p) => p.Second.Check(p.First.AsObject()));
+ }
+
+ 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()));
+ }
+
+ public static IEnumerable> GetStepSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.StepAttributes,
+ AllureSampleRegistry.LegacyStepAttributes,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
[Test]
- public async Task CheckStepsFromAnnotatedMethodCalls()
+ [MethodDataSource(nameof(GetStepSamples))]
+ public async Task CheckStepsFromAnnotatedMethodCalls(AllureSampleRegistryEntry sample)
{
- var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.DefaultStepAttributes);
+ 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(1);
+ await Assert.That(steps).Count().IsEqualTo(8);
- 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("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
index d98c89d8..672e93d2 100644
--- a/tests/Allure.NUnit.Tests/StoryTests.cs
+++ b/tests/Allure.NUnit.Tests/StoryTests.cs
@@ -8,12 +8,16 @@ class StoryTests
public static IEnumerable> GetStorySamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacyStoryAttributeOnClass,
- AllureSampleRegistry.LegacyStoryAttributeOnMethod,
- AllureSampleRegistry.LegacyStoryAttributeOnBaseClass,
+ 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) =>
diff --git a/tests/Allure.NUnit.Tests/SubSuiteTests.cs b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
index b082142b..2f1346b6 100644
--- a/tests/Allure.NUnit.Tests/SubSuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
@@ -8,12 +8,16 @@ class SubSuiteTests
public static IEnumerable> GetSubSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacySubSuiteAttributeOnClass,
- AllureSampleRegistry.LegacySubSuiteAttributeOnMethod,
- AllureSampleRegistry.LegacySubSuiteAttributeOnBaseClass,
+ 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) =>
diff --git a/tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs b/tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
new file mode 100644
index 00000000..364809f3
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
@@ -0,0 +1,46 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class SuiteHierarchyTests
+{
+ 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";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.NUnit.Tests/SuiteTests.cs b/tests/Allure.NUnit.Tests/SuiteTests.cs
index b6772836..60466fce 100644
--- a/tests/Allure.NUnit.Tests/SuiteTests.cs
+++ b/tests/Allure.NUnit.Tests/SuiteTests.cs
@@ -8,12 +8,16 @@ class SuiteTests
public static IEnumerable> GetSuiteSamples()
{
IEnumerable samples = [
- AllureSampleRegistry.LegacySuiteAttributeOnClass,
- AllureSampleRegistry.LegacySuiteAttributeOnMethod,
- AllureSampleRegistry.LegacySuiteAttributeOnBaseClass,
+ 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) =>
From 3bdb5a564d5ebdf1743fbbc6b460f9ac0296575f Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 29 Jan 2026 17:26:25 +0700
Subject: [PATCH 16/80] test(nunit): consolidate bdd and suite label tests
---
tests/Allure.NUnit.Tests/BddHierarchyTests.cs | 46 ------
tests/Allure.NUnit.Tests/BddLabelTests.cs | 151 ++++++++++++++++++
tests/Allure.NUnit.Tests/EpicTests.cs | 42 -----
tests/Allure.NUnit.Tests/FeatureTests.cs | 42 -----
tests/Allure.NUnit.Tests/ParentSuiteTests.cs | 42 -----
tests/Allure.NUnit.Tests/StoryTests.cs | 42 -----
tests/Allure.NUnit.Tests/SubSuiteTests.cs | 42 -----
.../Allure.NUnit.Tests/SuiteHierarchyTests.cs | 46 ------
tests/Allure.NUnit.Tests/SuiteLabelTests.cs | 151 ++++++++++++++++++
tests/Allure.NUnit.Tests/SuiteTests.cs | 42 -----
10 files changed, 302 insertions(+), 344 deletions(-)
delete mode 100644 tests/Allure.NUnit.Tests/BddHierarchyTests.cs
create mode 100644 tests/Allure.NUnit.Tests/BddLabelTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/EpicTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/FeatureTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/ParentSuiteTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/StoryTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/SubSuiteTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
create mode 100644 tests/Allure.NUnit.Tests/SuiteLabelTests.cs
delete mode 100644 tests/Allure.NUnit.Tests/SuiteTests.cs
diff --git a/tests/Allure.NUnit.Tests/BddHierarchyTests.cs b/tests/Allure.NUnit.Tests/BddHierarchyTests.cs
deleted file mode 100644
index dba2e6c1..00000000
--- a/tests/Allure.NUnit.Tests/BddHierarchyTests.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class BddHierarchyTests
-{
- 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";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/BddLabelTests.cs b/tests/Allure.NUnit.Tests/BddLabelTests.cs
new file mode 100644
index 00000000..69ffb6d7
--- /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 BddHierarchyTests
+{
+ 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/EpicTests.cs b/tests/Allure.NUnit.Tests/EpicTests.cs
deleted file mode 100644
index 58823054..00000000
--- a/tests/Allure.NUnit.Tests/EpicTests.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class EpicTests
-{
- 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";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/FeatureTests.cs b/tests/Allure.NUnit.Tests/FeatureTests.cs
deleted file mode 100644
index fa3924d8..00000000
--- a/tests/Allure.NUnit.Tests/FeatureTests.cs
+++ /dev/null
@@ -1,42 +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.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";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs b/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
deleted file mode 100644
index b85f1b07..00000000
--- a/tests/Allure.NUnit.Tests/ParentSuiteTests.cs
+++ /dev/null
@@ -1,42 +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.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";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/StoryTests.cs b/tests/Allure.NUnit.Tests/StoryTests.cs
deleted file mode 100644
index 672e93d2..00000000
--- a/tests/Allure.NUnit.Tests/StoryTests.cs
+++ /dev/null
@@ -1,42 +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.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/SubSuiteTests.cs b/tests/Allure.NUnit.Tests/SubSuiteTests.cs
deleted file mode 100644
index 2f1346b6..00000000
--- a/tests/Allure.NUnit.Tests/SubSuiteTests.cs
+++ /dev/null
@@ -1,42 +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.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/SuiteHierarchyTests.cs b/tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
deleted file mode 100644
index 364809f3..00000000
--- a/tests/Allure.NUnit.Tests/SuiteHierarchyTests.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class SuiteHierarchyTests
-{
- 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";
- }
- );
- }
-}
diff --git a/tests/Allure.NUnit.Tests/SuiteLabelTests.cs b/tests/Allure.NUnit.Tests/SuiteLabelTests.cs
new file mode 100644
index 00000000..54e3cb11
--- /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 SuiteHierarchyTests
+{
+ 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/SuiteTests.cs b/tests/Allure.NUnit.Tests/SuiteTests.cs
deleted file mode 100644
index 60466fce..00000000
--- a/tests/Allure.NUnit.Tests/SuiteTests.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Text.Json.Nodes;
-using Allure.Testing;
-
-namespace Allure.NUnit.Tests;
-
-class SuiteTests
-{
- 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";
- }
- );
- }
-}
From be91517ed74087fec7a33de6a4cc6038c39276e0 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 29 Jan 2026 17:38:28 +0700
Subject: [PATCH 17/80] test(nunit): add allure id tests
---
tests/Allure.NUnit.Tests/AllureIdTests.cs | 37 +++++++++++++++++++
.../Samples/AllureIdAttributeOnMethod.cs | 13 +++++++
.../LegacyAllureIdAttributeOnMethod.cs | 13 +++++++
.../Samples/SetAllureIdFromSetUp.cs | 18 +++++++++
.../Samples/SetAllureIdFromTearDown.cs | 18 +++++++++
.../Samples/SetAllureIdFromTest.cs | 15 ++++++++
6 files changed, 114 insertions(+)
create mode 100644 tests/Allure.NUnit.Tests/AllureIdTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AllureIdAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetAllureIdFromSetUp.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTearDown.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
diff --git a/tests/Allure.NUnit.Tests/AllureIdTests.cs b/tests/Allure.NUnit.Tests/AllureIdTests.cs
new file mode 100644
index 00000000..75fff0c0
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/AllureIdTests.cs
@@ -0,0 +1,37 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.NUnit.Tests;
+
+class AllureIdTests
+{
+ public static IEnumerable> GetAllureIdSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SetAllureIdFromSetUp,
+ AllureSampleRegistry.SetAllureIdFromTest,
+ AllureSampleRegistry.SetAllureIdFromTearDown,
+ AllureSampleRegistry.AllureIdAttributeOnMethod,
+ AllureSampleRegistry.LegacyAllureIdAttributeOnMethod,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetAllureIdSamples))]
+ public async Task CheckAllureIdLabelIsAdded(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"] == "ALLURE_ID" && (string)l["value"] == "1001";
+ }
+ );
+ }
+}
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/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/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/SetAllureIdFromTest.cs b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
new file mode 100644
index 00000000..9f178798
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetAllureIdFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetAllureIdFromTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.SetAllureId(1001);
+ }
+ }
+}
From 15c8a76241cfee600f9e618b3dddc21371cdec6a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:22:32 +0700
Subject: [PATCH 18/80] test(nunit): add link tests
---
.../Attributes/AllureLinkAttribute.cs | 3 +-
tests/Allure.NUnit.Tests/LinkTests.cs | 81 +++++++++++++++++++
.../Samples/AddLinksAtRuntime.cs | 30 +++++++
.../Samples/LegacyLinkAttributes.cs | 17 ++++
.../Samples/LinkAttributes.cs | 20 +++++
5 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 tests/Allure.NUnit.Tests/LinkTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddLinksAtRuntime.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyLinkAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
index 71d035c7..190be60f 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -21,7 +21,8 @@ public class AllureLinkAttribute(string url) : AllureMetadataAttribute
public string? Title { get; set; }
///
- /// A type of the link.
+ /// A type of the link. Use this property to select the correct link template from the
+ /// configuration.
///
public string? Type { get; set; }
diff --git a/tests/Allure.NUnit.Tests/LinkTests.cs b/tests/Allure.NUnit.Tests/LinkTests.cs
new file mode 100644
index 00000000..36966c75
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/LinkTests.cs
@@ -0,0 +1,81 @@
+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 CheckLegacyLinkAttributesWork()
+ {
+ 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 CheckLinkAttributesWork()
+ {
+ 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");
+ }
+}
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/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/LinkAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
new file mode 100644
index 00000000..c411e6d2
--- /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 = "name-3")]
+ public class TestsClass : TestClassBase, IMetadata
+ {
+ [Test]
+ [AllureLink("url-4", Title = "name-4", Type = "type-4")]
+ public void TestMethod() { }
+ }
+}
From 4b1e2e1314ff37516499e687ea37e77b43ce9826 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 29 Jan 2026 20:13:46 +0700
Subject: [PATCH 19/80] test(nunit): add issue tests
---
tests/Allure.NUnit.Tests/LinkTests.cs | 66 +++++++++++++++++++
.../Samples/AddIssuesAtRuntime.cs | 27 ++++++++
.../Samples/IssueAttributes.cs | 20 ++++++
.../Samples/LegacyIssueAttributes.cs | 17 +++++
4 files changed, 130 insertions(+)
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddIssuesAtRuntime.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/IssueAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyIssueAttributes.cs
diff --git a/tests/Allure.NUnit.Tests/LinkTests.cs b/tests/Allure.NUnit.Tests/LinkTests.cs
index 36966c75..22133de7 100644
--- a/tests/Allure.NUnit.Tests/LinkTests.cs
+++ b/tests/Allure.NUnit.Tests/LinkTests.cs
@@ -78,4 +78,70 @@ await Assert.That(links[3]).Satisfies(static (l) =>
&& (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 CheckLegacyIssueAttributesWork()
+ {
+ 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 CheckIssueAttributesWork()
+ {
+ 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(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"
+ && l["name"] is null
+ && (string)l["type"] == "issue");
+ }
}
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/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/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() { }
+ }
+}
From 3252c4ca345c35a36fce695af2ef91c1f21ff48e Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 29 Jan 2026 20:34:37 +0700
Subject: [PATCH 20/80] test(nunit): add tms link tests
---
tests/Allure.NUnit.Tests/LinkTests.cs | 66 +++++++++++++++++++
.../Samples/AddTmsItemsAtRuntime.cs | 27 ++++++++
.../Samples/LegacyTmsAttributes.cs | 17 +++++
.../Samples/TmsItemAttributes.cs | 20 ++++++
4 files changed, 130 insertions(+)
create mode 100644 tests/Allure.NUnit.Tests/Samples/AddTmsItemsAtRuntime.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyTmsAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/TmsItemAttributes.cs
diff --git a/tests/Allure.NUnit.Tests/LinkTests.cs b/tests/Allure.NUnit.Tests/LinkTests.cs
index 22133de7..efa2d82d 100644
--- a/tests/Allure.NUnit.Tests/LinkTests.cs
+++ b/tests/Allure.NUnit.Tests/LinkTests.cs
@@ -144,4 +144,70 @@ await Assert.That(links[2]).Satisfies(static (l) =>
&& 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 CheckLegacyTmsAttributesWork()
+ {
+ 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 CheckTmsItemAttributesWork()
+ {
+ 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(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"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ }
}
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/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/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() { }
+ }
+}
From 526fb28d35f6cf443e8646880d26e7c842ab1e45 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 12:03:46 +0700
Subject: [PATCH 21/80] test(nunit): add display name tests
---
tests/Allure.NUnit.Tests/NameTests.cs | 51 +++++++++++++++++++
.../Samples/LegacyNameAttribute.cs | 13 +++++
.../Samples/NameAttributeOnClass.cs | 13 +++++
.../Samples/NameAttributeOnMethod.cs | 13 +++++
.../Samples/SetTestNameFromSetUp.cs | 18 +++++++
.../Samples/SetTestNameFromTearDown.cs | 18 +++++++
.../Samples/SetTestNameFromTest.cs | 15 ++++++
.../Samples/SingleTescCase.cs | 11 ++++
8 files changed, 152 insertions(+)
create mode 100644 tests/Allure.NUnit.Tests/NameTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyNameAttribute.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NameAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NameAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetTestNameFromSetUp.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetTestNameFromTearDown.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetTestNameFromTest.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SingleTescCase.cs
diff --git a/tests/Allure.NUnit.Tests/NameTests.cs b/tests/Allure.NUnit.Tests/NameTests.cs
new file mode 100644
index 00000000..d349b829
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/NameTests.cs
@@ -0,0 +1,51 @@
+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 CheckAllureNameAffectsSuite()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.NameAttributeOnClass);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var labels = results.TestResults[0]["labels"].AsArray().Cast();
+ var subSuiteLabel = labels.First(static (l) => (string)l["name"] == "subSuite");
+ await Assert.That((string)subSuiteLabel["value"]).IsEqualTo("Lorem Ipsum");
+ }
+}
\ No newline at end of file
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/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/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/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 _) { }
+ }
+}
From fcd837dd72a69a1d0d68204889191bac660a5f7e Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 12:28:21 +0700
Subject: [PATCH 22/80] test(nunit): make nunit description tests more complete
---
tests/Allure.NUnit.Tests/DescriptionTests.cs | 30 +++++++++++--------
.../NUnitDescriptionPropertyComposition.cs | 3 +-
...d.cs => NUnitDescriptionPropertyOnTest.cs} | 2 +-
.../NUnitDescriptionPropertyOnTestCase.cs | 11 +++++++
... NUnitDescriptionPropertyOnTestFixture.cs} | 2 +-
5 files changed, 32 insertions(+), 16 deletions(-)
rename tests/Allure.NUnit.Tests/Samples/{NUnitDescriptionPropertyOnMethod.cs => NUnitDescriptionPropertyOnTest.cs} (70%)
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestCase.cs
rename tests/Allure.NUnit.Tests/Samples/{NUnitDescriptionPropertyOnClass.cs => NUnitDescriptionPropertyOnTestFixture.cs} (71%)
diff --git a/tests/Allure.NUnit.Tests/DescriptionTests.cs b/tests/Allure.NUnit.Tests/DescriptionTests.cs
index 6b40fcdd..c394e18b 100644
--- a/tests/Allure.NUnit.Tests/DescriptionTests.cs
+++ b/tests/Allure.NUnit.Tests/DescriptionTests.cs
@@ -10,8 +10,9 @@ public static IEnumerable> GetCommonDescr
IEnumerable samples = [
AllureSampleRegistry.NUnitDescriptionAttributeOnMethod,
AllureSampleRegistry.NUnitDescriptionAttributeOnClass,
- AllureSampleRegistry.NUnitDescriptionPropertyOnMethod,
- AllureSampleRegistry.NUnitDescriptionPropertyOnClass,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTest,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTestCase,
+ AllureSampleRegistry.NUnitDescriptionPropertyOnTestFixture,
AllureSampleRegistry.DescriptionAttributeOnMethod,
AllureSampleRegistry.DescriptionAttributeOnClass,
AllureSampleRegistry.DescriptionAttributeOnBaseClass,
@@ -63,27 +64,30 @@ public async Task CheckHtmkDescriptionIsAdded(AllureSampleRegistryEntry sample)
await Assert.That((string)results.TestResults[0]["descriptionHtml"]).IsEqualTo("Lorem Ipsum");
}
- public static IEnumerable> GetNUnitDescriptionCompositionSamples()
+ [Test]
+ public async Task NUnitDescriptionAttributesCompose()
{
- IEnumerable samples = [
- AllureSampleRegistry.NUnitDescriptionAttributeComposition,
- AllureSampleRegistry.NUnitDescriptionPropertyComposition,
- ];
+ var results = await AllureSampleRunner.RunAsync(
+ AllureSampleRegistry.NUnitDescriptionAttributeComposition
+ );
- return samples.Select(static (sample) =>
- new TestDataRow(sample, DisplayName: sample.Id));
+ 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]
- [MethodDataSource(nameof(GetNUnitDescriptionCompositionSamples))]
- public async Task NUnitDescriptionAttributeCompose(AllureSampleRegistryEntry sample)
+ public async Task NUnitDescriptionPropertiesCompose()
{
- var results = await AllureSampleRunner.RunAsync(sample);
+ 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");
+ .IsEqualTo("Lorem Ipsum\n\nDolor Sit Amet\n\nConsectetur Adipiscing Elit");
}
[Test]
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
index 38f3b229..1eed5853 100644
--- a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyComposition.cs
@@ -7,6 +7,7 @@ namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyComposition
public class TestsClass
{
[Test(Description = "Dolor Sit Amet")]
- public void TestMethod() { }
+ [TestCase(1, Description = "Consectetur Adipiscing Elit")]
+ public void TestMethod(int _) { }
}
}
diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs
similarity index 70%
rename from tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs
rename to tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs
index 67c43115..90075057 100644
--- a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnMethod.cs
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTest.cs
@@ -1,6 +1,6 @@
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnMethod
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnTest
{
[AllureNUnit]
public class TestsClass
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/NUnitDescriptionPropertyOnClass.cs b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs
similarity index 71%
rename from tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs
rename to tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs
index 64ba2b37..e1b55932 100644
--- a/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnClass.cs
+++ b/tests/Allure.NUnit.Tests/Samples/NUnitDescriptionPropertyOnTestFixture.cs
@@ -1,6 +1,6 @@
using NUnit.Framework;
-namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnClass
+namespace Allure.NUnit.Tests.Samples.NUnitDescriptionPropertyOnTestFixture
{
[AllureNUnit]
[TestFixture(Description = "Lorem Ipsum")]
From e286c6fd66ea24cd72d99fbf978dd308cc51e5cb Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 12:28:35 +0700
Subject: [PATCH 23/80] test(nunit): add owner tests
---
tests/Allure.NUnit.Tests/OwnerTests.cs | 41 +++++++++++++++++++
.../LegacyOwnerAttributeOnBaseClass.cs | 15 +++++++
.../Samples/LegacyOwnerAttributeOnClass.cs | 13 ++++++
.../Samples/LegacyOwnerAttributeOnMethod.cs | 13 ++++++
.../Samples/NUnitAuthorPropertyOnTest.cs | 11 +++++
.../Samples/NUnitAuthorPropertyOnTestCase.cs | 11 +++++
.../NUnitAuthorPropertyOnTestFixture.cs | 12 ++++++
.../Samples/OwnerAttributeOnBaseClass.cs | 15 +++++++
.../Samples/OwnerAttributeOnClass.cs | 13 ++++++
.../Samples/OwnerAttributeOnInterface.cs | 15 +++++++
.../Samples/OwnerAttributeOnMethod.cs | 13 ++++++
.../Samples/SetOwnerFromSetUp.cs | 18 ++++++++
.../Samples/SetOwnerFromTearDown.cs | 18 ++++++++
.../Samples/SetOwnerFromTest.cs | 15 +++++++
14 files changed, 223 insertions(+)
create mode 100644 tests/Allure.NUnit.Tests/OwnerTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyOwnerAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTest.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestCase.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitAuthorPropertyOnTestFixture.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnBaseClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnClass.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnInterface.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/OwnerAttributeOnMethod.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetOwnerFromSetUp.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetOwnerFromTearDown.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
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/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/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/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/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/SetOwnerFromTest.cs b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
new file mode 100644
index 00000000..ca209d4f
--- /dev/null
+++ b/tests/Allure.NUnit.Tests/Samples/SetOwnerFromTest.cs
@@ -0,0 +1,15 @@
+using Allure.Net.Commons;
+using NUnit.Framework;
+
+namespace Allure.NUnit.Tests.Samples.SetOwnerFromTest
+{
+ [AllureNUnit]
+ public class TestsClass
+ {
+ [Test]
+ public void TestMethod()
+ {
+ AllureApi.SetOwner("John Doe");
+ }
+ }
+}
From c8c8bfdaa6d05cd2d58747c1316439f9fd991182 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 16:27:53 +0700
Subject: [PATCH 24/80] feat(commons): add CreateParameters
---
.../Attributes/AllureParameterAttribute.cs | 19 +-
.../Functions/ModelFunctions.cs | 55 ++++++
.../ModelFunctionTests/ParameterTests.cs | 184 ++++++++++++++++++
3 files changed, 257 insertions(+), 1 deletion(-)
create mode 100644 tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
index ceeef026..e687dee4 100644
--- a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs
@@ -13,10 +13,27 @@ public class AllureParameterAttribute : Attribute
///
/// If set to true, the argument will be precluded from the report.
///
- public bool Ignore { get; init; }
+ 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.
+ ///
+ public bool Excluded { get; init; } = false;
}
\ No newline at end of file
diff --git a/src/Allure.Net.Commons/Functions/ModelFunctions.cs b/src/Allure.Net.Commons/Functions/ModelFunctions.cs
index b27d6e23..8be3c952 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,59 @@ 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
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/structs before attributes of derived classes/structs.
+ ///
+ ///
+ ///
+ 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/structs before attributes of derived classes/structs.
+ ///
+ /// - 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(TestResult testResult, MethodInfo method)
{
- var methodAttributes
- = method
- .GetCustomAttributes()
- .Reverse();
-
- foreach (var attr in methodAttributes)
+ foreach (var attr in GetMethodAttributes(method))
{
attr.Apply(testResult);
}
@@ -54,22 +110,16 @@ var methodAttributes
/// 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/structs are handled before derived classes/structs.
+ ///
+ ///
public static void ApplyTypeAttributes(TestResult testResult, Type type)
{
- var methodAttributes = type.GetCustomAttributes(true);
-
- var interfaceAttributes
- = type
- .GetInterfaces()
- .SelectMany(static (iFace) =>
- iFace.GetCustomAttributes(true));
-
- var allAttributes
- = methodAttributes
- .Concat(interfaceAttributes)
- .Reverse();
-
- foreach (var attr in allAttributes)
+ foreach (var attr in GetTypeAttributes(type))
{
attr.Apply(testResult);
}
@@ -80,9 +130,7 @@ var allAttributes
/// to a test result.
///
///
- /// Some applications are order-dependent (e.g., the application of
- /// ). Here are the rules that define the
- /// order:
+ /// The following is guaranteed about the order of application:
///
/// - Interfaces are handled before classes/structs.
/// - Base classes/structs are handled before derived classes/structs.
@@ -92,7 +140,23 @@ var allAttributes
///
public static void ApplyAllAttributes(TestResult testResult, MethodInfo method)
{
- ApplyTypeAttributes(testResult, method.DeclaringType);
- ApplyMethodAttributes(testResult, method);
+ foreach (var attr in GetAllAttributes(method))
+ {
+ attr.Apply(testResult);
+ }
+ }
+
+ ///
+ /// Applies to .
+ ///
+ public static void ApplyAttributes(
+ TestResult testResult,
+ IEnumerable attributes
+ )
+ {
+ foreach (var attribute in attributes)
+ {
+ attribute.Apply(testResult);
+ }
}
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
index fd1071d9..0236edda 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
@@ -24,6 +24,25 @@ public void DirectMethodAttributesAreApplied()
);
}
+ [Test]
+ public void DirectMethodAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
+
+ var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -42,6 +61,25 @@ public void AbstractBaseAttributesAreApplies()
);
}
+ [Test]
+ public void AbstractBaseAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
+
+ var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -60,6 +98,25 @@ public void VirtualBaseAttributesAreApplies()
);
}
+ [Test]
+ public void VirtualBaseAttributesAreReturned()
+ {
+ TestResult tr = new();
+ var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
+
+ var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -72,6 +129,19 @@ public void AppliesBaseBeforeOverride()
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 = AllureMetadataAttribute.GetMethodAttributes(method);
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
+ }
+
[Test]
public void DirectTypeAttributesAreApplied()
{
@@ -89,6 +159,24 @@ public void DirectTypeAttributesAreApplied()
);
}
+ [Test]
+ public void DirectTypeAttributesAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(ClassWithAttrs));
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -106,6 +194,24 @@ public void AttributesFromBaseClassAreApplied()
);
}
+ [Test]
+ public void AttributesFromBaseClassAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(InheritedFromClassAttributes));
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -123,6 +229,24 @@ public void AttributesFromInterfaceAreApplied()
);
}
+ [Test]
+ public void AttributesFromInterfaceAreReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(InheritedFromInterfaceAttributes));
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -146,6 +270,30 @@ public void AttributesFromDifferentSourcesAreCombined()
);
}
+ [Test]
+ public void AttributesFromDifferentSourcesAreCombinedWhenReturned()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(MultiSourceAttributes));
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
{
@@ -157,7 +305,18 @@ public void CheckTypeAttributeApplicationOrder()
}
[Test]
- public void ApplyAllAttributesToMethodAndItsTypeAtOnce()
+ public void CheckTypeAttributeReturnOrder()
+ {
+ TestResult tr = new();
+
+ var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(AttributeApplicationOrderChild));
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
+ }
+
+ [Test]
+ public void AppliesAllAttributesToMethodAndItsTypeAtOnce()
{
TestResult tr = new();
var method = typeof(ApplyAllInherited)
@@ -187,6 +346,38 @@ public void ApplyAllAttributesToMethodAndItsTypeAtOnce()
);
}
+ [Test]
+ public void ReturnsAllAttributesToMethodAndItsTypeAtOnce()
+ {
+ TestResult tr = new();
+ var method = typeof(ApplyAllInherited)
+ .GetMethod(nameof(ApplyAllInherited.TargetMethod));
+
+ var attrs = AllureMetadataAttribute.GetAllAttributes(method);
+ AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+
+ 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()
+ );
+ }
+
#region Types to check attribute application to methods
abstract class MethodsWithAttrsBase
From f22d710a61eb6a00a7df955379074688abfc11de Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 23:06:44 +0700
Subject: [PATCH 35/80] feat(commons): support mode for step parameters
---
.../Steps/AllureStepParameterHelper.cs | 35 +++++++++++--------
.../AttributeTests/StepTests.cs | 34 +++++++++++++++++-
2 files changed, 54 insertions(+), 15 deletions(-)
diff --git a/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs b/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
index e0c23aa7..5f8bcda1 100644
--- a/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
+++ b/src/Allure.Net.Commons/Steps/AllureStepParameterHelper.cs
@@ -145,20 +145,24 @@ public static List GetStepParameters(
IReadOnlyDictionary formatters
)
{
- return metadata.GetParameters()
- .Select(x => (
- name: GetCustomParameterName(x) ?? x.Name,
- skip: ShouldParameterBeIgnored(x)))
- .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) =>
@@ -169,6 +173,9 @@ 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/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
index 39add60d..b92449e0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
@@ -119,7 +119,7 @@ public void InterpolatesParameterIntoStepName()
}
[Test]
- public void DoesntAddIgnoredParameters()
+ public void IgnoredParametersNotAdded()
{
var tr = new TestResult();
@@ -161,6 +161,32 @@ public void UsesOriginalParameterNameForInterpolation()
Assert.That(tr.steps[0].name, Is.EqualTo("\"baz\""));
}
+ [Test]
+ public void AppliesMaskedModeToParameter()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => MaskedParameter("foo")
+ );
+
+ Assert.That(tr.steps[0].parameters[0].mode, Is.EqualTo(ParameterMode.Masked));
+ }
+
+ [Test]
+ public void AppliesHiddenModeToParameter()
+ {
+ var tr = new TestResult();
+
+ AllureLifecycle.Instance.RunInContext(
+ new AllureContext().WithTestContext(tr),
+ () => HiddenParameter("foo")
+ );
+
+ Assert.That(tr.steps[0].parameters[0].mode, Is.EqualTo(ParameterMode.Hidden));
+ }
+
[AllureStep]
static void VoidMethod() { }
@@ -197,4 +223,10 @@ static void RenamedParameter([AllureParameter(Name = "bar")] string foo) { }
[AllureStep("{foo}")]
static void InterpolatedRenamedParameter([AllureParameter(Name = "bar")] string foo) { }
+
+ [AllureStep]
+ static void MaskedParameter([AllureParameter(Mode = ParameterMode.Masked)] string foo) { }
+
+ [AllureStep]
+ static void HiddenParameter([AllureParameter(Mode = ParameterMode.Hidden)] string foo) { }
}
\ No newline at end of file
From 949188b63fa8c5b43592307e95ce8874c810344b Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 23:07:46 +0700
Subject: [PATCH 36/80] test(nunit): fix tests
---
tests/Allure.NUnit.Tests/LinkTests.cs | 24 ++++++++++++-------
.../Allure.NUnit.Tests/MetaAttributeTests.cs | 2 +-
.../Samples/LinkAttributes.cs | 2 +-
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/tests/Allure.NUnit.Tests/LinkTests.cs b/tests/Allure.NUnit.Tests/LinkTests.cs
index efa2d82d..d3f54045 100644
--- a/tests/Allure.NUnit.Tests/LinkTests.cs
+++ b/tests/Allure.NUnit.Tests/LinkTests.cs
@@ -32,7 +32,7 @@ await Assert.That(links[3]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckLegacyLinkAttributesWork()
+ public async Task CheckLegacyLinkAttributeWorks()
{
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyLinkAttributes);
@@ -54,7 +54,7 @@ await Assert.That(links[2]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckLinkAttributesWork()
+ public async Task CheckLinkAttributeWorks()
{
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LinkAttributes);
@@ -102,7 +102,7 @@ await Assert.That(links[2]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckLegacyIssueAttributesWork()
+ public async Task CheckLegacyIssueAttributeWorks()
{
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyIssueAttributes);
@@ -124,13 +124,13 @@ await Assert.That(links[2]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckIssueAttributesWork()
+ 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(3);
+ await Assert.That(links.Count).IsEqualTo(4);
await Assert.That(links[0]).Satisfies(static (l) =>
(string)l["url"] == "url-1"
&& l["name"] is null
@@ -143,6 +143,10 @@ 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]
@@ -168,7 +172,7 @@ await Assert.That(links[2]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckLegacyTmsAttributesWork()
+ public async Task CheckLegacyTmsAttributeWorks()
{
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyTmsAttributes);
@@ -190,13 +194,13 @@ await Assert.That(links[2]).Satisfies(static (l) =>
}
[Test]
- public async Task CheckTmsItemAttributesWork()
+ 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(3);
+ await Assert.That(links.Count).IsEqualTo(4);
await Assert.That(links[0]).Satisfies(static (l) =>
(string)l["url"] == "url-1"
&& l["name"] is null
@@ -209,5 +213,9 @@ 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
index fd667626..fc756439 100644
--- a/tests/Allure.NUnit.Tests/MetaAttributeTests.cs
+++ b/tests/Allure.NUnit.Tests/MetaAttributeTests.cs
@@ -56,7 +56,7 @@ await Assert.That(labels).Any(
return (string)l["name"] == "suite" && (string)l["value"] == "Qux";
}
);
- await Assert.That(labels).Any(
+ await Assert.That(links).Any(
static (l) =>
(string)l["url"] == "https://foo.bar/"
&& l["name"] is null
diff --git a/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
index c411e6d2..357fa521 100644
--- a/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
+++ b/tests/Allure.NUnit.Tests/Samples/LinkAttributes.cs
@@ -10,7 +10,7 @@ public interface IMetadata { }
public class TestClassBase { }
[AllureNUnit]
- [AllureLink("url-3", Type = "name-3")]
+ [AllureLink("url-3", Type = "type-3")]
public class TestsClass : TestClassBase, IMetadata
{
[Test]
From ba2efd036b8cbc7be9f2997267dde79123fa5ad2 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 30 Jan 2026 23:46:34 +0700
Subject: [PATCH 37/80] feat(commons): add attr ctor args as props
---
.../Attributes/AllureBddHierarchyAttribute.cs | 17 ++++++++++++---
.../Attributes/AllureDescriptionAttribute.cs | 15 ++++++++-----
.../AllureDescriptionHtmlAttribute.cs | 15 ++++++++-----
.../Attributes/AllureIssueAttribute.cs | 9 ++++++--
.../Attributes/AllureLabelAttribute.cs | 14 +++++++++++--
.../Attributes/AllureLinkAttribute.cs | 13 ++++++++----
.../Attributes/AllureNameAttribute.cs | 9 ++++++--
.../AllureSuiteHierarchyAttribute.cs | 17 ++++++++++++---
.../Attributes/AllureTagAttribute.cs | 21 +++++++++++++------
.../Attributes/AllureTmsItemAttribute.cs | 9 ++++++--
.../AttributeTests/AllureIdAttributeTests.cs | 5 ++++-
.../BddHierarchyAttributeTests.cs | 18 +++++++++++++---
.../DescriptionAttributeTests.cs | 4 +++-
.../DescriptionHtmlAttributeTests.cs | 4 +++-
.../AttributeTests/EpicAttributeTests.cs | 5 ++++-
.../AttributeTests/FeatureAttributeTests.cs | 5 ++++-
.../AttributeTests/IssueAttributeTests.cs | 4 +++-
.../AttributeTests/LabelAttributeTests.cs | 5 ++++-
.../AttributeTests/LinkAttributeTests.cs | 4 +++-
.../AttributeTests/OwnerAttributeTests.cs | 5 ++++-
.../ParentSuiteAttributeTests.cs | 5 ++++-
.../AttributeTests/SeverityAttributeTests.cs | 5 ++++-
.../AttributeTests/StoryAttributeTests.cs | 5 ++++-
.../AttributeTests/SubSuiteAttributeTests.cs | 5 ++++-
.../AttributeTests/SuiteAttributeTests.cs | 5 ++++-
.../SuiteHierarchyAttributeTests.cs | 18 +++++++++++++---
.../AttributeTests/TagAttributeTests.cs | 16 ++++++++++----
.../AttributeTests/TmsItemAttributeTests.cs | 4 +++-
28 files changed, 202 insertions(+), 59 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
index 39e2cdc5..43a2c6c5 100644
--- a/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
@@ -11,9 +11,20 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
public class AllureBddHierarchyAttribute : AllureMetadataAttribute
{
- string? Epic { get; init; }
- string? Feature { get; init; }
- string? Story { get; init; }
+ ///
+ /// 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 ,
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
index 46c38f6e..7499bdb9 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -8,10 +8,15 @@ namespace Allure.Net.Commons.Attributes;
///
/// Applies a description.
///
-/// A description text. Markdown is supported.
+/// A description text. Markdown is supported.
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureDescriptionAttribute(string description) : AllureMetadataAttribute
+public class AllureDescriptionAttribute(string markdownText) : AllureMetadataAttribute
{
+ ///
+ /// 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.
@@ -31,18 +36,18 @@ public class AllureDescriptionAttribute(string description) : AllureMetadataAttr
///
public override void Apply(TestResult testResult)
{
- if (description is null)
+ if (this.MarkdownText is null)
{
return;
}
if (this.Append && !string.IsNullOrEmpty(testResult.description))
{
- testResult.description += $"\n\n{description}";
+ testResult.description += $"\n\n{this.MarkdownText}";
}
else
{
- testResult.description = description;
+ testResult.description = this.MarkdownText;
}
}
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
index b3e4a2b5..6a809ec6 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
@@ -11,10 +11,15 @@ namespace Allure.Net.Commons.Attributes;
///
/// Prefer , which supports markdown.
///
-/// A description HTML markup.
+/// A description text in HTML.
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureDescriptionHtmlAttribute(string descriptionHtml) : AllureMetadataAttribute
+public class AllureDescriptionHtmlAttribute(string htmlText) : AllureMetadataAttribute
{
+ ///
+ /// 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.
@@ -37,18 +42,18 @@ public class AllureDescriptionHtmlAttribute(string descriptionHtml) : AllureMeta
///
public override void Apply(TestResult testResult)
{
- if (descriptionHtml is null)
+ if (this.HtmlText is null)
{
return;
}
if (this.Append && testResult.descriptionHtml is not null)
{
- testResult.descriptionHtml += descriptionHtml;
+ testResult.descriptionHtml += this.HtmlText;
}
else
{
- testResult.descriptionHtml = descriptionHtml;
+ testResult.descriptionHtml = this.HtmlText;
}
}
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
index f047c8e7..ddf50914 100644
--- a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -15,6 +15,11 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
{
+ ///
+ /// The ID of the issue or its full URL.
+ ///
+ public string IdOrUrl { get; init; } = issueIdOrUrl;
+
///
/// A display text of the issue link.
///
@@ -23,14 +28,14 @@ public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
///
public override void Apply(TestResult testResult)
{
- if (issueIdOrUrl is null)
+ if (this.IdOrUrl is null)
{
return;
}
testResult.links.Add(new()
{
- url = issueIdOrUrl,
+ 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
index c3da1756..fa18e073 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -13,14 +13,24 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureLabelAttribute(string name, string value) : AllureMetadataAttribute
{
+ ///
+ /// 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(name) || value is null)
+ if (string.IsNullOrEmpty(this.Name) || this.Value is null)
{
return;
}
- testResult.labels.Add(new() { name = name, value = value });
+ 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
index 190be60f..2af6bcad 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -15,28 +15,33 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureLinkAttribute(string url) : AllureMetadataAttribute
{
+ ///
+ /// The URL of the link.
+ ///
+ public string Url { get; init; } = url;
+
///
/// A display text of the link.
///
- public string? Title { get; set; }
+ 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; set; }
+ public string? Type { get; init; }
///
public override void Apply(TestResult testResult)
{
- if (url is null)
+ if (this.Url is null)
{
return;
}
testResult.links.Add(new()
{
- url = url,
+ url = this.Url,
name = this.Title,
type = this.Type,
});
diff --git a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
index a0e2d332..96d331b4 100644
--- a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -15,12 +15,17 @@ namespace Allure.Net.Commons.Attributes;
)]
public class AllureNameAttribute(string name) : AllureMetadataAttribute
{
+ ///
+ /// The provided name.
+ ///
+ public string Name { get; init; } = name;
+
///
public override void Apply(TestResult testResult)
{
- if (name is not null)
+ if (this.Name is not null)
{
- testResult.name = name;
+ testResult.name = this.Name;
}
}
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
index d2d7cded..cf8936ee 100644
--- a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
@@ -11,9 +11,20 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
public class AllureSuiteHierarchyAttribute : AllureMetadataAttribute
{
- string? ParentSuite { get; init; }
- string? Suite { get; init; }
- string? SubSuite { get; init; }
+ ///
+ /// 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 ,
diff --git a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
index cf6a839d..ba845617 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Immutable;
using System.Linq;
using Allure.Net.Commons.Sdk;
@@ -13,19 +14,27 @@ namespace Allure.Net.Commons.Attributes;
public class AllureTagAttribute(string tag, params string[] moreTags)
: AllureMetadataAttribute
{
+ ///
+ /// The provided tags.
+ ///
+ public ImmutableArray Tags { get; init; } = CreateTagArray(tag, moreTags);
+
///
public override void Apply(TestResult testResult)
{
- if (!string.IsNullOrEmpty(tag))
- {
- testResult.labels.Add(Label.Tag(tag));
- }
-
testResult.labels.AddRange(
- moreTags
+ 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
index 9fe2b45d..2c95f7b6 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -15,6 +15,11 @@ namespace Allure.Net.Commons.Attributes;
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttribute
{
+ ///
+ /// The ID of the TMS item or its full URL.
+ ///
+ public string IdOrUrl { get; init; } = tmsItemIdOrUrl;
+
///
/// A display text of the TMS item link.
///
@@ -23,14 +28,14 @@ public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttri
///
public override void Apply(TestResult testResult)
{
- if (tmsItemIdOrUrl is null)
+ if (this.IdOrUrl is null)
{
return;
}
testResult.links.Add(new()
{
- url = tmsItemIdOrUrl,
+ url = this.IdOrUrl,
name = this.Title,
type = LinkType.TMS_ITEM,
});
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
index 4bb6aa77..517e87e0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
@@ -9,9 +9,12 @@ class AllureIdAttributeTests
public void AllureIdCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureIdAttribute(1001);
- new AllureIdAttribute(1001).Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
index e41d4370..604705b8 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
@@ -24,9 +24,13 @@ public void CantBeInherited()
public void SingleFeatureCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo");
- new AllureBddHierarchyAttribute("foo").Apply(tr);
+ 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" }])
@@ -38,9 +42,13 @@ public void SingleFeatureCanBeAddedToTest()
public void EpicAndFeatureCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo", "bar");
- new AllureBddHierarchyAttribute("foo", "bar").Apply(tr);
+ 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([
@@ -54,9 +62,13 @@ public void EpicAndFeatureCanBeAddedToTest()
public void EpicFeatureAndStoryCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureBddHierarchyAttribute("foo", "bar", "baz");
- new AllureBddHierarchyAttribute("foo", "bar", "baz").Apply(tr);
+ 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([
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
index 1bccb2f0..51552f33 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
@@ -25,9 +25,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void SetsTestDescription()
{
TestResult tr = new();
+ var attr = new AllureDescriptionAttribute("foo");
- new AllureDescriptionAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.MarkdownText, Is.EqualTo("foo"));
Assert.That(tr.description, Is.EqualTo("foo"));
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
index c22405ad..9c1be0ef 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
@@ -25,9 +25,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void SetsTestDescription()
{
TestResult tr = new();
+ var attr = new AllureDescriptionHtmlAttribute("foo");
- new AllureDescriptionHtmlAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.HtmlText, Is.EqualTo("foo"));
Assert.That(tr.descriptionHtml, Is.EqualTo("foo"));
}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
index 7a342837..7fd28682 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void EpicCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureEpicAttribute("foo");
- new AllureEpicAttribute("foo").Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
index dfeade70..b3ff95c9 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void FeatureCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureFeatureAttribute("foo");
- new AllureFeatureAttribute("foo").Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
index b3f0621f..ecd5f4e7 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
@@ -24,9 +24,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void UrlOnlyIssueCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureIssueAttribute("foo");
- new AllureIssueAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.IdOrUrl, Is.EqualTo("foo"));
Assert.That(
tr.links,
Is.EquivalentTo([new Link { url = "foo", type = "issue" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
index 4325afeb..4e1279bf 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void ItAddsLabelToTest()
{
TestResult tr = new();
+ var attr = new AllureLabelAttribute("foo", "bar");
- new AllureLabelAttribute("foo", "bar").Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
index 5547e3b4..95a72b18 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
@@ -24,9 +24,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void UrlOnlyLinkCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureLinkAttribute("foo");
- new AllureLinkAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Url, Is.EqualTo("foo"));
Assert.That(
tr.links,
Is.EquivalentTo([new Link { url = "foo" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
index 190695f4..c26eaa42 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
@@ -35,9 +35,12 @@ public void OwnerOfTheMostDerivedClassQueried()
public void OwnerCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureOwnerAttribute("John Doe");
- new AllureOwnerAttribute("John Doe").Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
index 27fb91d8..dee3cefa 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void ParentSuiteCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureParentSuiteAttribute("foo");
- new AllureParentSuiteAttribute("foo").Apply(tr);
+ 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" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
index fcfbb8fd..55039578 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
@@ -35,9 +35,12 @@ public void SeverityOfTheMostDerivedClassQueried()
public void SeverityCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSeverityAttribute(SeverityLevel.critical);
- new AllureSeverityAttribute(SeverityLevel.critical).Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Name, Is.EqualTo("severity"));
+ Assert.That(attr.Value, Is.EqualTo("critical"));
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "severity", value = "critical" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
index 867c6817..bf6bcea0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void StoryCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureStoryAttribute("foo");
- new AllureStoryAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Name, Is.EqualTo("story"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "story", value = "foo" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
index 13fe48f7..f49e8edf 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void SubSuiteCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSubSuiteAttribute("foo");
- new AllureSubSuiteAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Name, Is.EqualTo("subSuite"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "subSuite", value = "foo" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
index 9d23fe96..52abff7c 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
@@ -24,9 +24,12 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void SuiteCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSuiteAttribute("foo");
- new AllureSuiteAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Name, Is.EqualTo("suite"));
+ Assert.That(attr.Value, Is.EqualTo("foo"));
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
index 7d07f723..896530ba 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
@@ -24,9 +24,13 @@ public void CantBeInherited()
public void SingleSuiteCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSuiteHierarchyAttribute("foo");
- new AllureSuiteHierarchyAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.ParentSuite, Is.Null);
+ Assert.That(attr.Suite, Is.EqualTo("foo"));
+ Assert.That(attr.SubSuite, Is.Null);
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "suite", value = "foo" }])
@@ -38,9 +42,13 @@ public void SingleSuiteCanBeAddedToTest()
public void TwoLevelSuiteHierarchyCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSuiteHierarchyAttribute("foo", "bar");
- new AllureSuiteHierarchyAttribute("foo", "bar").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.ParentSuite, Is.EqualTo("foo"));
+ Assert.That(attr.Suite, Is.EqualTo("bar"));
+ Assert.That(attr.SubSuite, Is.Null);
Assert.That(
tr.labels,
Is.EquivalentTo([
@@ -54,9 +62,13 @@ public void TwoLevelSuiteHierarchyCanBeAddedToTest()
public void ThreeLevelSuiteHierarchyCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureSuiteHierarchyAttribute("foo", "bar", "baz");
- new AllureSuiteHierarchyAttribute("foo", "bar", "baz").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.ParentSuite, Is.EqualTo("foo"));
+ Assert.That(attr.Suite, Is.EqualTo("bar"));
+ Assert.That(attr.SubSuite, Is.EqualTo("baz"));
Assert.That(
tr.labels,
Is.EquivalentTo([
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
index 73a066a5..d952b299 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
@@ -24,9 +24,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void ItAddsSingleTagToTest()
{
TestResult tr = new();
+ var attr = new AllureTagAttribute("foo");
- new AllureTagAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Tags, Is.EqualTo(["foo"]));
Assert.That(
tr.labels,
Is.EquivalentTo([new Label { name = "tag", value = "foo" }])
@@ -38,9 +40,11 @@ public void ItAddsSingleTagToTest()
public void ItAddsMultipleTagsToTest()
{
TestResult tr = new();
+ var attr = new AllureTagAttribute("foo", "bar", "baz");
- new AllureTagAttribute("foo", "bar", "baz").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Tags, Is.EqualTo(["foo", "bar", "baz"]));
Assert.That(
tr.labels,
Is.EquivalentTo([
@@ -55,9 +59,11 @@ public void ItAddsMultipleTagsToTest()
public void NullTagsAreIgnored()
{
TestResult tr = new();
+ var attr = new AllureTagAttribute(null, null, null);
- new AllureTagAttribute(null, null, null).Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Tags, Is.EqualTo(new string[]{ null, null, null }));
Assert.That(tr.labels, Is.Empty);
}
@@ -65,9 +71,11 @@ public void NullTagsAreIgnored()
public void EmptyTagsAreIgnored()
{
TestResult tr = new();
+ var attr = new AllureTagAttribute("", "", "");
- new AllureTagAttribute("", "", "").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.Tags, Is.EqualTo(["", "", ""]));
Assert.That(tr.labels, Is.Empty);
}
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
index 9604f095..9b11fa26 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
@@ -24,9 +24,11 @@ public void CanBeQueriedFromBaseAndInheritedClasses()
public void UrlOnlyTmsItemCanBeAddedToTest()
{
TestResult tr = new();
+ var attr = new AllureTmsItemAttribute("foo");
- new AllureTmsItemAttribute("foo").Apply(tr);
+ attr.Apply(tr);
+ Assert.That(attr.IdOrUrl, Is.EqualTo("foo"));
Assert.That(
tr.links,
Is.EquivalentTo([new Link { url = "foo", type = "tms" }])
From 8648d7a9aeebfdf1b84799cacefe07582da6188d Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 00:11:41 +0700
Subject: [PATCH 38/80] feat(nunit): add support for attribute API
---
src/Allure.NUnit/Core/AllureNUnitHelper.cs | 62 +++++++++++++---------
tests/Allure.NUnit.Tests/NameTests.cs | 11 +++-
2 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index 2d673863..408f83b5 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,28 @@ 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;
+ var testFixtureAttributes
+ = AllureMetadataAttribute
+ .GetTypeAttributes(testFixtureClass)
+ .Where(static (a) => a is not AllureNameAttribute);
+
+ AllureMetadataAttribute.ApplyAttributes(testResult, testFixtureAttributes);
+ AllureMetadataAttribute.ApplyMethodAttributes(testResult, test.Method.MethodInfo);
+ }
- static void UpdateTestDataFromAllureAttributes(ITest test, TestResult testResult)
+ static void ApplyLegacyAllureAttributes(ITest test, TestResult testResult)
{
foreach (var attribute in IterateAllAllureAttribites(test))
{
@@ -290,12 +293,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 +312,14 @@ static string GetNamespace(string classFullName)
);
}
+ static string ResolveSubSuite(TestFixture testFixture)
+ => AllureMetadataAttribute
+ .GetTypeAttributes(testFixture.TypeInfo.Type)
+ .OfType()
+ .LastOrDefault()
+ ?.Name
+ ?? GetClassName(testFixture.FullName);
+
static string GetClassName(string classFullName)
{
var lastDotIndex = StripTypeArgs(classFullName)?.LastIndexOf('.') ?? -1;
@@ -349,17 +360,18 @@ 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
)
);
}
diff --git a/tests/Allure.NUnit.Tests/NameTests.cs b/tests/Allure.NUnit.Tests/NameTests.cs
index d349b829..e27bbe97 100644
--- a/tests/Allure.NUnit.Tests/NameTests.cs
+++ b/tests/Allure.NUnit.Tests/NameTests.cs
@@ -39,13 +39,20 @@ public async Task MethodNameIsUsedForTestCases()
}
[Test]
- public async Task CheckAllureNameAffectsSuite()
+ public async Task CheckAllureNameOnTestFixtureAffectsSuiteOnly()
{
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.NameAttributeOnClass);
await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
- var labels = results.TestResults[0]["labels"].AsArray().Cast();
+ 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
From d52a8e89fe85b63e746e9cb802c389c4be5efd14 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 00:38:26 +0700
Subject: [PATCH 39/80] fix(commons): remove AttributeUsage from abstract attrs
---
src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs | 1 -
src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs | 9 ---------
2 files changed, 10 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
index e3a3b923..8d2966f3 100644
--- a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -9,7 +9,6 @@ namespace Allure.Net.Commons.Attributes;
///
/// Applies all the attributes applied to its subclass, serving as a shortcut for them.
///
-[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public abstract class AllureMetaAttribute : AllureMetadataAttribute
{
private readonly AllureMetadataAttribute[] attributes;
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index 2a2d44d4..44cce58d 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -11,14 +10,6 @@ namespace Allure.Net.Commons.Sdk;
///
/// A base class for attributes that apply metadata to test results.
///
-[AttributeUsage(
- AttributeTargets.Class
- | AttributeTargets.Struct
- | AttributeTargets.Method
- | AttributeTargets.Interface,
- AllowMultiple = true,
- Inherited = true
-)]
public abstract class AllureMetadataAttribute : Attribute
{
///
From d69186231e41b38d28bafbc3e20d2f23f822c915 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 00:56:10 +0700
Subject: [PATCH 40/80] feat(xunit): add support for attribute API
---
src/Allure.Xunit/AllureXunitHelper.cs | 70 ++++++++++++++++++---------
1 file changed, 46 insertions(+), 24 deletions(-)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index 31637644..30c95287 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -3,8 +3,9 @@
using System.Collections.Generic;
using System.Linq;
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;
@@ -117,21 +118,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 : AllureMetadataAttribute
+ .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 +187,8 @@ string displayName
]
};
SetTestResultIdentifiers(testCase, displayName, testResult);
- UpdateTestDataFromAttributes(testResult, testMethod);
+ ApplyLegacyAllureAttributes(testResult, testMethod);
+ ApplyAllureAttributes(testResult, testMethod);
return testResult;
}
@@ -243,23 +252,36 @@ 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();
+ var testClassAttributes
+ = AllureMetadataAttribute
+ .GetTypeAttributes(testClass)
+ .Where(static (a) => a is not AllureNameAttribute);
+
+ AllureMetadataAttribute.ApplyAttributes(testResult, testClassAttributes);
+ AllureMetadataAttribute.ApplyMethodAttributes(testResult, method);
+ }
+
+ 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 +289,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 +333,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 +355,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 +368,7 @@ ITestMethod method
testResult.labels.AddDistinct(allureIdLabel, false);
break;
- case AllureLabelAttribute labelAttribute:
+ case Attributes.AllureLabelAttribute labelAttribute:
var label = new Label()
{
name = labelAttribute.Label,
From edb3da9ff6c8fa7cc59ebb8d3db665aced68ba98 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 01:42:53 +0700
Subject: [PATCH 41/80] feat(commons): add before and after attrs
---
.../Attributes/AllureAfterAttribute.cs | 27 ++
.../Attributes/AllureBeforeAttribute.cs | 27 ++
.../AttributeTests/AfterFixtureTests.cs | 231 +++++++++++++++
.../AttributeTests/BeforeFixtureTests.cs | 276 ++++++++++++++++++
.../AttributeTests/StepTests.cs | 1 -
5 files changed, 561 insertions(+), 1 deletion(-)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureAfterAttribute.cs
create mode 100644 src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs
create mode 100644 tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs
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/AllureBeforeAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
new file mode 100644
index 00000000..6d329b95
--- /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 set up 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 set up 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 set up fixture.
+ ///
+ ///
+ /// A name of the fixture. Use the {paramName} placeholders to interpolate the
+ /// arguments.
+ ///
+ public AllureBeforeAttribute(string name) : base(name) { }
+}
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs
new file mode 100644
index 00000000..3b7ae501
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs
@@ -0,0 +1,231 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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/AttributeTests/BeforeFixtureTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs
new file mode 100644
index 00000000..8110d0e9
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs
@@ -0,0 +1,276 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+using NUnit.Framework;
+
+namespace Allure.Net.Commons.Tests.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/AttributeTests/StepTests.cs b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
index b92449e0..531a0006 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
+++ b/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using Allure.Net.Commons.Attributes;
-using Allure.Net.Commons.Steps;
using NUnit.Framework;
namespace Allure.Net.Commons.Tests.AttributeTests;
From 88bf93219718239db4b36cf7dcca1c32bb2b55dd Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 01:45:01 +0700
Subject: [PATCH 42/80] feat(commons): allow fixture parameters
---
.../Steps/AllureStepAspect.cs | 35 ++++++++++++++-----
1 file changed, 26 insertions(+), 9 deletions(-)
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(
From d71d9a934ba9a043dd92fb95b2bb88d38f1c3a5a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Sat, 31 Jan 2026 03:03:50 +0700
Subject: [PATCH 43/80] test(nunit): test fixture attrs
---
.../Allure.NUnit.Tests.csproj | 5 +-
tests/Allure.NUnit.Tests/FixtureTests.cs | 78 +++++++++++++++++++
.../Samples/FixtureAttributes.cs | 29 +++++++
.../Samples/LegacyFixtureAttributes.cs | 29 +++++++
tests/Allure.NUnit.Tests/StepTests.cs | 4 +-
5 files changed, 142 insertions(+), 3 deletions(-)
create mode 100644 tests/Allure.NUnit.Tests/FixtureTests.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/FixtureAttributes.cs
create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyFixtureAttributes.cs
diff --git a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj
index 4b91a6ea..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/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/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/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/StepTests.cs b/tests/Allure.NUnit.Tests/StepTests.cs
index 0cc531af..9fd38a3c 100644
--- a/tests/Allure.NUnit.Tests/StepTests.cs
+++ b/tests/Allure.NUnit.Tests/StepTests.cs
@@ -5,7 +5,7 @@ namespace Allure.NUnit.Tests;
class StepTests
{
- record class ParameterExpectations(string Name, string Value, string Mode = null)
+ internal record class ParameterExpectations(string Name, string Value, string Mode = null)
{
public bool Check(JsonObject parameter)
=> (string)parameter["name"] == this.Name
@@ -21,7 +21,7 @@ JsonArray parameters
.All(static (p) => p.Second.Check(p.First.AsObject()));
}
- record class StepExpectations(
+ internal record class StepExpectations(
string Name,
string Status,
List Parameters,
From 480ca008f0a6fea88917d7bf1eaecc29f501d1eb Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:01:36 +0700
Subject: [PATCH 44/80] test(commons): move attr tests to api tests
---
.../{AllureFacadeTests => }/AllureApiTestFixture.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/AfterFixtureTests.cs | 2 +-
.../AttributeTests/AllureIdAttributeTests.cs | 2 +-
.../AttributeTests/AttributeApplicationTests.cs | 2 +-
.../AttributeTests/BddHierarchyAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/BeforeFixtureTests.cs | 2 +-
.../AttributeTests/DescriptionAttributeTests.cs | 3 +--
.../AttributeTests/DescriptionHtmlAttributeTests.cs | 3 +--
.../{ => UserAPITests}/AttributeTests/EpicAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/FeatureAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/IssueAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/LabelAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/LinkAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/MetaAttributeTests.cs | 3 +--
.../{ => UserAPITests}/AttributeTests/NameAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/OwnerAttributeTests.cs | 2 +-
.../AttributeTests/ParentSuiteAttributeTests.cs | 2 +-
.../AttributeTests/SeverityAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/StepTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/StoryAttributeTests.cs | 2 +-
.../AttributeTests/SubSuiteAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/SuiteAttributeTests.cs | 2 +-
.../AttributeTests/SuiteHierarchyAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/TagAttributeTests.cs | 2 +-
.../{ => UserAPITests}/AttributeTests/TmsItemAttributeTests.cs | 2 +-
25 files changed, 25 insertions(+), 28 deletions(-)
rename tests/Allure.Net.Commons.Tests/UserAPITests/{AllureFacadeTests => }/AllureApiTestFixture.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/AfterFixtureTests.cs (98%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/AllureIdAttributeTests.cs (89%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/AttributeApplicationTests.cs (99%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/BddHierarchyAttributeTests.cs (97%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/BeforeFixtureTests.cs (99%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/DescriptionAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/DescriptionHtmlAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/EpicAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/FeatureAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/IssueAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/LabelAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/LinkAttributeTests.cs (96%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/MetaAttributeTests.cs (92%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/NameAttributeTests.cs (92%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/OwnerAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/ParentSuiteAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/SeverityAttributeTests.cs (95%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/StepTests.cs (98%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/StoryAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/SubSuiteAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/SuiteAttributeTests.cs (93%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/SuiteHierarchyAttributeTests.cs (97%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/TagAttributeTests.cs (96%)
rename tests/Allure.Net.Commons.Tests/{ => UserAPITests}/AttributeTests/TmsItemAttributeTests.cs (95%)
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/AttributeTests/AfterFixtureTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs
similarity index 98%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs
index 3b7ae501..36f328ec 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/AfterFixtureTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AfterFixtureTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
public class AfterFixtureTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs
similarity index 89%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs
index 517e87e0..e97c1175 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/AllureIdAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AllureIdAttributeTests.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class AllureIdAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
similarity index 99%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
index 0236edda..422abf47 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Sdk;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class AttributeApplicationTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs
similarity index 97%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs
index 604705b8..1d0abcaa 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/BddHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BddHierarchyAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class BddHierarchyAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs
similarity index 99%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs
index 8110d0e9..9e317c90 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/BeforeFixtureTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/BeforeFixtureTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
public class BeforeFixtureTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs
index 51552f33..e5c63fa0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionAttributeTests.cs
@@ -1,9 +1,8 @@
using System.Reflection;
using Allure.Net.Commons.Attributes;
-using Allure.Net.Commons.Sdk;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class DescriptionAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs
index 9c1be0ef..9ee4c7d3 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/DescriptionHtmlAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/DescriptionHtmlAttributeTests.cs
@@ -1,9 +1,8 @@
using System.Reflection;
using Allure.Net.Commons.Attributes;
-using Allure.Net.Commons.Sdk;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class DescriptionHtmlAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs
index 7fd28682..01efa466 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/EpicAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/EpicAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class EpicAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs
index b3ff95c9..309abbb8 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/FeatureAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/FeatureAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class FeatureAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs
index ecd5f4e7..26960f94 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/IssueAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/IssueAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class IssueAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs
index 4e1279bf..482d1f34 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LabelAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LabelAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class LabelAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs
similarity index 96%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs
index 95a72b18..3a1237e3 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/LinkAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/LinkAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class LinkAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs
similarity index 92%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs
index ce072c9b..272b7c6c 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/MetaAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/MetaAttributeTests.cs
@@ -1,9 +1,8 @@
using System;
-using System.Reflection;
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class MetaAttributeTests
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs
similarity index 92%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs
index b7130ae5..d961fa31 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/NameAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/NameAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class NameAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs
index c26eaa42..51f1db4b 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/OwnerAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/OwnerAttributeTests.cs
@@ -3,7 +3,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class OwnerAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs
index dee3cefa..0c720971 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/ParentSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/ParentSuiteAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class ParentSuiteAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs
index 55039578..2354fc0e 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SeverityAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SeverityAttributeTests.cs
@@ -3,7 +3,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class SeverityAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StepTests.cs
similarity index 98%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StepTests.cs
index 531a0006..958905f7 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StepTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StepTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
public class StepTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StoryAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StoryAttributeTests.cs
index bf6bcea0..91693821 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/StoryAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/StoryAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class StoryAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SubSuiteAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SubSuiteAttributeTests.cs
index f49e8edf..c7e1c9c0 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SubSuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SubSuiteAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class SubSuiteAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteAttributeTests.cs
similarity index 93%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteAttributeTests.cs
index 52abff7c..05042722 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class SuiteAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteHierarchyAttributeTests.cs
similarity index 97%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteHierarchyAttributeTests.cs
index 896530ba..faf5259a 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/SuiteHierarchyAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/SuiteHierarchyAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class SuiteHierarchyAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TagAttributeTests.cs
similarity index 96%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TagAttributeTests.cs
index d952b299..507b8877 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TagAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TagAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class TagAttributeTests
{
diff --git a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TmsItemAttributeTests.cs
similarity index 95%
rename from tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
rename to tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TmsItemAttributeTests.cs
index 9b11fa26..f1d434d1 100644
--- a/tests/Allure.Net.Commons.Tests/AttributeTests/TmsItemAttributeTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/TmsItemAttributeTests.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons.Attributes;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.AttributeTests;
+namespace Allure.Net.Commons.Tests.UserAPITests.AttributeTests;
class TmsItemAttributeTests
{
From a19a9e8548735cd83247cb772d810d99ab67b29d Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:02:13 +0700
Subject: [PATCH 45/80] test(commons): fix potential concurrency issue
---
src/Allure.Net.Commons/AllureApi.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/Allure.Net.Commons/AllureApi.cs b/src/Allure.Net.Commons/AllureApi.cs
index 0dc8c837..c76f3f76 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;
From e66e16731cc6d150ec71a62b6311c27ced4b15d6 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:02:53 +0700
Subject: [PATCH 46/80] feat(commons): [AllureAttachment] attribute
---
.../Attributes/AllureAttachmentAttribute.cs | 66 ++++++
.../Sdk/Aspects/AllureAttachmentAspect.cs | 59 +++++
.../AttributeTests/AttachmentTests.cs | 203 ++++++++++++++++++
3 files changed, 328 insertions(+)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
create mode 100644 src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
create mode 100644 tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
diff --git a/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
new file mode 100644
index 00000000..c738c236
--- /dev/null
+++ b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
@@ -0,0 +1,66 @@
+using System;
+using Allure.Net.Commons.Sdk.Aspects;
+using AspectInjector.Broker;
+
+#nullable enable
+
+namespace Allure.Net.Commons.Attributes;
+
+///
+/// When applied to a function returning byte[] or string, creates an attachment
+/// from the function's return value each time it's 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 function'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 function returns byte[], this property has no effect.
+ ///
+ public string? Encoding { get; init; }
+
+ ///
+ /// Sets up the target function to create an attachment with the same name as the function.
+ ///
+ public AllureAttachmentAttribute() { }
+
+ ///
+ /// Sets up the target function to create an explicitly named attachment.
+ ///
+ ///
+ /// 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/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
new file mode 100644
index 00000000..f2a912f9
--- /dev/null
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Reflection;
+using System.Text;
+using Allure.Net.Commons.Attributes;
+using AspectInjector.Broker;
+
+#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
+ )
+ {
+ var attr = metadata.GetCustomAttribute();
+ var attachmentName
+ = string.IsNullOrEmpty(attr?.Name)
+ ? name
+ : Steps.AllureStepParameterHelper.GetStepName(attr!.Name, metadata, arguments);
+ var contentType
+ = attr?.ContentType
+ ?? (returnType == typeof(string)
+ ? "text/plain"
+ : "application/octet-stream");
+ var extension
+ = attr?.Extension
+ ?? HeyRed.Mime.MimeTypesMap.GetExtension(contentType)
+ ?? "";
+
+ extension
+ = extension.Length == 0 || extension.StartsWith(".")
+ ? extension
+ : $".{extension}";
+
+ byte[] content = returnValue switch
+ {
+ null => [],
+ byte[] byteArray => byteArray,
+ string text => Encoding.GetEncoding(attr?.Encoding ?? "UTF-8").GetBytes(text),
+ _ => throw new InvalidOperationException(
+ $"Can't create an attachment from {returnValue.GetType().Name}. "
+ + "String or byte[] expected."
+ )
+ };
+
+ AllureApi.AddAttachment(attachmentName, contentType, content, extension);
+ }
+}
\ No newline at end of file
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..e2e42891
--- /dev/null
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -0,0 +1,203 @@
+using System.Threading.Tasks;
+using Allure.Net.Commons.Attributes;
+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.testResult = new();
+ 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.EqualTo("application/octet-stream"));
+ Assert.That(attachment.source, Does.EndWith(".bin"));
+ 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 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 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())));
+ }
+
+ [AllureAttachment]
+ static byte[] AttachByteArray() => [1, 2, 3];
+
+ [AllureAttachment]
+ static string AttachString() => "Lorem Ipsum";
+
+ [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";
+ }
+}
From d64cdfe467a3006aa8f66e4fd7ebc9b94dbb5b14 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:38:29 +0700
Subject: [PATCH 47/80] feat(commons): use type formatters by
[AllureAttachment]
---
.../Sdk/Aspects/AllureAttachmentAspect.cs | 7 +++++-
.../AttributeTests/AttachmentTests.cs | 22 ++++++++++++++++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
index f2a912f9..0cddde54 100644
--- a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -27,7 +27,12 @@ public void AttachReturnValue(
var attachmentName
= string.IsNullOrEmpty(attr?.Name)
? name
- : Steps.AllureStepParameterHelper.GetStepName(attr!.Name, metadata, arguments);
+ : Steps.AllureStepParameterHelper.GetStepName(
+ attr!.Name,
+ metadata,
+ arguments,
+ AllureApi.CurrentLifecycle.TypeFormatters
+ );
var contentType
= attr?.ContentType
?? (returnType == typeof(string)
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
index e2e42891..9e396546 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -12,7 +12,7 @@ class AttachmentTests : AllureApiTestFixture
[SetUp]
public void SetUpContext()
{
- this.testResult = new();
+ this.lifecycle.AddTypeFormatter(new InterpolationStub.TF());
this.lifecycle.StartTestCase(this.testResult);
}
@@ -126,6 +126,15 @@ public void InterpolatesArgumentsIntoName()
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()
{
@@ -200,4 +209,15 @@ 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) => [];
}
From 5d93b2fa052a6d690aab02e17a56fe4f4ebaf14c Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:40:23 +0700
Subject: [PATCH 48/80] feat(commons): delegate byte[] content type detection
to report
---
src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs | 4 ++--
.../UserAPITests/AttributeTests/AttachmentTests.cs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
index 0cddde54..17b460d2 100644
--- a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -37,10 +37,10 @@ var contentType
= attr?.ContentType
?? (returnType == typeof(string)
? "text/plain"
- : "application/octet-stream");
+ : null);
var extension
= attr?.Extension
- ?? HeyRed.Mime.MimeTypesMap.GetExtension(contentType)
+ ?? (contentType is null ? "" : HeyRed.Mime.MimeTypesMap.GetExtension(contentType))
?? "";
extension
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
index 9e396546..52dfc0e8 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -24,8 +24,8 @@ public void CreatesAttachmentFromByteArray()
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.EqualTo("application/octet-stream"));
- Assert.That(attachment.source, Does.EndWith(".bin"));
+ 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 })));
}
From da2b0511c00bfb7cd85bcf8e76bbacea93b8b7c8 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 14:40:58 +0700
Subject: [PATCH 49/80] feat(commons): avoid conversions if Allure not running
---
src/Allure.Net.Commons/AllureApi.cs | 4 +--
.../Sdk/Aspects/AllureAttachmentAspect.cs | 7 ++++-
.../AttributeTests/AttachmentTests.cs | 28 +++++++++++++++++++
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/src/Allure.Net.Commons/AllureApi.cs b/src/Allure.Net.Commons/AllureApi.cs
index c76f3f76..cfffd0fb 100644
--- a/src/Allure.Net.Commons/AllureApi.cs
+++ b/src/Allure.Net.Commons/AllureApi.cs
@@ -794,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/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
index 17b460d2..7299d970 100644
--- a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -23,6 +23,11 @@ public void AttachReturnValue(
[Argument(Source.ReturnValue)] object? returnValue
)
{
+ if (!AllureApi.HasTestOrFixture)
+ {
+ return;
+ }
+
var attr = metadata.GetCustomAttribute();
var attachmentName
= string.IsNullOrEmpty(attr?.Name)
@@ -59,6 +64,6 @@ var extension
)
};
- AllureApi.AddAttachment(attachmentName, contentType, content, extension);
+ AllureApi.AddAttachmentInternal(attachmentName, contentType, content, extension);
}
}
\ No newline at end of file
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
index 52dfc0e8..e6a1fd4a 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -1,5 +1,7 @@
+using System;
using System.Threading.Tasks;
using Allure.Net.Commons.Attributes;
+using Allure.Net.Commons.Functions;
using Allure.Net.Commons.Tests.UserApiTests;
using NUnit.Framework;
@@ -13,6 +15,11 @@ class AttachmentTests : AllureApiTestFixture
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);
}
@@ -169,6 +176,15 @@ public async Task SupportsValueTask()
"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];
@@ -220,4 +236,16 @@ public class TF : TypeFormatter
[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) => [];
}
From 9a4e176983e3cd2e59c0348045bc3c721bcf52b4 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 15:05:03 +0700
Subject: [PATCH 50/80] test(xunit): add bdd label tests
---
allure-csharp.slnx | 3 +
.../Allure.Xunit.Tests.csproj | 35 +++++
tests/Allure.Xunit.Tests/BddLabelTests.cs | 148 ++++++++++++++++++
tests/Allure.Xunit.Tests/GlobalSetup.cs | 15 ++
.../Samples/AddEpicFromTearDown.cs | 17 ++
.../Samples/AddEpicFromTest.cs | 14 ++
.../Samples/AddFeatureFromTearDown.cs | 17 ++
.../Samples/AddFeatureFromTest.cs | 14 ++
.../Samples/AddStoryFromTearDown.cs | 17 ++
.../Samples/AddStoryFromTest.cs | 14 ++
.../BddHierarchyAttributeOnBaseClass.cs | 14 ++
.../Samples/BddHierarchyAttributeOnClass.cs | 12 ++
.../BddHierarchyAttributeOnInterface.cs | 14 ++
.../Samples/BddHierarchyAttributeOnMethod.cs | 12 ++
.../Samples/EpicAttributeOnBaseClass.cs | 14 ++
.../Samples/EpicAttributeOnClass.cs | 12 ++
.../Samples/EpicAttributeOnInterface.cs | 14 ++
.../Samples/EpicAttributeOnMethod.cs | 12 ++
.../Samples/FeatureAttributeOnBaseClass.cs | 14 ++
.../Samples/FeatureAttributeOnClass.cs | 12 ++
.../Samples/FeatureAttributeOnInterface.cs | 14 ++
.../Samples/FeatureAttributeOnMethod.cs | 12 ++
.../Samples/LegacyEpicAttributeOnBaseClass.cs | 14 ++
.../Samples/LegacyEpicAttributeOnClass.cs | 12 ++
.../Samples/LegacyEpicAttributeOnMethod.cs | 12 ++
.../LegacyFeatureAttributeOnBaseClass.cs | 14 ++
.../Samples/LegacyFeatureAttributeOnClass.cs | 12 ++
.../Samples/LegacyFeatureAttributeOnMethod.cs | 12 ++
.../LegacyStoryAttributeOnBaseClass.cs | 14 ++
.../Samples/LegacyStoryAttributeOnClass.cs | 12 ++
.../Samples/LegacyStoryAttributeOnMethod.cs | 12 ++
.../Samples/StoryAttributeOnBaseClass.cs | 14 ++
.../Samples/StoryAttributeOnClass.cs | 12 ++
.../Samples/StoryAttributeOnInterface.cs | 14 ++
.../Samples/StoryAttributeOnMethod.cs | 12 ++
35 files changed, 616 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/Allure.Xunit.Tests.csproj
create mode 100644 tests/Allure.Xunit.Tests/BddLabelTests.cs
create mode 100644 tests/Allure.Xunit.Tests/GlobalSetup.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddEpicFromTest.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddFeatureFromTest.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddStoryFromTest.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/EpicAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/EpicAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/EpicAttributeOnInterface.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/EpicAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnInterface.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/StoryAttributeOnBaseClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/StoryAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/StoryAttributeOnInterface.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/StoryAttributeOnMethod.cs
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/tests/Allure.Xunit.Tests/Allure.Xunit.Tests.csproj b/tests/Allure.Xunit.Tests/Allure.Xunit.Tests.csproj
new file mode 100644
index 00000000..f620a9b1
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Allure.Xunit.Tests.csproj
@@ -0,0 +1,35 @@
+
+
+
+ enable
+ Exe
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Allure.Xunit.Tests/BddLabelTests.cs b/tests/Allure.Xunit.Tests/BddLabelTests.cs
new file mode 100644
index 00000000..c7ac1757
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/BddLabelTests.cs
@@ -0,0 +1,148 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.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.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.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.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.Xunit.Tests/GlobalSetup.cs b/tests/Allure.Xunit.Tests/GlobalSetup.cs
new file mode 100644
index 00000000..29fded28
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/GlobalSetup.cs
@@ -0,0 +1,15 @@
+using Allure.Testing;
+
+[assembly: System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+
+#if ALLURE_TEST_PARALLEL
+
+[assembly: ParallelLimiter]
+
+#else
+
+[assembly: NotInParallel(["Allure.NUnit", "Allure.Net.Commons"])]
+
+#endif
+
+namespace Allure.Xunit.Tests;
diff --git a/tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs
new file mode 100644
index 00000000..8d459a2b
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs
@@ -0,0 +1,17 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddEpicFromTearDown
+{
+ public class TestsClass : IDisposable
+ {
+ public void Dispose()
+ {
+ AllureApi.AddEpic("foo");
+ }
+
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddEpicFromTest.cs b/tests/Allure.Xunit.Tests/Samples/AddEpicFromTest.cs
new file mode 100644
index 00000000..42614e23
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddEpicFromTest.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddEpicFromTest
+{
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddEpic("foo");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs
new file mode 100644
index 00000000..3af46739
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs
@@ -0,0 +1,17 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddFeatureFromTearDown
+{
+ public class TestsClass : IDisposable
+ {
+ public void Dispose()
+ {
+ AllureApi.AddFeature("foo");
+ }
+
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTest.cs b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTest.cs
new file mode 100644
index 00000000..ea600c34
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTest.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddFeatureFromTest
+{
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddFeature("foo");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs
new file mode 100644
index 00000000..62817305
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs
@@ -0,0 +1,17 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddStoryFromTearDown
+{
+ public class TestsClass : IDisposable
+ {
+ public void Dispose()
+ {
+ AllureApi.AddStory("foo");
+ }
+
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddStoryFromTest.cs b/tests/Allure.Xunit.Tests/Samples/AddStoryFromTest.cs
new file mode 100644
index 00000000..f80b419c
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddStoryFromTest.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddStoryFromTest
+{
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddStory("foo");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
new file mode 100644
index 00000000..bb9042ea
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.BddHierarchyAttributeOnBaseClass
+{
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnClass.cs
new file mode 100644
index 00000000..c6af6fb9
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.BddHierarchyAttributeOnClass
+{
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnInterface.cs b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
new file mode 100644
index 00000000..76716b06
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnInterface.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.BddHierarchyAttributeOnInterface
+{
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public interface IMetadataInterface {}
+
+ public class TestsClass : IMetadataInterface
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
new file mode 100644
index 00000000..930a44f9
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/BddHierarchyAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.BddHierarchyAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureBddHierarchy("foo", "bar", "baz")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnBaseClass.cs
new file mode 100644
index 00000000..64abeeb1
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.EpicAttributeOnBaseClass
+{
+ [AllureEpic("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnClass.cs
new file mode 100644
index 00000000..8526b554
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.EpicAttributeOnClass
+{
+ [AllureEpic("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnInterface.cs b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnInterface.cs
new file mode 100644
index 00000000..427bf280
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnInterface.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.EpicAttributeOnInterface
+{
+ [AllureEpic("foo")]
+ public interface IMetadataInterface {}
+
+ public class TestsClass : IMetadataInterface
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnMethod.cs
new file mode 100644
index 00000000..bef40a9c
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/EpicAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.EpicAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureEpic("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnBaseClass.cs
new file mode 100644
index 00000000..fe6d8d17
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.FeatureAttributeOnBaseClass
+{
+ [AllureFeature("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnClass.cs
new file mode 100644
index 00000000..97adaa89
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.FeatureAttributeOnClass
+{
+ [AllureFeature("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnInterface.cs b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnInterface.cs
new file mode 100644
index 00000000..a214e777
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnInterface.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.FeatureAttributeOnInterface
+{
+ [AllureFeature("foo")]
+ public interface IMetadataInterface {}
+
+ public class TestsClass : IMetadataInterface
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnMethod.cs
new file mode 100644
index 00000000..0f9ef112
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/FeatureAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.FeatureAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureFeature("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
new file mode 100644
index 00000000..829ba3ce
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyEpicAttributeOnBaseClass
+{
+ [AllureEpic("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnClass.cs
new file mode 100644
index 00000000..a4484d22
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyEpicAttributeOnClass
+{
+ [AllureEpic("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
new file mode 100644
index 00000000..9812a5f2
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyEpicAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyEpicAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureEpic("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
new file mode 100644
index 00000000..4f5b842b
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyFeatureAttributeOnBaseClass
+{
+ [AllureFeature("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
new file mode 100644
index 00000000..ad3ddf64
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyFeatureAttributeOnClass
+{
+ [AllureFeature("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
new file mode 100644
index 00000000..b88fd70f
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyFeatureAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyFeatureAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureFeature("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
new file mode 100644
index 00000000..5d93cc4a
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyStoryAttributeOnBaseClass
+{
+ [AllureStory("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnClass.cs
new file mode 100644
index 00000000..49837ab6
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyStoryAttributeOnClass
+{
+ [AllureStory("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
new file mode 100644
index 00000000..41037f5a
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyStoryAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyStoryAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureStory("foo")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnBaseClass.cs b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnBaseClass.cs
new file mode 100644
index 00000000..5b45da99
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnBaseClass.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.StoryAttributeOnBaseClass
+{
+ [AllureStory("foo")]
+ public class BaseClass {}
+
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnClass.cs
new file mode 100644
index 00000000..2ea80be5
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.StoryAttributeOnClass
+{
+ [AllureStory("foo")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnInterface.cs b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnInterface.cs
new file mode 100644
index 00000000..379f2715
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnInterface.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.StoryAttributeOnInterface
+{
+ [AllureStory("foo")]
+ public interface IMetadataInterface {}
+
+ public class TestsClass : IMetadataInterface
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnMethod.cs
new file mode 100644
index 00000000..099cebde
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/StoryAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.StoryAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureStory("foo")]
+ public void TestMethod() { }
+ }
+}
From b7d6fa429aadd7d16c2a3e4931e21886e301fc8b Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 15:05:59 +0700
Subject: [PATCH 51/80] chore: run xunit tests in ci
---
.github/workflows/test.yml | 4 ++++
1 file changed, 4 insertions(+)
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\
From 567bfb53c8628be52beb5d19bab05a5c05ece472 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 15:12:33 +0700
Subject: [PATCH 52/80] test(xunit): add allure id tests
---
tests/Allure.Xunit.Tests/AllureIdTests.cs | 36 +++++++++++++++++++
.../Samples/AllureIdAttributeOnMethod.cs | 12 +++++++
.../LegacyAllureIdAttributeOnMethod.cs | 12 +++++++
.../Samples/SetAllureIdFromTearDown.cs | 17 +++++++++
.../Samples/SetAllureIdFromTest.cs | 14 ++++++++
5 files changed, 91 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/AllureIdTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AllureIdAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTest.cs
diff --git a/tests/Allure.Xunit.Tests/AllureIdTests.cs b/tests/Allure.Xunit.Tests/AllureIdTests.cs
new file mode 100644
index 00000000..11816dd9
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/AllureIdTests.cs
@@ -0,0 +1,36 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class AllureIdTests
+{
+ public static IEnumerable> GetAllureIdSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SetAllureIdFromTest,
+ AllureSampleRegistry.SetAllureIdFromTearDown,
+ AllureSampleRegistry.AllureIdAttributeOnMethod,
+ AllureSampleRegistry.LegacyAllureIdAttributeOnMethod,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetAllureIdSamples))]
+ public async Task CheckAllureIdLabelIsAdded(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"] == "ALLURE_ID" && (string)l["value"] == "1001";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AllureIdAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/AllureIdAttributeOnMethod.cs
new file mode 100644
index 00000000..0be18038
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AllureIdAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AllureIdAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureId(1001)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
new file mode 100644
index 00000000..51335135
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyAllureIdAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AllureIdAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureId("1001")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs
new file mode 100644
index 00000000..5576ef15
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs
@@ -0,0 +1,17 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.SetAllureIdFromTearDown
+{
+ public class TestsClass : IDisposable
+ {
+ public void Dispose()
+ {
+ AllureApi.SetAllureId(1001);
+ }
+
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTest.cs b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTest.cs
new file mode 100644
index 00000000..a3a87276
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTest.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.SetAllureIdFromTest
+{
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.SetAllureId(1001);
+ }
+ }
+}
From e3dbdc9e02fd9e5964b0df50b9e8d2ed96f281a8 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 15:28:52 +0700
Subject: [PATCH 53/80] test(xunit): add custom label tests
---
tests/Allure.Xunit.Tests/CustomLabelTests.cs | 82 +++++++++++++++++++
.../Allure.Xunit.Tests/Samples/AddLabelApi.cs | 20 +++++
.../Samples/LabelAttribute.cs | 19 +++++
.../Samples/LegacyLabelAttribute.cs | 16 ++++
4 files changed, 137 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/CustomLabelTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
diff --git a/tests/Allure.Xunit.Tests/CustomLabelTests.cs b/tests/Allure.Xunit.Tests/CustomLabelTests.cs
new file mode 100644
index 00000000..e6cd40e6
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/CustomLabelTests.cs
@@ -0,0 +1,82 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class CustomLabelTests
+{
+ [Test]
+ public async Task CheckCustomLabelIsAdded()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddLabelApi);
+
+ 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"] == "test" && (string)l["value"] == "foo";
+ }
+ ).Any(
+ l =>
+ {
+ return (string)l["name"] == "dispose" && (string)l["value"] == "bar";
+ }
+ );
+ }
+
+ [Test]
+ public async Task LabelAttributeShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LabelAttribute);
+
+ 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"] == "interface" && (string)l["value"] == "foo";
+ }
+ ).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "baseClass" && (string)l["value"] == "bar";
+ }
+ ).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "class" && (string)l["value"] == "baz";
+ }
+ ).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "method" && (string)l["value"] == "qux";
+ }
+ );
+ }
+
+ [Test]
+ public async Task LegacyLabelAttributeShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyLabelAttribute);
+
+ 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"] == "baseClass" && (string)l["value"] == "foo";
+ }
+ ).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "class" && (string)l["value"] == "bar";
+ }
+ ).Any(
+ static (l) =>
+ {
+ return (string)l["name"] == "method" && (string)l["value"] == "baz";
+ }
+ );
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs b/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
new file mode 100644
index 00000000..d685c435
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
@@ -0,0 +1,20 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddLabelFromTearDown
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddLabel("test", "foo");
+ }
+
+ public void Dispose()
+ {
+ AllureApi.AddLabel("dispose", "bar");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs b/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
new file mode 100644
index 00000000..c5d2685c
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
@@ -0,0 +1,19 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LabelAttributeOnBaseClass
+{
+ [AllureLabel("interface", "foo")]
+ public interface IMetadataInterface {}
+
+ [AllureLabel("baseClass", "bar")]
+ public class BaseClass {}
+
+ [AllureLabel("class", "baz")]
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ [AllureLabel("method", "qux")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs b/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
new file mode 100644
index 00000000..63da3c85
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
@@ -0,0 +1,16 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyLabelAttributeOnClass
+{
+ [AllureLabel("baseClass", "foo")]
+ public class BaseClass {}
+
+ [AllureLabel("class", "bar")]
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ [AllureLabel("method", "baz")]
+ public void TestMethod() { }
+ }
+}
From 0beda4c12642332b03d1a33cf4ec2d2a7da5ba96 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 15:51:43 +0700
Subject: [PATCH 54/80] test(xunit): add description tests
---
tests/Allure.Xunit.Tests/DescriptionTests.cs | 61 +++++++++++++++++++
.../AddDescriptionFromDisposeHtmlFromTest.cs | 20 ++++++
.../AddDescriptionFromTestHtmlFromDispose.cs | 20 ++++++
.../Samples/DescriptionAttributes.cs | 23 +++++++
.../Samples/LegacyDescriptionAttribute.cs | 12 ++++
5 files changed, 136 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/DescriptionTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddDescriptionFromDisposeHtmlFromTest.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddDescriptionFromTestHtmlFromDispose.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/DescriptionAttributes.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyDescriptionAttribute.cs
diff --git a/tests/Allure.Xunit.Tests/DescriptionTests.cs b/tests/Allure.Xunit.Tests/DescriptionTests.cs
new file mode 100644
index 00000000..0f218a56
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/DescriptionTests.cs
@@ -0,0 +1,61 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class DescriptionTests
+{
+ [Test]
+ public async Task CheckDescriptionAndDescriptionHtmlCanBeAdded()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddDescriptionFromTestHtmlFromDispose);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["description"]).IsEqualTo("Lorem Ipsum");
+ await Assert.That((string)results.TestResults[0]["descriptionHtml"]).IsEqualTo("Dolor Sit Amet");
+ }
+
+ [Test]
+ public async Task CheckDescriptionHtmlAndDescriptionCanBeAdded()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddDescriptionFromDisposeHtmlFromTest);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["descriptionHtml"]).IsEqualTo("Lorem Ipsum");
+ await Assert.That((string)results.TestResults[0]["description"]).IsEqualTo("Dolor Sit Amet");
+ }
+
+ [Test]
+ public async Task DescriptionAttributeShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.DescriptionAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["description"]).IsEqualTo(
+ """
+ Lorem Ipsum
+
+ Consectetur Adipiscing Elit
+
+ Tempor Incididunt
+
+ Et Dolore
+ """
+ );
+ await Assert.That((string)results.TestResults[0]["descriptionHtml"]).IsEqualTo(
+ "Dolor Sit Amet
"
+ + "Sed Do Eiusmod
"
+ + "Ut Labore
"
+ + "Magna Aliqua
"
+ );
+ }
+
+ [Test]
+ public async Task LegacyDescriptionAttributeShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyDescriptionAttribute);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ await Assert.That((string)results.TestResults[0]["description"]).IsEqualTo("Lorem Ipsum");
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromDisposeHtmlFromTest.cs b/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromDisposeHtmlFromTest.cs
new file mode 100644
index 00000000..8eaee80e
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromDisposeHtmlFromTest.cs
@@ -0,0 +1,20 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromDisposeHtmlFromTest
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.SetDescriptionHtml("Lorem Ipsum");
+ }
+
+ public void Dispose()
+ {
+ AllureApi.SetDescription("Dolor Sit Amet");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromTestHtmlFromDispose.cs b/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromTestHtmlFromDispose.cs
new file mode 100644
index 00000000..1ac03d00
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddDescriptionFromTestHtmlFromDispose.cs
@@ -0,0 +1,20 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.NUnit.Tests.Samples.AddDescriptionFromTestHtmlFromDispose
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.SetDescription("Lorem Ipsum");
+ }
+
+ public void Dispose()
+ {
+ AllureApi.SetDescriptionHtml("Dolor Sit Amet");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/DescriptionAttributes.cs b/tests/Allure.Xunit.Tests/Samples/DescriptionAttributes.cs
new file mode 100644
index 00000000..bb38e256
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/DescriptionAttributes.cs
@@ -0,0 +1,23 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.DescriptionAttributes
+{
+ [AllureDescription("Lorem Ipsum")]
+ [AllureDescriptionHtml("Dolor Sit Amet
")]
+ public interface IMetadataInterface { }
+
+ [AllureDescription("Consectetur Adipiscing Elit", Append = true)]
+ [AllureDescriptionHtml("Sed Do Eiusmod
", Append = true)]
+ public class TestClassBase { }
+
+ [AllureDescription("Tempor Incididunt", Append = true)]
+ [AllureDescriptionHtml("Ut Labore
", Append = true)]
+ public class TestsClass : TestClassBase, IMetadataInterface
+ {
+ [Fact]
+ [AllureDescription("Et Dolore", Append = true)]
+ [AllureDescriptionHtml("Magna Aliqua
", Append = true)]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyDescriptionAttribute.cs b/tests/Allure.Xunit.Tests/Samples/LegacyDescriptionAttribute.cs
new file mode 100644
index 00000000..74f036cd
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyDescriptionAttribute.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyDescriptionAttribute
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureDescription("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
From 08ff2691222d1752845d9a12a1323c9e6cdb3d2d Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 16:57:19 +0700
Subject: [PATCH 55/80] test(xunit): fix some tests
---
tests/Allure.NUnit.Tests/DescriptionTests.cs | 2 +-
tests/Allure.Xunit.Tests/CustomLabelTests.cs | 77 +++++++------------
.../Allure.Xunit.Tests/Samples/AddLabelApi.cs | 2 +-
.../Samples/LabelAttribute.cs | 4 +-
.../Samples/LegacyLabelAttribute.cs | 2 +-
5 files changed, 33 insertions(+), 54 deletions(-)
diff --git a/tests/Allure.NUnit.Tests/DescriptionTests.cs b/tests/Allure.NUnit.Tests/DescriptionTests.cs
index c394e18b..57a797a1 100644
--- a/tests/Allure.NUnit.Tests/DescriptionTests.cs
+++ b/tests/Allure.NUnit.Tests/DescriptionTests.cs
@@ -56,7 +56,7 @@ public static IEnumerable> GetHtmlDescrip
[Test]
[MethodDataSource(nameof(GetHtmlDescriptionSamples))]
- public async Task CheckHtmkDescriptionIsAdded(AllureSampleRegistryEntry sample)
+ public async Task CheckHtmlDescriptionIsAdded(AllureSampleRegistryEntry sample)
{
var results = await AllureSampleRunner.RunAsync(sample);
diff --git a/tests/Allure.Xunit.Tests/CustomLabelTests.cs b/tests/Allure.Xunit.Tests/CustomLabelTests.cs
index e6cd40e6..705f2bcc 100644
--- a/tests/Allure.Xunit.Tests/CustomLabelTests.cs
+++ b/tests/Allure.Xunit.Tests/CustomLabelTests.cs
@@ -12,17 +12,13 @@ public async Task CheckCustomLabelIsAdded()
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"] == "test" && (string)l["value"] == "foo";
- }
- ).Any(
- l =>
- {
- return (string)l["name"] == "dispose" && (string)l["value"] == "bar";
- }
- );
+ await Assert.That(nodes)
+ .Any(static (l) =>
+ (string)l["name"] == "test"
+ && (string)l["value"] == "foo")
+ .And.Any(static (l) =>
+ (string)l["name"] == "dispose"
+ && (string)l["value"] == "bar");
}
[Test]
@@ -31,28 +27,20 @@ public async Task LabelAttributeShouldWork()
var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LabelAttribute);
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"] == "interface" && (string)l["value"] == "foo";
- }
- ).Any(
- static (l) =>
- {
- return (string)l["name"] == "baseClass" && (string)l["value"] == "bar";
- }
- ).Any(
- static (l) =>
- {
- return (string)l["name"] == "class" && (string)l["value"] == "baz";
- }
- ).Any(
- static (l) =>
- {
- return (string)l["name"] == "method" && (string)l["value"] == "qux";
- }
- );
+ var labels = results.TestResults[0]["labels"].AsArray().ToArray();
+ await Assert.That(labels)
+ .Any(static (l) =>
+ (string)l["name"] == "interface"
+ && (string)l["value"] == "foo")
+ .And.Any(static (l) =>
+ (string)l["name"] == "baseClass"
+ && (string)l["value"] == "bar")
+ .And.Any(static (l) =>
+ (string)l["name"] == "class"
+ && (string)l["value"] == "baz")
+ .And.Any(static (l) =>
+ (string)l["name"] == "method"
+ && (string)l["value"] == "qux");
}
[Test]
@@ -62,21 +50,12 @@ public async Task LegacyLabelAttributeShouldWork()
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"] == "baseClass" && (string)l["value"] == "foo";
- }
- ).Any(
- static (l) =>
- {
- return (string)l["name"] == "class" && (string)l["value"] == "bar";
- }
- ).Any(
- static (l) =>
- {
- return (string)l["name"] == "method" && (string)l["value"] == "baz";
- }
- );
+ await Assert.That(labels)
+ .Any(static (l) =>
+ (string)l["name"] == "class"
+ && (string)l["value"] == "bar")
+ .And.Any(static (l) =>
+ (string)l["name"] == "method"
+ && (string)l["value"] == "baz");
}
}
diff --git a/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs b/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
index d685c435..a59f9f8b 100644
--- a/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
+++ b/tests/Allure.Xunit.Tests/Samples/AddLabelApi.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.AddLabelFromTearDown
+namespace Allure.Xunit.Tests.Samples.AddLabelApi
{
public class TestsClass : IDisposable
{
diff --git a/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs b/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
index c5d2685c..d921ba05 100644
--- a/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
+++ b/tests/Allure.Xunit.Tests/Samples/LabelAttribute.cs
@@ -1,7 +1,7 @@
using Allure.Net.Commons.Attributes;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.LabelAttributeOnBaseClass
+namespace Allure.Xunit.Tests.Samples.LabelAttribute
{
[AllureLabel("interface", "foo")]
public interface IMetadataInterface {}
@@ -10,7 +10,7 @@ public interface IMetadataInterface {}
public class BaseClass {}
[AllureLabel("class", "baz")]
- public class TestsClass : BaseClass
+ public class TestsClass : BaseClass, IMetadataInterface
{
[Fact]
[AllureLabel("method", "qux")]
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs b/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
index 63da3c85..f5dafeea 100644
--- a/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyLabelAttribute.cs
@@ -1,7 +1,7 @@
using Allure.Xunit.Attributes;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.LegacyLabelAttributeOnClass
+namespace Allure.Xunit.Tests.Samples.LegacyLabelAttribute
{
[AllureLabel("baseClass", "foo")]
public class BaseClass {}
From 21b7d2a0e05de84e0bc82f1776df003807aa90f2 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 16:57:33 +0700
Subject: [PATCH 56/80] test(xunit): add link tests
---
tests/Allure.Xunit.Tests/LinkTests.cs | 131 ++++++++++++++++++
.../Samples/LegacyLinkAttributes.cs | 19 +++
.../Samples/LinkAttributes.cs | 27 ++++
.../Samples/LinkRuntimeApi.cs | 26 ++++
4 files changed, 203 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/LinkTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyLinkAttributes.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LinkAttributes.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LinkRuntimeApi.cs
diff --git a/tests/Allure.Xunit.Tests/LinkTests.cs b/tests/Allure.Xunit.Tests/LinkTests.cs
new file mode 100644
index 00000000..1c170e55
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/LinkTests.cs
@@ -0,0 +1,131 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class LinkTests
+{
+ [Test]
+ public async Task LinkRuntimeApiShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LinkRuntimeApi);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToList();
+ await Assert.That(links.Count).IsEqualTo(7);
+ 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"
+ && (string)l["type"] == "type-2");
+ 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"] == "tms");
+ await Assert.That(links[4]).Satisfies(static (l) =>
+ (string)l["url"] == "url-5"
+ && (string)l["name"] == "name-5"
+ && l["type"] is null);
+ await Assert.That(links[5]).Satisfies(static (l) =>
+ (string)l["url"] == "url-6"
+ && (string)l["name"] == "name-6"
+ && (string)l["type"] == "issue");
+ await Assert.That(links[6]).Satisfies(static (l) =>
+ (string)l["url"] == "url-7"
+ && (string)l["name"] == "name-7"
+ && (string)l["type"] == "tms");
+ }
+
+ [Test]
+ public async Task LinkAttributesShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LinkAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToArray();
+ await Assert.That(links.Count).IsEqualTo(12);
+ await Assert.That(links)
+ .Any(static (l) =>
+ (string)l["url"] == "url-1"
+ && l["name"] is null
+ && l["type"] is null)
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-2"
+ && l["name"] is null
+ && (string)l["type"] == "issue")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-3"
+ && l["name"] is null
+ && (string)l["type"] == "tms")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-4"
+ && (string)l["name"] == "name-4"
+ && l["type"] is null)
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-5"
+ && (string)l["name"] == "name-5"
+ && (string)l["type"] == "issue")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-6"
+ && (string)l["name"] == "name-6"
+ && (string)l["type"] == "tms")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-7"
+ && l["name"] is null
+ && (string)l["type"] == "type-7")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-8"
+ && l["name"] is null
+ && (string)l["type"] == "issue")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-9"
+ && l["name"] is null
+ && (string)l["type"] == "tms")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-10"
+ && (string)l["name"] == "name-10"
+ && (string)l["type"] == "type-10")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-11"
+ && l["name"] is null
+ && (string)l["type"] == "issue")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-12"
+ && l["name"] is null
+ && (string)l["type"] == "tms");
+ }
+
+ [Test]
+ public async Task LegacyLinkAttributesShouldWork()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyLinkAttributes);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+ var links = results.TestResults[0]["links"].AsArray().Cast().ToArray();
+ await Assert.That(links.Count).IsEqualTo(4);
+ await Assert.That(links)
+ .Any(static (l) =>
+ (string)l["url"] == "url-3"
+ && (string)l["name"] == "name-3"
+ && (string)l["type"] == "link")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-4"
+ && (string)l["name"] == "name-4"
+ && (string)l["type"] == "issue")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-5"
+ && (string)l["name"] == "url-5"
+ && (string)l["type"] == "link")
+ .And.Any(static (l) =>
+ (string)l["url"] == "url-6"
+ && (string)l["name"] == "url-6"
+ && (string)l["type"] == "issue");
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyLinkAttributes.cs b/tests/Allure.Xunit.Tests/Samples/LegacyLinkAttributes.cs
new file mode 100644
index 00000000..60282575
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyLinkAttributes.cs
@@ -0,0 +1,19 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyLinkAttributes
+{
+ [AllureLink("url-1")]
+ [AllureIssue("url-2")]
+ public class BaseClass {}
+
+ [AllureLink("name-3", "url-3")]
+ [AllureIssue("name-4", "url-4")]
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ [AllureLink("url-5")]
+ [AllureIssue("url-6")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LinkAttributes.cs b/tests/Allure.Xunit.Tests/Samples/LinkAttributes.cs
new file mode 100644
index 00000000..36609cfd
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LinkAttributes.cs
@@ -0,0 +1,27 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LinkAttributes
+{
+ [AllureLink("url-1")]
+ [AllureIssue("url-2")]
+ [AllureTmsItem("url-3")]
+ public interface IMetadataInterface {}
+
+ [AllureLink("url-4", Title = "name-4")]
+ [AllureIssue("url-5", Title = "name-5")]
+ [AllureTmsItem("url-6", Title = "name-6")]
+ public class BaseClass {}
+
+ [AllureLink("url-7", Type = "type-7")]
+ [AllureIssue("url-8")]
+ [AllureTmsItem("url-9")]
+ public class TestsClass : BaseClass, IMetadataInterface
+ {
+ [Fact]
+ [AllureLink("url-10", Title = "name-10", Type = "type-10")]
+ [AllureIssue("url-11")]
+ [AllureTmsItem("url-12")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LinkRuntimeApi.cs b/tests/Allure.Xunit.Tests/Samples/LinkRuntimeApi.cs
new file mode 100644
index 00000000..5c97bd70
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LinkRuntimeApi.cs
@@ -0,0 +1,26 @@
+using System;
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LinkRuntimeApi
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddLink("url-1");
+ AllureApi.AddLink("name-2", "type-2", "url-2");
+ AllureApi.AddIssue("url-3");
+ AllureApi.AddTmsItem("url-4");
+ }
+
+ public void Dispose()
+ {
+ AllureApi.AddLink("name-5", "url-5");
+ AllureApi.AddIssue("name-6", "url-6");
+ AllureApi.AddTmsItem("name-7", "url-7");
+ }
+ }
+}
From 118218c68af268394b0bf739302c3b8fc65e3312 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:01:27 +0700
Subject: [PATCH 57/80] test(xunit): add meta attribute tests
---
.../Allure.Xunit.Tests/MetaAttributeTests.cs | 48 +++++++++++++++++++
.../Samples/MetaAttributes.cs | 41 ++++++++++++++++
2 files changed, 89 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/MetaAttributeTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/MetaAttributes.cs
diff --git a/tests/Allure.Xunit.Tests/MetaAttributeTests.cs b/tests/Allure.Xunit.Tests/MetaAttributeTests.cs
new file mode 100644
index 00000000..560c762b
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/MetaAttributeTests.cs
@@ -0,0 +1,48 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.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) =>
+ (string)l["name"] == "epic"
+ && (string)l["value"] == "Foo")
+ .And.Any(static (l) =>
+ (string)l["name"] == "owner"
+ && (string)l["value"] == "John Doe")
+ .And.Any(static (l) =>
+ (string)l["name"] == "feature"
+ && (string)l["value"] == "Bar")
+ .And.Any(static (l) =>
+ (string)l["name"] == "tag"
+ && (string)l["value"] == "foo")
+ .And.Any(static (l) =>
+ (string)l["name"] == "tag"
+ && (string)l["value"] == "bar")
+ .And.Any(static (l) =>
+ (string)l["name"] == "story"
+ && (string)l["value"] == "Baz")
+ .And.Any(static (l) =>
+ (string)l["name"] == "severity"
+ && (string)l["value"] == "critical")
+ .And.Any(static (l) =>
+ (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.Xunit.Tests/Samples/MetaAttributes.cs b/tests/Allure.Xunit.Tests/Samples/MetaAttributes.cs
new file mode 100644
index 00000000..ca559afc
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/MetaAttributes.cs
@@ -0,0 +1,41 @@
+using System;
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.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 { }
+
+ [StoryLink]
+ public class TestsClass : BaseClass, IMetadata
+ {
+ [Fact]
+ [SeveritySuite]
+ public void TestMethod() { }
+ }
+}
From 6485d8446bab3c423ec46df79c85def573785813 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:14:02 +0700
Subject: [PATCH 58/80] test(xunit): fix some sample names
---
tests/Allure.Xunit.Tests/AllureIdTests.cs | 2 +-
tests/Allure.Xunit.Tests/BddLabelTests.cs | 6 +++---
.../{AddEpicFromTearDown.cs => AddEpicFromDispose.cs} | 2 +-
.../{AddFeatureFromTearDown.cs => AddFeatureFromDispose.cs} | 2 +-
.../{AddStoryFromTearDown.cs => AddStoryFromDispose.cs} | 2 +-
...SetAllureIdFromTearDown.cs => SetAllureIdFromDispose.cs} | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
rename tests/Allure.Xunit.Tests/Samples/{AddEpicFromTearDown.cs => AddEpicFromDispose.cs} (81%)
rename tests/Allure.Xunit.Tests/Samples/{AddFeatureFromTearDown.cs => AddFeatureFromDispose.cs} (81%)
rename tests/Allure.Xunit.Tests/Samples/{AddStoryFromTearDown.cs => AddStoryFromDispose.cs} (81%)
rename tests/Allure.Xunit.Tests/Samples/{SetAllureIdFromTearDown.cs => SetAllureIdFromDispose.cs} (80%)
diff --git a/tests/Allure.Xunit.Tests/AllureIdTests.cs b/tests/Allure.Xunit.Tests/AllureIdTests.cs
index 11816dd9..b56da9ce 100644
--- a/tests/Allure.Xunit.Tests/AllureIdTests.cs
+++ b/tests/Allure.Xunit.Tests/AllureIdTests.cs
@@ -9,7 +9,7 @@ public static IEnumerable> GetAllureIdSam
{
IEnumerable samples = [
AllureSampleRegistry.SetAllureIdFromTest,
- AllureSampleRegistry.SetAllureIdFromTearDown,
+ AllureSampleRegistry.SetAllureIdFromDispose,
AllureSampleRegistry.AllureIdAttributeOnMethod,
AllureSampleRegistry.LegacyAllureIdAttributeOnMethod,
];
diff --git a/tests/Allure.Xunit.Tests/BddLabelTests.cs b/tests/Allure.Xunit.Tests/BddLabelTests.cs
index c7ac1757..21705e6f 100644
--- a/tests/Allure.Xunit.Tests/BddLabelTests.cs
+++ b/tests/Allure.Xunit.Tests/BddLabelTests.cs
@@ -52,7 +52,7 @@ public static IEnumerable> GetEpicSamples
AllureSampleRegistry.EpicAttributeOnBaseClass,
AllureSampleRegistry.EpicAttributeOnInterface,
AllureSampleRegistry.AddEpicFromTest,
- AllureSampleRegistry.AddEpicFromTearDown,
+ AllureSampleRegistry.AddEpicFromDispose,
AllureSampleRegistry.LegacyEpicAttributeOnClass,
AllureSampleRegistry.LegacyEpicAttributeOnMethod,
AllureSampleRegistry.LegacyEpicAttributeOnBaseClass,
@@ -86,7 +86,7 @@ public static IEnumerable> GetFeatureSamp
AllureSampleRegistry.FeatureAttributeOnBaseClass,
AllureSampleRegistry.FeatureAttributeOnInterface,
AllureSampleRegistry.AddFeatureFromTest,
- AllureSampleRegistry.AddFeatureFromTearDown,
+ AllureSampleRegistry.AddFeatureFromDispose,
AllureSampleRegistry.LegacyFeatureAttributeOnClass,
AllureSampleRegistry.LegacyFeatureAttributeOnMethod,
AllureSampleRegistry.LegacyFeatureAttributeOnBaseClass,
@@ -120,7 +120,7 @@ public static IEnumerable> GetStorySample
AllureSampleRegistry.StoryAttributeOnBaseClass,
AllureSampleRegistry.StoryAttributeOnInterface,
AllureSampleRegistry.AddStoryFromTest,
- AllureSampleRegistry.AddStoryFromTearDown,
+ AllureSampleRegistry.AddStoryFromDispose,
AllureSampleRegistry.LegacyStoryAttributeOnClass,
AllureSampleRegistry.LegacyStoryAttributeOnMethod,
AllureSampleRegistry.LegacyStoryAttributeOnBaseClass,
diff --git a/tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddEpicFromDispose.cs
similarity index 81%
rename from tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs
rename to tests/Allure.Xunit.Tests/Samples/AddEpicFromDispose.cs
index 8d459a2b..13f3747f 100644
--- a/tests/Allure.Xunit.Tests/Samples/AddEpicFromTearDown.cs
+++ b/tests/Allure.Xunit.Tests/Samples/AddEpicFromDispose.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.AddEpicFromTearDown
+namespace Allure.Xunit.Tests.Samples.AddEpicFromDispose
{
public class TestsClass : IDisposable
{
diff --git a/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromDispose.cs
similarity index 81%
rename from tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs
rename to tests/Allure.Xunit.Tests/Samples/AddFeatureFromDispose.cs
index 3af46739..b6108bca 100644
--- a/tests/Allure.Xunit.Tests/Samples/AddFeatureFromTearDown.cs
+++ b/tests/Allure.Xunit.Tests/Samples/AddFeatureFromDispose.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.AddFeatureFromTearDown
+namespace Allure.Xunit.Tests.Samples.AddFeatureFromDispose
{
public class TestsClass : IDisposable
{
diff --git a/tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/AddStoryFromDispose.cs
similarity index 81%
rename from tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs
rename to tests/Allure.Xunit.Tests/Samples/AddStoryFromDispose.cs
index 62817305..23876b7c 100644
--- a/tests/Allure.Xunit.Tests/Samples/AddStoryFromTearDown.cs
+++ b/tests/Allure.Xunit.Tests/Samples/AddStoryFromDispose.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.AddStoryFromTearDown
+namespace Allure.Xunit.Tests.Samples.AddStoryFromDispose
{
public class TestsClass : IDisposable
{
diff --git a/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromDispose.cs
similarity index 80%
rename from tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs
rename to tests/Allure.Xunit.Tests/Samples/SetAllureIdFromDispose.cs
index 5576ef15..139ec4a9 100644
--- a/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromTearDown.cs
+++ b/tests/Allure.Xunit.Tests/Samples/SetAllureIdFromDispose.cs
@@ -2,7 +2,7 @@
using Allure.Net.Commons;
using Xunit;
-namespace Allure.Xunit.Tests.Samples.SetAllureIdFromTearDown
+namespace Allure.Xunit.Tests.Samples.SetAllureIdFromDispose
{
public class TestsClass : IDisposable
{
From f889e9f59e0cd9194568d74d17a4a393ed56f791 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:14:23 +0700
Subject: [PATCH 59/80] test(xunit): add display name tests
---
tests/Allure.Xunit.Tests/NameTests.cs | 58 +++++++++++++++++++
.../Samples/NameAttributeOnClass.cs | 12 ++++
.../Samples/NameAttributeOnMethod.cs | 12 ++++
.../Samples/SetTestNameFromDispose.cs | 17 ++++++
.../Samples/SetTestNameFromTest.cs | 14 +++++
.../Samples/SingleTheory.cs | 11 ++++
.../Samples/XunitDisplayNameOnFact.cs | 11 ++++
.../Samples/XunitDisplayNameOnTheory.cs | 12 ++++
8 files changed, 147 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/NameTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/NameAttributeOnClass.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/NameAttributeOnMethod.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/SetTestNameFromDispose.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/SetTestNameFromTest.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/SingleTheory.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnFact.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnTheory.cs
diff --git a/tests/Allure.Xunit.Tests/NameTests.cs b/tests/Allure.Xunit.Tests/NameTests.cs
new file mode 100644
index 00000000..c152f1d1
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/NameTests.cs
@@ -0,0 +1,58 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class NameTests
+{
+ public static IEnumerable> GetTestRenameSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.SetTestNameFromTest,
+ AllureSampleRegistry.SetTestNameFromDispose,
+ AllureSampleRegistry.NameAttributeOnMethod,
+ AllureSampleRegistry.XunitDisplayNameOnFact,
+ AllureSampleRegistry.XunitDisplayNameOnTheory,
+ ];
+
+ 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 MethodNameIsUsedForTheories()
+ {
+ var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.SingleTheory);
+
+ 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.Xunit.Tests/Samples/NameAttributeOnClass.cs b/tests/Allure.Xunit.Tests/Samples/NameAttributeOnClass.cs
new file mode 100644
index 00000000..6915e4c4
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/NameAttributeOnClass.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.NameAttributeOnClass
+{
+ [AllureName("Lorem Ipsum")]
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/NameAttributeOnMethod.cs b/tests/Allure.Xunit.Tests/Samples/NameAttributeOnMethod.cs
new file mode 100644
index 00000000..e3f68ca8
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/NameAttributeOnMethod.cs
@@ -0,0 +1,12 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.NameAttributeOnMethod
+{
+ public class TestsClass
+ {
+ [Fact]
+ [AllureName("Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/SetTestNameFromDispose.cs b/tests/Allure.Xunit.Tests/Samples/SetTestNameFromDispose.cs
new file mode 100644
index 00000000..500e35f0
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/SetTestNameFromDispose.cs
@@ -0,0 +1,17 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.SetTestNameFromDispose
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod() { }
+
+ public void Dispose()
+ {
+ AllureApi.SetTestName("Lorem Ipsum");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/SetTestNameFromTest.cs b/tests/Allure.Xunit.Tests/Samples/SetTestNameFromTest.cs
new file mode 100644
index 00000000..4dac4485
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/SetTestNameFromTest.cs
@@ -0,0 +1,14 @@
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.SetTestNameFromTest
+{
+ public class TestsClass
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.SetTestName("Lorem Ipsum");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/SingleTheory.cs b/tests/Allure.Xunit.Tests/Samples/SingleTheory.cs
new file mode 100644
index 00000000..fa3bb4ca
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/SingleTheory.cs
@@ -0,0 +1,11 @@
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyNameAttribute
+{
+ public class TestsClass
+ {
+ [Theory]
+ [InlineData(1)]
+ public void TestMethod(int _) { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnFact.cs b/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnFact.cs
new file mode 100644
index 00000000..0a49f0ee
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnFact.cs
@@ -0,0 +1,11 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.XunitDisplayNameOnFact
+{
+ public class TestsClass
+ {
+ [Fact(DisplayName = "Lorem Ipsum")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnTheory.cs b/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnTheory.cs
new file mode 100644
index 00000000..35d4514c
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/XunitDisplayNameOnTheory.cs
@@ -0,0 +1,12 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.XunitDisplayNameOnTheory
+{
+ public class TestsClass
+ {
+ [Theory(DisplayName = "Lorem Ipsum")]
+ [InlineData(1)]
+ public void TestMethod(int foo) { }
+ }
+}
From f982f231d02caa4650aaeb206683e4239d8413eb Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:40:41 +0700
Subject: [PATCH 60/80] test(xunit): add parameter tests
---
src/Allure.Xunit/AllureMessageSink.cs | 6 +-
src/Allure.Xunit/AllureXunitHelper.cs | 40 ++++++++----
tests/Allure.Xunit.Tests/ParameterTests.cs | 61 +++++++++++++++++++
.../Samples/AddTestParameter.cs | 23 +++++++
.../ParameterAttributesOnTheoryParameters.cs | 25 ++++++++
5 files changed, 143 insertions(+), 12 deletions(-)
create mode 100644 tests/Allure.Xunit.Tests/ParameterTests.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddTestParameter.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/ParameterAttributesOnTheoryParameters.cs
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 30c95287..e661a748 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -2,6 +2,7 @@
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;
@@ -90,21 +91,38 @@ 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);
+
+ var parametersList
+ = parameters
+ .Zip(arguments, (param, value) => (
+ param,
+ attr: runtimeParameters.TryGetValue(param.Name, out var pInfo)
+ ? pInfo.GetCustomAttribute()
+ : null,
+ value))
+ .Where(static (p) => p.attr?.Ignore != true)
+ .Select(static (p) => new Parameter
+ {
+ name = p.attr?.Name ?? p.param.Name,
+ value = FormatFunctions.Format(
+ p.value,
+ AllureLifecycle.Instance.TypeFormatters
+ ),
+ mode = p.attr?.Mode is not ParameterMode.Default
+ ? p.attr?.Mode
+ : null,
+ excluded = p.attr?.Excluded == true,
+ })
+ .ToList();
AllureLifecycle.Instance.UpdateTestCase(testResult =>
{
diff --git a/tests/Allure.Xunit.Tests/ParameterTests.cs b/tests/Allure.Xunit.Tests/ParameterTests.cs
new file mode 100644
index 00000000..e69d67bb
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/ParameterTests.cs
@@ -0,0 +1,61 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.Tests;
+
+class ParameterTests
+{
+ public static IEnumerable> GetParameterSamples()
+ {
+ IEnumerable samples = [
+ AllureSampleRegistry.AddTestParameter,
+ AllureSampleRegistry.ParameterAttributesOnTheoryParameters,
+ ];
+
+ return samples.Select(static (sample) =>
+ new TestDataRow(sample, DisplayName: sample.Id));
+ }
+
+ [Test]
+ [MethodDataSource(nameof(GetParameterSamples))]
+ public async Task ParametersApiWorks(AllureSampleRegistryEntry sample)
+ {
+ var results = await AllureSampleRunner.RunAsync(sample);
+
+ await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1);
+
+ var parameters = results.TestResults[0]["parameters"].AsArray().Cast().ToList();
+
+ 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
+ );
+ 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
+ );
+ 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(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
+ );
+ }
+}
\ No newline at end of file
diff --git a/tests/Allure.Xunit.Tests/Samples/AddTestParameter.cs b/tests/Allure.Xunit.Tests/Samples/AddTestParameter.cs
new file mode 100644
index 00000000..8aa90de9
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddTestParameter.cs
@@ -0,0 +1,23 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddTestParameters
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddTestParameter("name1", "value-1");
+ AllureApi.AddTestParameter("name2", "value-2", ParameterMode.Masked);
+ AllureApi.AddTestParameter("name3", "value-3", ParameterMode.Hidden);
+ AllureApi.AddTestParameter("name4", "value-4", excluded: true);
+ }
+
+ public void Dispose()
+ {
+ AllureApi.AddTestParameter("name5", "value-5", ParameterMode.Masked, true);
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/ParameterAttributesOnTheoryParameters.cs b/tests/Allure.Xunit.Tests/Samples/ParameterAttributesOnTheoryParameters.cs
new file mode 100644
index 00000000..e20de5e0
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/ParameterAttributesOnTheoryParameters.cs
@@ -0,0 +1,25 @@
+using Allure.Net.Commons;
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+#pragma warning disable xUnit1026
+
+namespace Allure.Xunit.Tests.Samples.ParameterAttributesOnTheoryParameters
+{
+ public class TestsClass
+ {
+ [Theory]
+ [InlineData("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
+ )
+ {
+ _ = name1 = ignored = renamed1 = name3 = name4 = renamed2;
+ }
+ }
+}
From 18952c7680e4db94846386368e6b3d20908ca802 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:42:25 +0700
Subject: [PATCH 61/80] fix(xunit): don't overwrite dynamic parameters
---
src/Allure.Xunit/AllureXunitHelper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index e661a748..a1c306b8 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -126,7 +126,7 @@ var parametersList
AllureLifecycle.Instance.UpdateTestCase(testResult =>
{
- testResult.parameters = parametersList;
+ testResult.parameters = [..parametersList, ..testResult.parameters];
});
}
From 683d5343aed726e6dcfd6fa1e46afa7b048e82ad Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Mon, 2 Feb 2026 17:49:38 +0700
Subject: [PATCH 62/80] test(xunit): add tag tests
---
.../Samples/AddTagsApiCalls.cs | 20 +++++++
.../Samples/LegacyTagAttributes.cs | 16 ++++++
.../Samples/TagAttributes.cs | 19 +++++++
tests/Allure.Xunit.Tests/TagTests.cs | 56 +++++++++++++++++++
4 files changed, 111 insertions(+)
create mode 100644 tests/Allure.Xunit.Tests/Samples/AddTagsApiCalls.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/LegacyTagAttributes.cs
create mode 100644 tests/Allure.Xunit.Tests/Samples/TagAttributes.cs
create mode 100644 tests/Allure.Xunit.Tests/TagTests.cs
diff --git a/tests/Allure.Xunit.Tests/Samples/AddTagsApiCalls.cs b/tests/Allure.Xunit.Tests/Samples/AddTagsApiCalls.cs
new file mode 100644
index 00000000..6d1979cc
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/AddTagsApiCalls.cs
@@ -0,0 +1,20 @@
+using System;
+using Allure.Net.Commons;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.AddTagsApiCalls
+{
+ public class TestsClass : IDisposable
+ {
+ [Fact]
+ public void TestMethod()
+ {
+ AllureApi.AddTags("foo", "bar");
+ }
+
+ public void Dispose()
+ {
+ AllureApi.AddTags("baz");
+ }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/LegacyTagAttributes.cs b/tests/Allure.Xunit.Tests/Samples/LegacyTagAttributes.cs
new file mode 100644
index 00000000..8e8d8870
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/LegacyTagAttributes.cs
@@ -0,0 +1,16 @@
+using Allure.Xunit.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.LegacyTagAttributes
+{
+ [AllureTag("foo")]
+ public class BaseClass { }
+
+ [AllureTag("bar")]
+ public class TestsClass : BaseClass
+ {
+ [Fact]
+ [AllureTag("baz", "qux")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/Samples/TagAttributes.cs b/tests/Allure.Xunit.Tests/Samples/TagAttributes.cs
new file mode 100644
index 00000000..1440103f
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/Samples/TagAttributes.cs
@@ -0,0 +1,19 @@
+using Allure.Net.Commons.Attributes;
+using Xunit;
+
+namespace Allure.Xunit.Tests.Samples.TagAttributes
+{
+ [AllureTag("foo")]
+ public interface IMetadata { }
+
+ [AllureTag("bar")]
+ public class BaseClass { }
+
+ [AllureTag("baz")]
+ public class TestsClass : BaseClass, IMetadata
+ {
+ [Fact]
+ [AllureTag("qux", "qut")]
+ public void TestMethod() { }
+ }
+}
diff --git a/tests/Allure.Xunit.Tests/TagTests.cs b/tests/Allure.Xunit.Tests/TagTests.cs
new file mode 100644
index 00000000..195dab80
--- /dev/null
+++ b/tests/Allure.Xunit.Tests/TagTests.cs
@@ -0,0 +1,56 @@
+using System.Text.Json.Nodes;
+using Allure.Testing;
+
+namespace Allure.Xunit.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"],
+ 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(["bar", "baz", "qux"]);
+ }
+}
From 1475fa2323e85a71e3eb3f362a4251b7b68d1c0a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 4 Feb 2026 20:58:27 +0700
Subject: [PATCH 63/80] feat(commons): add non-reflection overload of
CreateParameters
---
.../Functions/ModelFunctions.cs | 83 ++++--
.../CreateParametersExplicitTests.cs | 252 ++++++++++++++++++
.../CreateParametersReflectionTests.cs} | 10 +-
3 files changed, 315 insertions(+), 30 deletions(-)
create mode 100644 tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersExplicitTests.cs
rename tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/{ParameterTests.cs => CreateParametersTests.cs/CreateParametersReflectionTests.cs} (96%)
diff --git a/src/Allure.Net.Commons/Functions/ModelFunctions.cs b/src/Allure.Net.Commons/Functions/ModelFunctions.cs
index 8be3c952..99312a1e 100644
--- a/src/Allure.Net.Commons/Functions/ModelFunctions.cs
+++ b/src/Allure.Net.Commons/Functions/ModelFunctions.cs
@@ -162,35 +162,66 @@ public static IEnumerable CreateParameters(
IEnumerable values,
IReadOnlyDictionary formatters
)
- {
- var pairs = parameters.Zip(values, static (p, v) => (p, v));
- foreach (var (parameter, value) in parameters.Zip(values, static (p, v) => (p, v)))
- {
- var attr = parameter.GetCustomAttribute();
- if (attr?.Ignore == true)
- {
- continue;
- }
+ => CreateParameters(
+ parameters.Select(static (p) => p.Name),
+ parameters.Select(static (p) => p.GetCustomAttribute()),
+ values,
+ formatters
+ );
- var name = attr?.Name;
- var mode = attr?.Mode;
- var excluded = attr?.Excluded == true;
-
- Parameter allureParameter = new()
- {
- name = attr?.Name ?? parameter.Name,
- value = FormatFunctions.Format(value, formatters),
- excluded = attr?.Excluded == true
- };
+ ///
+ /// 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));
- if (mode is not null and not ParameterMode.Default)
- {
- allureParameter.mode = attr?.Mode;
- }
+ 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)
+ };
- yield return allureParameter;
- }
- }
+ static ParameterMode? ResolveParameterMode(AllureParameterAttribute? attribute)
+ => attribute is AllureParameterAttribute { Mode: ParameterMode mode and not ParameterMode.Default }
+ ? mode
+ : null;
static bool ShouldAddEnvVarAsLabel(
[NotNullWhen(true)] string? name,
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/ParameterTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs
similarity index 96%
rename from tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs
rename to tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs
index 98f8339f..435839e0 100644
--- a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs
+++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/CreateParametersTests.cs/CreateParametersReflectionTests.cs
@@ -5,13 +5,15 @@
using Allure.Net.Commons.Functions;
using NUnit.Framework;
-namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests;
+namespace Allure.Net.Commons.Tests.FunctionTests.ModelFunctionTests.CreateParametersTests.cs;
-class ParameterTests
+class CreateParametersReflectionTests
{
- static ParameterTests()
+ static CreateParametersReflectionTests()
{
- var parameters = typeof(ParameterTests).GetMethod(nameof(Target)).GetParameters();
+ var parameters
+ = typeof(CreateParametersReflectionTests)
+ .GetMethod(nameof(Target)).GetParameters();
NoAttribute = parameters[0];
NoEffect = parameters[1];
From 6471278abe93b62f1a85ec075e853a8b10b7e5d1 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Wed, 4 Feb 2026 20:59:08 +0700
Subject: [PATCH 64/80] refactor(xunit): reuse CreateParameters
---
src/Allure.Xunit/AllureXunitHelper.cs | 34 ++++++++++-----------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index a1c306b8..db0aee88 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -101,32 +101,22 @@ var runtimeParameters
.GetParameters()
.ToDictionary(static (p) => p.Name);
- var parametersList
- = parameters
- .Zip(arguments, (param, value) => (
- param,
- attr: runtimeParameters.TryGetValue(param.Name, out var pInfo)
+ Parameter[] parametersFromMethod = [
+ ..ModelFunctions.CreateParameters(
+ parameters.Select(static (p) => p.Name),
+ parameters.Select((p) =>
+ runtimeParameters.TryGetValue(p.Name, out var pInfo)
? pInfo.GetCustomAttribute()
- : null,
- value))
- .Where(static (p) => p.attr?.Ignore != true)
- .Select(static (p) => new Parameter
- {
- name = p.attr?.Name ?? p.param.Name,
- value = FormatFunctions.Format(
- p.value,
- AllureLifecycle.Instance.TypeFormatters
- ),
- mode = p.attr?.Mode is not ParameterMode.Default
- ? p.attr?.Mode
- : null,
- excluded = p.attr?.Excluded == true,
- })
- .ToList();
+ : null),
+ arguments,
+ AllureLifecycle.Instance.TypeFormatters
+ )
+ ];
AllureLifecycle.Instance.UpdateTestCase(testResult =>
{
- testResult.parameters = [..parametersList, ..testResult.parameters];
+ var dynamicParameters = testResult.parameters;
+ testResult.parameters = [..parametersFromMethod, ..dynamicParameters];
});
}
From d1b9ec1e5ccd9e1f14feaf601543aa6536efa6d3 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 02:21:52 +0700
Subject: [PATCH 65/80] fix(commons): use link as the default link type when
matching a template
---
src/Allure.Net.Commons/Helpers/LinkHelper.cs | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
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);
}
}
}
From 5c08532c357ec9af13bee015ddd22d1994d540fa Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 03:55:07 +0700
Subject: [PATCH 66/80] feat(commons): attachments from streams
---
.../Attributes/AllureAttachmentAttribute.cs | 15 ++--
.../Sdk/Aspects/AllureAttachmentAspect.cs | 30 ++++++-
.../AttributeTests/AttachmentTests.cs | 80 +++++++++++++++++++
3 files changed, 117 insertions(+), 8 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
index c738c236..ecc677a0 100644
--- a/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureAttachmentAttribute.cs
@@ -7,8 +7,10 @@
namespace Allure.Net.Commons.Attributes;
///
-/// When applied to a function returning byte[] or string, creates an attachment
-/// from the function's return value each time it's called.
+/// 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)]
@@ -16,7 +18,7 @@ public class AllureAttachmentAttribute : Attribute
{
///
/// A name of the attachment to display in the report. The {paramName} placeholders can
- /// be used to interpolate the function's arguments into the name.
+ /// be used to interpolate the method's arguments into the name.
///
public string? Name { get; }
@@ -43,17 +45,18 @@ public class AllureAttachmentAttribute : Attribute
/// UTF-8 is used.
///
///
- /// If the function returns byte[], this property has no effect.
+ /// If the method returns a type other than string (or its async counterpart),
+ /// this property has no effect.
///
public string? Encoding { get; init; }
///
- /// Sets up the target function to create an attachment with the same name as the function.
+ /// Creates attachments named after the method.
///
public AllureAttachmentAttribute() { }
///
- /// Sets up the target function to create an explicitly named attachment.
+ /// Creates attachments with explicit names. Argument interpolation is supported.
///
///
/// The attachment's name. Use the {paramName} placeholders to interpolate the
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
index 7299d970..22922dea 100644
--- a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Reflection;
using System.Text;
using Allure.Net.Commons.Attributes;
@@ -58,12 +59,37 @@ var extension
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 attachment from {returnValue.GetType().Name}. "
- + "String or byte[] expected."
+ $"Can't create an Allure attachment from {returnValue.GetType().FullName}. "
+ + "A string, byte[], or stream was expected."
)
};
AllureApi.AddAttachmentInternal(attachmentName, contentType, content, extension);
}
+
+ 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/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
index e6a1fd4a..f888715b 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Threading.Tasks;
using Allure.Net.Commons.Attributes;
using Allure.Net.Commons.Functions;
@@ -53,6 +54,63 @@ public void CreatesAttachmentFromString()
"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()
{
@@ -191,6 +249,28 @@ public void NoEffectIfNoContextActive()
[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";
From d8a263152df340e41ab130b15331b558b2d38cea Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 04:39:25 +0700
Subject: [PATCH 67/80] refactor(commons): extract methods in attachment aspect
---
.../Sdk/Aspects/AllureAttachmentAspect.cs | 85 +++++++++++--------
1 file changed, 51 insertions(+), 34 deletions(-)
diff --git a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
index 22922dea..b9aedb62 100644
--- a/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
+++ b/src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentAspect.cs
@@ -4,6 +4,7 @@
using System.Text;
using Allure.Net.Commons.Attributes;
using AspectInjector.Broker;
+using HeyRed.Mime;
#nullable enable
@@ -30,45 +31,61 @@ public void AttachReturnValue(
}
var attr = metadata.GetCustomAttribute();
- var attachmentName
- = string.IsNullOrEmpty(attr?.Name)
- ? name
- : Steps.AllureStepParameterHelper.GetStepName(
- attr!.Name,
- metadata,
- arguments,
- AllureApi.CurrentLifecycle.TypeFormatters
- );
- var contentType
- = attr?.ContentType
- ?? (returnType == typeof(string)
- ? "text/plain"
- : null);
- var extension
- = attr?.Extension
- ?? (contentType is null ? "" : HeyRed.Mime.MimeTypesMap.GetExtension(contentType))
- ?? "";
- extension
- = extension.Length == 0 || extension.StartsWith(".")
- ? extension
- : $".{extension}";
-
- byte[] content = returnValue 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 {returnValue.GetType().FullName}. "
- + "A string, byte[], or stream was expected."
- )
- };
+ 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)
From a138957b95984677dafcd4391279b21eb2d8bf5e Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 04:39:56 +0700
Subject: [PATCH 68/80] feat(commons): add [AllureAttachmentFile]
---
.../AllureAttachmentFileAttribute.cs | 51 ++++
.../Sdk/Aspects/AllureAttachmentFileAspect.cs | 79 ++++++
.../AttributeTests/AttachmentFileTests.cs | 245 ++++++++++++++++++
3 files changed, 375 insertions(+)
create mode 100644 src/Allure.Net.Commons/Attributes/AllureAttachmentFileAttribute.cs
create mode 100644 src/Allure.Net.Commons/Sdk/Aspects/AllureAttachmentFileAspect.cs
create mode 100644 tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttachmentFileTests.cs
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/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/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();
+}
From dbaaa0b8bfc5a267bc1bda565a08b4396cc746eb Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 04:40:46 +0700
Subject: [PATCH 69/80] docs(commons): fix runtime API list
---
src/Allure.Net.Commons/README.md | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/Allure.Net.Commons/README.md b/src/Allure.Net.Commons/README.md
index e7a19f6a..2fe0ee5b 100644
--- a/src/Allure.Net.Commons/README.md
+++ b/src/Allure.Net.Commons/README.md
@@ -116,10 +116,8 @@ functions.
* `SetStepName`
* `SetDescription`
* `SetDescriptionHtml`
-* `SetDescriptionHtml`
* `AddLabels`
* `AddLabel`
-* `SetLabel`
* `SetSeverity`
* `SetOwner`
* `SetAllureId`
@@ -132,17 +130,11 @@ functions.
#### Hierrarchies
* `AddParentSuite`
-* `SetParentSuite`
* `AddSuite`
-* `SetSuite`
* `AddSubSuite`
-* `SetSubSuite`
* `AddEpic`
-* `SetEpic`
* `AddFeature`
-* `SetFeature`
* `AddStory`
-* `SetStory`
#### Lambda steps
From 4081f7737276aeda4acf8f03ce014bdd334a0987 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 04:41:41 +0700
Subject: [PATCH 70/80] docs(commons): document Attribute API
---
src/Allure.Net.Commons/README.md | 179 ++++++++++++++++++++++++++++++-
1 file changed, 178 insertions(+), 1 deletion(-)
diff --git a/src/Allure.Net.Commons/README.md b/src/Allure.Net.Commons/README.md
index 2fe0ee5b..5b57e8e6 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 set up 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.
@@ -200,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
From cd632167457122eb543ae079243cc828e5c957f6 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 13:42:26 +0700
Subject: [PATCH 71/80] test(commons): fix test on empty type link
---
tests/Allure.Net.Commons.Tests/LinkHelperTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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"));
From afe232d46f8594dfff265e4e5da3f4c531756a7b Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 15:37:12 +0700
Subject: [PATCH 72/80] refactor(commons): simplify RunInContextAsync around
context isolation
---
src/Allure.Net.Commons/AllureLifecycle.cs | 13 +++----------
.../Allure.Net.Commons.Tests/AllureLifeCycleTest.cs | 4 +++-
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/src/Allure.Net.Commons/AllureLifecycle.cs b/src/Allure.Net.Commons/AllureLifecycle.cs
index ed521b2d..ace03d84 100644
--- a/src/Allure.Net.Commons/AllureLifecycle.cs
+++ b/src/Allure.Net.Commons/AllureLifecycle.cs
@@ -202,16 +202,9 @@ public async Task RunInContextAsync(AllureContext? context, Func asyncActi
return;
}
- var originalContext = this.Context;
- try
- {
- this.Context = context;
- await asyncAction();
- }
- finally
- {
- this.Context = originalContext;
- }
+ // This change will be discarded once the method exits because it's async.
+ this.Context = context;
+ await asyncAction();
}
///
diff --git a/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
index b0f77bb9..4ecb326c 100644
--- a/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
+++ b/tests/Allure.Net.Commons.Tests/AllureLifeCycleTest.cs
@@ -183,14 +183,16 @@ await Task.Factory.StartNew(() =>
});
context = lifecycle.Context;
});
+
await lifecycle.RunInContextAsync(context, async () =>
{
lifecycle.StopTestCase();
- await Task.Delay(1);
+ await Task.Yield();
lifecycle.WriteTestCase();
});
Assert.That(writer.testResults, Is.Not.Empty);
+ Assert.That(lifecycle.Context.HasTest, Is.False);
}
[Test]
From 48fe25dd39016cc22e8b75c5be535c1d5964da92 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 16:00:45 +0700
Subject: [PATCH 73/80] docs(commons): fix inaccurate attr application
descriptions
---
.../Attributes/AllureDescriptionAttribute.cs | 2 +-
.../Attributes/AllureDescriptionHtmlAttribute.cs | 2 +-
src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
index 7499bdb9..d6cce5a5 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -26,7 +26,7 @@ public class AllureDescriptionAttribute(string markdownText) : AllureMetadataAtt
/// the attributes are applied:
///
/// - Interfaces before classes/structs.
- /// - Base classes/structs before derived classes/structs.
+ /// - Base classes before derived classes.
/// - Classes/structs before methods.
/// - Base methods before method overrides.
///
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
index 6a809ec6..dfd7e763 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
@@ -32,7 +32,7 @@ public class AllureDescriptionHtmlAttribute(string htmlText) : AllureMetadataAtt
/// the attributes are applied:
///
/// - Interfaces before classes/structs.
- /// - Base classes/structs before derived classes/structs.
+ /// - Base classes before derived classes.
/// - Classes/structs before methods.
/// - Base methods before method overrides.
///
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index 44cce58d..3b6faba9 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -46,7 +46,7 @@ public static IEnumerable GetMethodAttributes(MethodInf
///
/// - Attributes of interfaces before attributes of classes/structs.
/// -
- /// Attributes of base classes/structs before attributes of derived classes/structs.
+ /// Attributes of base classes before attributes of derived classes.
///
///
///
@@ -69,7 +69,7 @@ public static IEnumerable GetTypeAttributes(Type type)
///
/// - Attributes of interfaces before attributes of classes/structs.
/// -
- /// Attributes of base classes/structs before attributes of derived 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.
@@ -105,7 +105,7 @@ public static void ApplyMethodAttributes(TestResult testResult, MethodInfo metho
/// The following is guaranteed about the order of application:
///
/// - Interfaces are handled before classes/structs.
- /// - Base classes/structs are handled before derived classes/structs.
+ /// - Base classes are handled before derived classes.
///
///
public static void ApplyTypeAttributes(TestResult testResult, Type type)
@@ -124,7 +124,7 @@ public static void ApplyTypeAttributes(TestResult testResult, Type type)
/// The following is guaranteed about the order of application:
///
/// - Interfaces are handled before classes/structs.
- /// - Base classes/structs are handled before derived classes/structs.
+ /// - Base classes are handled before derived classes.
/// - Classes/structs are handled before methods
/// - Base methods are handled before methods overrides.
///
From 07dd6f21d213af8418f6ab07b3b9995b19ad23f9 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 16:23:14 +0700
Subject: [PATCH 74/80] chore(xunit): fix false positive null check
---
src/Allure.Xunit/AllureXunitHelper.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index db0aee88..702dc3e9 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -146,7 +146,7 @@ internal static void ApplyDefaultSuites(ITestMethod method)
?.Name)
?? (string.IsNullOrEmpty(@namespace)
? xunitTestClass.Name
- : xunitTestClass.Name?.Substring(@namespace.Length + 1));
+ : xunitTestClass.Name?.Substring(@namespace!.Length + 1));
internal static void ReportCurrentTestCase()
{
From c1889dc623f2f41aa1028742ff8fbd82741b2110 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 18:26:22 +0700
Subject: [PATCH 75/80] docs(nunit): add attributes API info to readme
---
src/Allure.NUnit/README.md | 150 ++++++++++++++++++++++++++++++++++++-
1 file changed, 149 insertions(+), 1 deletion(-)
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
From dd32b5ac31459e25d4be214956a2032fc4d8e885 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Thu, 5 Feb 2026 18:26:43 +0700
Subject: [PATCH 76/80] docs(xunit): add attributes API info to readme
---
src/Allure.Xunit/README.md | 157 ++++++++++++++++++++++++++++++++++++-
1 file changed, 156 insertions(+), 1 deletion(-)
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
From c0cea434f8b380f89550d03f14c9facf08901ba8 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:01:07 +0700
Subject: [PATCH 77/80] docs: set up fixture -> setup fixture
---
src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs | 6 +++---
src/Allure.Net.Commons/README.md | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
index 6d329b95..8ada34a6 100644
--- a/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureBeforeAttribute.cs
@@ -5,19 +5,19 @@
namespace Allure.Net.Commons.Attributes;
///
-/// Wraps each call of the method in a set up fixture.
+/// 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 set up fixture using the method's
+ /// 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 set up fixture.
+ /// 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
diff --git a/src/Allure.Net.Commons/README.md b/src/Allure.Net.Commons/README.md
index 5b57e8e6..9e178d33 100644
--- a/src/Allure.Net.Commons/README.md
+++ b/src/Allure.Net.Commons/README.md
@@ -109,7 +109,7 @@ Use the attributes defined in the `Allure.Net.Commons.Attributes` namespaces:
|`[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 set up fixture from the method or constructor call. |Method, constructor. |Uses AspectInjector under the hood.|
+|`[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.|
From b7d9afb47eae08072c6572695bfe7fee8ea2c76a Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:48:34 +0700
Subject: [PATCH 78/80] feat(commons): skip class AllureName application on
commons level
---
src/Allure.NUnit/Core/AllureNUnitHelper.cs | 6 +-----
.../Sdk/AllureMetadataAttribute.cs | 13 ++++++++-----
src/Allure.Xunit/AllureXunitHelper.cs | 6 +-----
.../AttributeApplicationTests.cs | 19 +++++++++++++++++++
4 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index 408f83b5..f9458f0e 100644
--- a/src/Allure.NUnit/Core/AllureNUnitHelper.cs
+++ b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
@@ -276,12 +276,8 @@ static void AddTestParametersFromNUnit(ITest test, TestResult testResult)
static void ApplyAllureAttributes(ITest test, TestResult testResult)
{
var testFixtureClass = GetTestFixture(test).TypeInfo.Type;
- var testFixtureAttributes
- = AllureMetadataAttribute
- .GetTypeAttributes(testFixtureClass)
- .Where(static (a) => a is not AllureNameAttribute);
- AllureMetadataAttribute.ApplyAttributes(testResult, testFixtureAttributes);
+ AllureMetadataAttribute.ApplyTypeAttributes(testResult, testFixtureClass);
AllureMetadataAttribute.ApplyMethodAttributes(testResult, test.Method.MethodInfo);
}
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
index 3b6faba9..046a66ce 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Allure.Net.Commons.Attributes;
#nullable enable
@@ -110,7 +111,11 @@ public static void ApplyMethodAttributes(TestResult testResult, MethodInfo metho
///
public static void ApplyTypeAttributes(TestResult testResult, Type type)
{
- foreach (var attr in GetTypeAttributes(type))
+ var typeAttributesToApply
+ = GetTypeAttributes(type)
+ .Where(static (a) => a is not AllureNameAttribute);
+
+ foreach (var attr in typeAttributesToApply)
{
attr.Apply(testResult);
}
@@ -131,10 +136,8 @@ public static void ApplyTypeAttributes(TestResult testResult, Type type)
///
public static void ApplyAllAttributes(TestResult testResult, MethodInfo method)
{
- foreach (var attr in GetAllAttributes(method))
- {
- attr.Apply(testResult);
- }
+ ApplyTypeAttributes(testResult, method.DeclaringType);
+ ApplyMethodAttributes(testResult, method);
}
///
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index 702dc3e9..cd44b2c1 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -264,12 +264,8 @@ static void ApplyAllureAttributes(TestResult testResult, ITestMethod xunitTestMe
{
var method = xunitTestMethod.Method.ToRuntimeMethod();
var testClass = xunitTestMethod.TestClass.Class.ToRuntimeType();
- var testClassAttributes
- = AllureMetadataAttribute
- .GetTypeAttributes(testClass)
- .Where(static (a) => a is not AllureNameAttribute);
- AllureMetadataAttribute.ApplyAttributes(testResult, testClassAttributes);
+ AllureMetadataAttribute.ApplyTypeAttributes(testResult, testClass);
AllureMetadataAttribute.ApplyMethodAttributes(testResult, method);
}
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
index 422abf47..6888639e 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
@@ -378,6 +378,19 @@ public void ReturnsAllAttributesToMethodAndItsTypeAtOnce()
);
}
+ [Test]
+ public void AllureNameFromTypeNotApplied()
+ {
+ TestResult tr = new();
+ var type = typeof(WithAllureNameOnType);
+ var method = type.GetMethod(nameof(WithAllureNameOnType.TargetMethod));
+
+ AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(WithAllureNameOnType));
+ AllureMetadataAttribute.ApplyAllAttributes(tr, method);
+
+ Assert.That(tr.name, Is.Null);
+ }
+
#region Types to check attribute application to methods
abstract class MethodsWithAttrsBase
@@ -428,6 +441,12 @@ class InheritedFromInterfaceAttributes : IInterfaceWithAttributes { }
[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
From 747c9b89f98fd250517587c9c538c74896f2265e Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:54:41 +0700
Subject: [PATCH 79/80] feat(commons): rename base attribute to
AllureApiAttribute
---
src/Allure.NUnit/Core/AllureNUnitHelper.cs | 6 +-
.../Attributes/AllureBddHierarchyAttribute.cs | 2 +-
.../Attributes/AllureDescriptionAttribute.cs | 2 +-
.../AllureDescriptionHtmlAttribute.cs | 2 +-
.../Attributes/AllureIssueAttribute.cs | 2 +-
.../Attributes/AllureLabelAttribute.cs | 2 +-
.../Attributes/AllureLinkAttribute.cs | 2 +-
.../Attributes/AllureMetaAttribute.cs | 6 +-
.../Attributes/AllureNameAttribute.cs | 2 +-
.../AllureSuiteHierarchyAttribute.cs | 2 +-
.../Attributes/AllureTagAttribute.cs | 2 +-
.../Attributes/AllureTmsItemAttribute.cs | 2 +-
...dataAttribute.cs => AllureApiAttribute.cs} | 16 ++---
src/Allure.Xunit/AllureXunitHelper.cs | 6 +-
.../AttributeApplicationTests.cs | 64 +++++++++----------
15 files changed, 59 insertions(+), 59 deletions(-)
rename src/Allure.Net.Commons/Sdk/{AllureMetadataAttribute.cs => AllureApiAttribute.cs} (89%)
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index f9458f0e..5bd0ae02 100644
--- a/src/Allure.NUnit/Core/AllureNUnitHelper.cs
+++ b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
@@ -277,8 +277,8 @@ static void ApplyAllureAttributes(ITest test, TestResult testResult)
{
var testFixtureClass = GetTestFixture(test).TypeInfo.Type;
- AllureMetadataAttribute.ApplyTypeAttributes(testResult, testFixtureClass);
- AllureMetadataAttribute.ApplyMethodAttributes(testResult, test.Method.MethodInfo);
+ AllureApiAttribute.ApplyTypeAttributes(testResult, testFixtureClass);
+ AllureApiAttribute.ApplyMethodAttributes(testResult, test.Method.MethodInfo);
}
static void ApplyLegacyAllureAttributes(ITest test, TestResult testResult)
@@ -309,7 +309,7 @@ static string GetNamespace(string classFullName)
}
static string ResolveSubSuite(TestFixture testFixture)
- => AllureMetadataAttribute
+ => AllureApiAttribute
.GetTypeAttributes(testFixture.TypeInfo.Type)
.OfType()
.LastOrDefault()
diff --git a/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
index 43a2c6c5..43d45ade 100644
--- a/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureBddHierarchyAttribute.cs
@@ -9,7 +9,7 @@ namespace Allure.Net.Commons.Attributes;
/// Applies the whole BDD hierarchy at once.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
-public class AllureBddHierarchyAttribute : AllureMetadataAttribute
+public class AllureBddHierarchyAttribute : AllureApiAttribute
{
///
/// Value for the epic label.
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
index d6cce5a5..ab6e0c60 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionAttribute.cs
@@ -10,7 +10,7 @@ namespace Allure.Net.Commons.Attributes;
///
/// A description text. Markdown is supported.
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureDescriptionAttribute(string markdownText) : AllureMetadataAttribute
+public class AllureDescriptionAttribute(string markdownText) : AllureApiAttribute
{
///
/// Description text in Markdown format.
diff --git a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
index dfd7e763..4752e4a9 100644
--- a/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureDescriptionHtmlAttribute.cs
@@ -13,7 +13,7 @@ namespace Allure.Net.Commons.Attributes;
///
/// A description text in HTML.
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureDescriptionHtmlAttribute(string htmlText) : AllureMetadataAttribute
+public class AllureDescriptionHtmlAttribute(string htmlText) : AllureApiAttribute
{
///
/// Description text in HTML.
diff --git a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
index ddf50914..6262771d 100644
--- a/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureIssueAttribute.cs
@@ -13,7 +13,7 @@ namespace Allure.Net.Commons.Attributes;
/// exists in the configuration.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureIssueAttribute(string issueIdOrUrl) : AllureMetadataAttribute
+public class AllureIssueAttribute(string issueIdOrUrl) : AllureApiAttribute
{
///
/// The ID of the issue or its full URL.
diff --git a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
index fa18e073..ff2ef2ab 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLabelAttribute.cs
@@ -11,7 +11,7 @@ namespace Allure.Net.Commons.Attributes;
/// A label's name.
/// A label's value.
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureLabelAttribute(string name, string value) : AllureMetadataAttribute
+public class AllureLabelAttribute(string name, string value) : AllureApiAttribute
{
///
/// The name of the label.
diff --git a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
index 2af6bcad..9c64c5ca 100644
--- a/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureLinkAttribute.cs
@@ -13,7 +13,7 @@ namespace Allure.Net.Commons.Attributes;
/// the link's type must exist in the configuration.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureLinkAttribute(string url) : AllureMetadataAttribute
+public class AllureLinkAttribute(string url) : AllureApiAttribute
{
///
/// The URL of the link.
diff --git a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
index 8d2966f3..91d22ca7 100644
--- a/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureMetaAttribute.cs
@@ -9,14 +9,14 @@ namespace Allure.Net.Commons.Attributes;
///
/// Applies all the attributes applied to its subclass, serving as a shortcut for them.
///
-public abstract class AllureMetaAttribute : AllureMetadataAttribute
+public abstract class AllureMetaAttribute : AllureApiAttribute
{
- private readonly AllureMetadataAttribute[] attributes;
+ private readonly AllureApiAttribute[] attributes;
public AllureMetaAttribute()
{
this.attributes = [
- ..this.GetType().GetCustomAttributes(true),
+ ..this.GetType().GetCustomAttributes(true),
];
}
diff --git a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
index 96d331b4..de1d83c0 100644
--- a/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureNameAttribute.cs
@@ -13,7 +13,7 @@ namespace Allure.Net.Commons.Attributes;
AllowMultiple = false,
Inherited = false
)]
-public class AllureNameAttribute(string name) : AllureMetadataAttribute
+public class AllureNameAttribute(string name) : AllureApiAttribute
{
///
/// The provided name.
diff --git a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
index cf8936ee..7b75ae0b 100644
--- a/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureSuiteHierarchyAttribute.cs
@@ -9,7 +9,7 @@ namespace Allure.Net.Commons.Attributes;
/// Applies the whole suite hierarchy at once.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = false, Inherited = true)]
-public class AllureSuiteHierarchyAttribute : AllureMetadataAttribute
+public class AllureSuiteHierarchyAttribute : AllureApiAttribute
{
///
/// The value of the parentSuite label.
diff --git a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
index ba845617..1bd4bf74 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTagAttribute.cs
@@ -12,7 +12,7 @@ namespace Allure.Net.Commons.Attributes;
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
public class AllureTagAttribute(string tag, params string[] moreTags)
- : AllureMetadataAttribute
+ : AllureApiAttribute
{
///
/// The provided tags.
diff --git a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
index 2c95f7b6..b11760bf 100644
--- a/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
+++ b/src/Allure.Net.Commons/Attributes/AllureTmsItemAttribute.cs
@@ -13,7 +13,7 @@ namespace Allure.Net.Commons.Attributes;
/// exists in the configuration.
///
[AttributeUsage(ALLURE_METADATA_TARGETS, AllowMultiple = true, Inherited = true)]
-public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureMetadataAttribute
+public class AllureTmsItemAttribute(string tmsItemIdOrUrl) : AllureApiAttribute
{
///
/// The ID of the TMS item or its full URL.
diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
similarity index 89%
rename from src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
rename to src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
index 046a66ce..b441e11b 100644
--- a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
@@ -11,7 +11,7 @@ namespace Allure.Net.Commons.Sdk;
///
/// A base class for attributes that apply metadata to test results.
///
-public abstract class AllureMetadataAttribute : Attribute
+public abstract class AllureApiAttribute : Attribute
{
///
/// Default targets for Allure metadata attributes.
@@ -34,9 +34,9 @@ public const AttributeTargets ALLURE_METADATA_TARGETS
/// Attributes of the base methods (virtual or abstract) are guaranteed to appear
/// before attributes of the derived ones.
///
- public static IEnumerable GetMethodAttributes(MethodInfo method)
+ public static IEnumerable GetMethodAttributes(MethodInfo method)
=> method
- .GetCustomAttributes()
+ .GetCustomAttributes()
.Reverse();
///
@@ -51,14 +51,14 @@ public static IEnumerable GetMethodAttributes(MethodInf
///
///
///
- public static IEnumerable GetTypeAttributes(Type type)
+ public static IEnumerable GetTypeAttributes(Type type)
=> type
- .GetCustomAttributes()
+ .GetCustomAttributes()
.Concat(
type
.GetInterfaces()
.SelectMany(static (iFace) =>
- iFace.GetCustomAttributes()))
+ iFace.GetCustomAttributes()))
.Reverse();
///
@@ -76,7 +76,7 @@ public static IEnumerable GetTypeAttributes(Type type)
/// - Attributes of base methods before attributes of methods overrides.
///
///
- public static IEnumerable GetAllAttributes(MethodInfo method)
+ public static IEnumerable GetAllAttributes(MethodInfo method)
=> GetTypeAttributes(method.DeclaringType)
.Concat(
GetMethodAttributes(method)
@@ -145,7 +145,7 @@ public static void ApplyAllAttributes(TestResult testResult, MethodInfo method)
///
public static void ApplyAttributes(
TestResult testResult,
- IEnumerable attributes
+ IEnumerable attributes
)
{
foreach (var attribute in attributes)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index cd44b2c1..2abedecf 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -139,7 +139,7 @@ internal static void ApplyDefaultSuites(ITestMethod method)
}
static string? ResolveSubSuite(ITypeInfo xunitTestClass, Type? testClass, string? @namespace)
- => (testClass is null ? null : AllureMetadataAttribute
+ => (testClass is null ? null : AllureApiAttribute
.GetTypeAttributes(testClass)
.OfType()
.LastOrDefault()
@@ -265,8 +265,8 @@ static void ApplyAllureAttributes(TestResult testResult, ITestMethod xunitTestMe
var method = xunitTestMethod.Method.ToRuntimeMethod();
var testClass = xunitTestMethod.TestClass.Class.ToRuntimeType();
- AllureMetadataAttribute.ApplyTypeAttributes(testResult, testClass);
- AllureMetadataAttribute.ApplyMethodAttributes(testResult, method);
+ AllureApiAttribute.ApplyTypeAttributes(testResult, testClass);
+ AllureApiAttribute.ApplyMethodAttributes(testResult, method);
}
static void ApplyLegacyAllureAttributes(
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
index 6888639e..e3a30d1f 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
@@ -12,7 +12,7 @@ public void DirectMethodAttributesAreApplied()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
- AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(tr, method);
Assert.That(
tr.labels,
@@ -30,8 +30,8 @@ public void DirectMethodAttributesAreReturned()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
- var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -49,7 +49,7 @@ public void AbstractBaseAttributesAreApplies()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
- AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(tr, method);
Assert.That(
tr.labels,
@@ -67,8 +67,8 @@ public void AbstractBaseAttributesAreReturned()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
- var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -86,7 +86,7 @@ public void VirtualBaseAttributesAreApplies()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
- AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(tr, method);
Assert.That(
tr.labels,
@@ -104,8 +104,8 @@ public void VirtualBaseAttributesAreReturned()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
- var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -124,7 +124,7 @@ public void AppliesBaseBeforeOverride()
var method = typeof(AttributeApplicationOrderChild)
.GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
- AllureMetadataAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(tr, method);
Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
}
@@ -136,8 +136,8 @@ public void ReturnsBaseBeforeOverride()
var method = typeof(AttributeApplicationOrderChild)
.GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
- var attrs = AllureMetadataAttribute.GetMethodAttributes(method);
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetMethodAttributes(method);
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
}
@@ -147,7 +147,7 @@ public void DirectTypeAttributesAreApplied()
{
TestResult tr = new();
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(ClassWithAttrs));
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(ClassWithAttrs));
Assert.That(
tr.labels,
@@ -164,8 +164,8 @@ public void DirectTypeAttributesAreReturned()
{
TestResult tr = new();
- var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(ClassWithAttrs));
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(ClassWithAttrs));
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -182,7 +182,7 @@ public void AttributesFromBaseClassAreApplied()
{
TestResult tr = new();
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromClassAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromClassAttributes));
Assert.That(
tr.labels,
@@ -199,8 +199,8 @@ public void AttributesFromBaseClassAreReturned()
{
TestResult tr = new();
- var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(InheritedFromClassAttributes));
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromClassAttributes));
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -217,7 +217,7 @@ public void AttributesFromInterfaceAreApplied()
{
TestResult tr = new();
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromInterfaceAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromInterfaceAttributes));
Assert.That(
tr.labels,
@@ -234,8 +234,8 @@ public void AttributesFromInterfaceAreReturned()
{
TestResult tr = new();
- var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(InheritedFromInterfaceAttributes));
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromInterfaceAttributes));
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -252,7 +252,7 @@ public void AttributesFromDifferentSourcesAreCombined()
{
TestResult tr = new();
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(MultiSourceAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(MultiSourceAttributes));
Assert.That(
tr.labels,
@@ -275,8 +275,8 @@ public void AttributesFromDifferentSourcesAreCombinedWhenReturned()
{
TestResult tr = new();
- var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(MultiSourceAttributes));
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(MultiSourceAttributes));
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -299,7 +299,7 @@ public void CheckTypeAttributeApplicationOrder()
{
TestResult tr = new();
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(AttributeApplicationOrderChild));
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(AttributeApplicationOrderChild));
Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
}
@@ -309,8 +309,8 @@ public void CheckTypeAttributeReturnOrder()
{
TestResult tr = new();
- var attrs = AllureMetadataAttribute.GetTypeAttributes(typeof(AttributeApplicationOrderChild));
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetTypeAttributes(typeof(AttributeApplicationOrderChild));
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
}
@@ -322,7 +322,7 @@ public void AppliesAllAttributesToMethodAndItsTypeAtOnce()
var method = typeof(ApplyAllInherited)
.GetMethod(nameof(ApplyAllInherited.TargetMethod));
- AllureMetadataAttribute.ApplyAllAttributes(tr, method);
+ AllureApiAttribute.ApplyAllAttributes(tr, method);
Assert.That(
tr.labels,
@@ -353,8 +353,8 @@ public void ReturnsAllAttributesToMethodAndItsTypeAtOnce()
var method = typeof(ApplyAllInherited)
.GetMethod(nameof(ApplyAllInherited.TargetMethod));
- var attrs = AllureMetadataAttribute.GetAllAttributes(method);
- AllureMetadataAttribute.ApplyAttributes(tr, attrs);
+ var attrs = AllureApiAttribute.GetAllAttributes(method);
+ AllureApiAttribute.ApplyAttributes(tr, attrs);
Assert.That(
tr.labels,
@@ -385,8 +385,8 @@ public void AllureNameFromTypeNotApplied()
var type = typeof(WithAllureNameOnType);
var method = type.GetMethod(nameof(WithAllureNameOnType.TargetMethod));
- AllureMetadataAttribute.ApplyTypeAttributes(tr, typeof(WithAllureNameOnType));
- AllureMetadataAttribute.ApplyAllAttributes(tr, method);
+ AllureApiAttribute.ApplyTypeAttributes(tr, typeof(WithAllureNameOnType));
+ AllureApiAttribute.ApplyAllAttributes(tr, method);
Assert.That(tr.name, Is.Null);
}
From a14175be5aa6f01a3b2faa5865fb90a7a4ee95d2 Mon Sep 17 00:00:00 2001
From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com>
Date: Fri, 6 Feb 2026 17:07:59 +0700
Subject: [PATCH 80/80] feat(commons): fix param order in attr application fns
---
src/Allure.NUnit/Core/AllureNUnitHelper.cs | 4 +-
.../Sdk/AllureApiAttribute.cs | 14 +++---
src/Allure.Xunit/AllureXunitHelper.cs | 4 +-
.../AttributeApplicationTests.cs | 44 +++++++++----------
4 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/src/Allure.NUnit/Core/AllureNUnitHelper.cs b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
index 5bd0ae02..163a9081 100644
--- a/src/Allure.NUnit/Core/AllureNUnitHelper.cs
+++ b/src/Allure.NUnit/Core/AllureNUnitHelper.cs
@@ -277,8 +277,8 @@ static void ApplyAllureAttributes(ITest test, TestResult testResult)
{
var testFixtureClass = GetTestFixture(test).TypeInfo.Type;
- AllureApiAttribute.ApplyTypeAttributes(testResult, testFixtureClass);
- AllureApiAttribute.ApplyMethodAttributes(testResult, test.Method.MethodInfo);
+ AllureApiAttribute.ApplyTypeAttributes(testFixtureClass, testResult);
+ AllureApiAttribute.ApplyMethodAttributes(test.Method.MethodInfo, testResult);
}
static void ApplyLegacyAllureAttributes(ITest test, TestResult testResult)
diff --git a/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
index b441e11b..6c3a1b1b 100644
--- a/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
+++ b/src/Allure.Net.Commons/Sdk/AllureApiAttribute.cs
@@ -90,7 +90,7 @@ public static IEnumerable GetAllAttributes(MethodInfo method
/// Attributes of the base methods (virtual or abstract) are guaranteed to be applied before
/// attributes of the derived ones.
///
- public static void ApplyMethodAttributes(TestResult testResult, MethodInfo method)
+ public static void ApplyMethodAttributes(MethodInfo method, TestResult testResult)
{
foreach (var attr in GetMethodAttributes(method))
{
@@ -109,7 +109,7 @@ public static void ApplyMethodAttributes(TestResult testResult, MethodInfo metho
/// - Base classes are handled before derived classes.
///
///
- public static void ApplyTypeAttributes(TestResult testResult, Type type)
+ public static void ApplyTypeAttributes(Type type, TestResult testResult)
{
var typeAttributesToApply
= GetTypeAttributes(type)
@@ -134,18 +134,18 @@ var typeAttributesToApply
/// - Base methods are handled before methods overrides.
///
///
- public static void ApplyAllAttributes(TestResult testResult, MethodInfo method)
+ public static void ApplyAllAttributes(MethodInfo method, TestResult testResult)
{
- ApplyTypeAttributes(testResult, method.DeclaringType);
- ApplyMethodAttributes(testResult, method);
+ ApplyTypeAttributes(method.DeclaringType, testResult);
+ ApplyMethodAttributes(method, testResult);
}
///
/// Applies to .
///
public static void ApplyAttributes(
- TestResult testResult,
- IEnumerable attributes
+ IEnumerable attributes,
+ TestResult testResult
)
{
foreach (var attribute in attributes)
diff --git a/src/Allure.Xunit/AllureXunitHelper.cs b/src/Allure.Xunit/AllureXunitHelper.cs
index 2abedecf..fe688ef2 100644
--- a/src/Allure.Xunit/AllureXunitHelper.cs
+++ b/src/Allure.Xunit/AllureXunitHelper.cs
@@ -265,8 +265,8 @@ static void ApplyAllureAttributes(TestResult testResult, ITestMethod xunitTestMe
var method = xunitTestMethod.Method.ToRuntimeMethod();
var testClass = xunitTestMethod.TestClass.Class.ToRuntimeType();
- AllureApiAttribute.ApplyTypeAttributes(testResult, testClass);
- AllureApiAttribute.ApplyMethodAttributes(testResult, method);
+ AllureApiAttribute.ApplyTypeAttributes(testClass, testResult);
+ AllureApiAttribute.ApplyMethodAttributes(method, testResult);
}
static void ApplyLegacyAllureAttributes(
diff --git a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
index e3a30d1f..f7187f08 100644
--- a/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
+++ b/tests/Allure.Net.Commons.Tests/UserAPITests/AttributeTests/AttributeApplicationTests.cs
@@ -12,7 +12,7 @@ public void DirectMethodAttributesAreApplied()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
- AllureApiAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
Assert.That(
tr.labels,
@@ -31,7 +31,7 @@ public void DirectMethodAttributesAreReturned()
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Foo));
var attrs = AllureApiAttribute.GetMethodAttributes(method);
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -49,7 +49,7 @@ public void AbstractBaseAttributesAreApplies()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
- AllureApiAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
Assert.That(
tr.labels,
@@ -68,7 +68,7 @@ public void AbstractBaseAttributesAreReturned()
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Bar));
var attrs = AllureApiAttribute.GetMethodAttributes(method);
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -86,7 +86,7 @@ public void VirtualBaseAttributesAreApplies()
TestResult tr = new();
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
- AllureApiAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
Assert.That(
tr.labels,
@@ -105,7 +105,7 @@ public void VirtualBaseAttributesAreReturned()
var method = typeof(MethodsWithAttrs).GetMethod(nameof(MethodsWithAttrs.Baz));
var attrs = AllureApiAttribute.GetMethodAttributes(method);
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -124,7 +124,7 @@ public void AppliesBaseBeforeOverride()
var method = typeof(AttributeApplicationOrderChild)
.GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
- AllureApiAttribute.ApplyMethodAttributes(tr, method);
+ AllureApiAttribute.ApplyMethodAttributes(method, tr);
Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
}
@@ -137,7 +137,7 @@ public void ReturnsBaseBeforeOverride()
.GetMethod(nameof(AttributeApplicationOrderChild.TargetMethod));
var attrs = AllureApiAttribute.GetMethodAttributes(method);
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(tr.description, Is.EqualTo("baz\n\nqut"));
}
@@ -147,7 +147,7 @@ public void DirectTypeAttributesAreApplied()
{
TestResult tr = new();
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(ClassWithAttrs));
+ AllureApiAttribute.ApplyTypeAttributes(typeof(ClassWithAttrs), tr);
Assert.That(
tr.labels,
@@ -165,7 +165,7 @@ public void DirectTypeAttributesAreReturned()
TestResult tr = new();
var attrs = AllureApiAttribute.GetTypeAttributes(typeof(ClassWithAttrs));
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -182,7 +182,7 @@ public void AttributesFromBaseClassAreApplied()
{
TestResult tr = new();
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromClassAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(typeof(InheritedFromClassAttributes), tr);
Assert.That(
tr.labels,
@@ -200,7 +200,7 @@ public void AttributesFromBaseClassAreReturned()
TestResult tr = new();
var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromClassAttributes));
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -217,7 +217,7 @@ public void AttributesFromInterfaceAreApplied()
{
TestResult tr = new();
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(InheritedFromInterfaceAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(typeof(InheritedFromInterfaceAttributes), tr);
Assert.That(
tr.labels,
@@ -235,7 +235,7 @@ public void AttributesFromInterfaceAreReturned()
TestResult tr = new();
var attrs = AllureApiAttribute.GetTypeAttributes(typeof(InheritedFromInterfaceAttributes));
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -252,7 +252,7 @@ public void AttributesFromDifferentSourcesAreCombined()
{
TestResult tr = new();
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(MultiSourceAttributes));
+ AllureApiAttribute.ApplyTypeAttributes(typeof(MultiSourceAttributes), tr);
Assert.That(
tr.labels,
@@ -276,7 +276,7 @@ public void AttributesFromDifferentSourcesAreCombinedWhenReturned()
TestResult tr = new();
var attrs = AllureApiAttribute.GetTypeAttributes(typeof(MultiSourceAttributes));
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -299,7 +299,7 @@ public void CheckTypeAttributeApplicationOrder()
{
TestResult tr = new();
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(AttributeApplicationOrderChild));
+ AllureApiAttribute.ApplyTypeAttributes(typeof(AttributeApplicationOrderChild), tr);
Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
}
@@ -310,7 +310,7 @@ public void CheckTypeAttributeReturnOrder()
TestResult tr = new();
var attrs = AllureApiAttribute.GetTypeAttributes(typeof(AttributeApplicationOrderChild));
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(tr.description, Is.EqualTo("foo\n\nbar\n\nqux"));
}
@@ -322,7 +322,7 @@ public void AppliesAllAttributesToMethodAndItsTypeAtOnce()
var method = typeof(ApplyAllInherited)
.GetMethod(nameof(ApplyAllInherited.TargetMethod));
- AllureApiAttribute.ApplyAllAttributes(tr, method);
+ AllureApiAttribute.ApplyAllAttributes(method, tr);
Assert.That(
tr.labels,
@@ -354,7 +354,7 @@ public void ReturnsAllAttributesToMethodAndItsTypeAtOnce()
.GetMethod(nameof(ApplyAllInherited.TargetMethod));
var attrs = AllureApiAttribute.GetAllAttributes(method);
- AllureApiAttribute.ApplyAttributes(tr, attrs);
+ AllureApiAttribute.ApplyAttributes(attrs, tr);
Assert.That(
tr.labels,
@@ -385,8 +385,8 @@ public void AllureNameFromTypeNotApplied()
var type = typeof(WithAllureNameOnType);
var method = type.GetMethod(nameof(WithAllureNameOnType.TargetMethod));
- AllureApiAttribute.ApplyTypeAttributes(tr, typeof(WithAllureNameOnType));
- AllureApiAttribute.ApplyAllAttributes(tr, method);
+ AllureApiAttribute.ApplyTypeAttributes(typeof(WithAllureNameOnType), tr);
+ AllureApiAttribute.ApplyAllAttributes(method, tr);
Assert.That(tr.name, Is.Null);
}