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 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; + } + + 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 + }; + + if (mode is not null and not ParameterMode.Default) + { + allureParameter.mode = attr?.Mode; + } + + yield return allureParameter; + } + } + static bool ShouldAddEnvVarAsLabel( [NotNullWhen(true)] string? name, [NotNullWhen(true)] string? value diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs new file mode 100644 index 00000000..a57b7828 --- /dev/null +++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs @@ -0,0 +1,184 @@ +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; + +class ParameterTests +{ + static ParameterTests() + { + var parameters = typeof(ParameterTests).GetMethod(nameof(Target)).GetParameters(); + + NoAttribute = parameters[0]; + NoEffect = parameters[1]; + Ignored = parameters[2]; + Renamed = parameters[3]; + Masked = parameters[4]; + Hidden = parameters[5]; + Excluded = parameters[6]; + } + + public static void Target( + int noAttribute, + [AllureParameter] int noEffect, + [AllureParameter(Ignore = true)] int ignored, + [AllureParameter(Name = "New name")] int renamed, + [AllureParameter(Mode = ParameterMode.Masked)] int masked, + [AllureParameter(Mode = ParameterMode.Hidden)] int hidden, + [AllureParameter(Excluded = true)] int excluded + ) { } + + static ParameterInfo NoAttribute; + static ParameterInfo NoEffect; + static ParameterInfo Ignored; + static ParameterInfo Renamed; + static ParameterInfo Masked; + static ParameterInfo Hidden; + static ParameterInfo Excluded; + static readonly Dictionary emptyFormatters = []; + + [Test] + public void EmptyParameterInfoSeqGivesEmptySeq() + { + var parameters = ModelFunctions.CreateParameters([], ["foo"], emptyFormatters); + + Assert.That(parameters, Is.Empty); + } + + [Test] + public void EmptyValueSeqGivesEmptySeq() + { + var parameters = ModelFunctions.CreateParameters([], ["foo"], emptyFormatters); + + Assert.That(parameters, Is.Empty); + } + + [Test] + public void PlainParameter() + { + var parameters = ModelFunctions.CreateParameters([NoAttribute], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([new Parameter { name = "noAttribute", value = "\"foo\"" }]) + .UsingPropertiesComparer() + ); + } + + [Test] + public void ParameterWithEmptyAttribute() + { + var parameters = ModelFunctions.CreateParameters([NoEffect], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([new Parameter { name = "noEffect", value = "\"foo\"" }]) + .UsingPropertiesComparer() + ); + } + + [Test] + public void IgnoredParameter() + { + var parameters = ModelFunctions.CreateParameters([Ignored], ["foo"], emptyFormatters); + + Assert.That(parameters, Is.Empty); + } + + [Test] + public void RenamedParameter() + { + var parameters = ModelFunctions.CreateParameters([Renamed], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([new Parameter { name = "New name", value = "\"foo\"" }]) + .UsingPropertiesComparer() + ); + } + + [Test] + public void MaskedParameter() + { + var parameters = ModelFunctions.CreateParameters([Masked], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([ + new Parameter + { + name = "masked", + value = "\"foo\"", + mode = ParameterMode.Masked + } + ]).UsingPropertiesComparer() + ); + } + + [Test] + public void HiddenParameter() + { + var parameters = ModelFunctions.CreateParameters([Hidden], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([ + new Parameter + { + name = "hidden", + value = "\"foo\"", + mode = ParameterMode.Hidden + } + ]).UsingPropertiesComparer() + ); + } + + [Test] + public void ExcludedParameter() + { + var parameters = ModelFunctions.CreateParameters([Excluded], ["foo"], emptyFormatters); + + Assert.That( + parameters, + Is.EqualTo([ + new Parameter + { + name = "excluded", + value = "\"foo\"", + excluded = true + } + ]).UsingPropertiesComparer() + ); + } + + class StringFormatterDummy : TypeFormatter + { + public override string Format(string value) => "bar"; + } + + [Test] + public void FormatterUsedIfMatched() + { + var formatters = new Dictionary + { + { typeof(string), new StringFormatterDummy() }, + }; + + var parameters = ModelFunctions.CreateParameters([NoAttribute], ["foo"], formatters); + + Assert.That( + parameters, + Is.EqualTo([ + new Parameter + { + name = "noAttribute", + value = "bar", + } + ]).UsingPropertiesComparer() + ); + } +} From e7f3731410a908b5d75d1bbac1b8486810614e8d Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:28:17 +0700 Subject: [PATCH 25/80] test(commons): fix flaky concurrency tests --- .../ConcurrencyTests.cs | 46 +++++++++------- .../ModelFunctionTests/ParameterTests.cs | 55 ++++++++++++++++++- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs b/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs index bf3ec54f..4fa7ddfe 100644 --- a/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs +++ b/tests/Allure.Net.Commons.Tests/ConcurrencyTests.cs @@ -29,8 +29,8 @@ public void ParallelTestsAreIsolated() () => this.AddTestWithSteps("test-2", "step-2-1", "step-2-2") ); - this.AssertTestWithSteps("test-1", "step-1-1", "step-1-2"); - this.AssertTestWithSteps("test-2", "step-2-1", "step-2-2"); + this.AssertTestWithSteps("test-1", false, "step-1-1", "step-1-2"); + this.AssertTestWithSteps("test-2", false, "step-2-1", "step-2-2"); } [Test] @@ -42,9 +42,9 @@ await Task.WhenAll( this.AddTestWithStepsAsync("test-3", "step-3-1", "step-3-2") ); - this.AssertTestWithSteps("test-1", "step-1-1", "step-1-2"); - this.AssertTestWithSteps("test-2", "step-2-1", "step-2-2"); - this.AssertTestWithSteps("test-3", "step-3-1", "step-3-2"); + this.AssertTestWithSteps("test-1", false, "step-1-1", "step-1-2"); + this.AssertTestWithSteps("test-2", false, "step-2-1", "step-2-2"); + this.AssertTestWithSteps("test-3", false, "step-3-1", "step-3-2"); } [Test] @@ -55,7 +55,7 @@ public void ParallelStepsOfTestAreIsolated() () => this.AddStep("step-2") )); - this.AssertTestWithSteps("test-1", "step-1", "step-2"); + this.AssertTestWithSteps("test-1", true, "step-1", "step-2"); } [Test] @@ -67,7 +67,7 @@ await this.WrapInTestAsync("test-1", async () => await Task.WhenAll( this.AddStepsAsync("step-3") )); - this.AssertTestWithSteps("test-1", "step-1", "step-2", "step-3"); + this.AssertTestWithSteps("test-1", true, "step-1", "step-2", "step-3"); } [Test] @@ -104,10 +104,11 @@ public void ContextCapturedBySubThreads() this.AssertTestWithSteps( "test", - ("outer", new object[] + false, + ("outer", true, new object[] { - ("inner-1", new object[] { "inner-1-1", "inner-1-2" }), - ("inner-2", new object[] { "inner-2-1", "inner-2-2" }) + ("inner-1", false, new object[] { "inner-1-1", "inner-1-2" }), + ("inner-2", false, new object[] { "inner-2-1", "inner-2-2" }) }) ); } @@ -142,10 +143,11 @@ await this.WrapInTestAsync( this.AssertTestWithSteps( "test", - ("outer", new object[] + false, + ("outer", true, new object[] { - ("inner-1", new object[] { "inner-1-1", "inner-1-2" }), - ("inner-2", new object[] { "inner-2-1", "inner-2-2" }) + ("inner-1", false, new object[] { "inner-1-1", "inner-1-2" }), + ("inner-2", false, new object[] { "inner-2-1", "inner-2-2" }) }) ); } @@ -294,31 +296,37 @@ async Task AddStepWithSubstepsAsync(string name, params object[] substeps) this.lifecycle.StopStep(); } - void AssertTestWithSteps(string testName, params object[] steps) + void AssertTestWithSteps(string testName, bool anyOrder, params object[] steps) { Assert.That( this.writer.testResults.Select(tr => tr.name), Contains.Item(testName) ); var test = this.writer.testResults.Single(tr => tr.name == testName); - this.AssertSteps(test.steps, steps); + this.AssertSteps(test.steps, anyOrder, steps); } - void AssertSteps(List actualSteps, params object[] steps) + void AssertSteps(List actualSteps, bool anyOrder, params object[] steps) { + if (anyOrder) + { + actualSteps = actualSteps.OrderBy(static (sr) => sr.name).ToList(); + } + var expectedCount = steps.Length; Assert.That(actualSteps.Count, Is.EqualTo(expectedCount)); for (var i = 0; i < expectedCount; i++) { var actualStep = actualSteps[i]; var step = steps.ElementAt(i); - if (!(step is (string expectedStepName, object[] substeps))) + if (!(step is (string expectedStepName, bool subStepsInAnyOrder, object[] substeps))) { expectedStepName = (string)step; - substeps = Array.Empty(); + substeps = []; + subStepsInAnyOrder = false; } Assert.That(actualStep.name, Is.EqualTo(expectedStepName)); - this.AssertSteps(actualStep.steps, substeps); + this.AssertSteps(actualStep.steps, subStepsInAnyOrder, substeps); } } diff --git a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs index a57b7828..98f8339f 100644 --- a/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs +++ b/tests/Allure.Net.Commons.Tests/FunctionTests/ModelFunctionTests/ParameterTests.cs @@ -155,7 +155,7 @@ public void ExcludedParameter() ); } - class StringFormatterDummy : TypeFormatter + class StringFormatterStub : TypeFormatter { public override string Format(string value) => "bar"; } @@ -165,7 +165,7 @@ public void FormatterUsedIfMatched() { var formatters = new Dictionary { - { typeof(string), new StringFormatterDummy() }, + { typeof(string), new StringFormatterStub() }, }; var parameters = ModelFunctions.CreateParameters([NoAttribute], ["foo"], formatters); @@ -181,4 +181,55 @@ public void FormatterUsedIfMatched() ]).UsingPropertiesComparer() ); } + + class StringFormatterDummy : TypeFormatter + { + public override string Format(string value) => throw new NotImplementedException(); + } + + [Test] + public void FormattingSkippedForIgnoredParameter() + { + var formatters = new Dictionary + { + { typeof(string), new StringFormatterDummy() }, + }; + + var parameters = ModelFunctions.CreateParameters([Ignored], ["foo"], formatters); + + Assert.That(parameters, Is.Empty); + } + + [Test] + public void MultipleParameters() + { + var parameters = ModelFunctions.CreateParameters( + [NoAttribute, Ignored, Masked, Excluded], + ["foo", "bar", "baz", "qux"], + emptyFormatters + ); + + Assert.That( + parameters, + Is.EqualTo([ + new Parameter + { + name = "noAttribute", + value = "\"foo\"", + }, + new Parameter + { + name = "masked", + value = "\"baz\"", + mode = ParameterMode.Masked, + }, + new Parameter + { + name = "excluded", + value = "\"qux\"", + excluded = true, + } + ]).UsingPropertiesComparer() + ); + } } From 1b34baf1834ec0be0ee08b529283265b4c80241a Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:20:48 +0700 Subject: [PATCH 26/80] test(nunit): rewrite parameter tests --- tests/Allure.NUnit.Tests/ParameterTests.cs | 87 +++++++------------ .../Samples/AddExcludedParameter.cs | 17 ---- .../Samples/AddHiddenParameter.cs | 15 ---- .../Samples/AddMaskedParameter.cs | 15 ---- .../Samples/AddParameterFromSetUp.cs | 18 ---- .../Samples/AddParameterFromTearDown.cs | 18 ---- .../Samples/AddParameterFromTest.cs | 15 ---- .../Samples/AddTestParameter.cs | 31 +++++++ .../OneNUnitTestCaseWithOneParameter.cs | 12 --- ...ParameterAttributesOnTestCaseParameters.cs | 20 +++++ 10 files changed, 84 insertions(+), 164 deletions(-) delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs delete mode 100644 tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs diff --git a/tests/Allure.NUnit.Tests/ParameterTests.cs b/tests/Allure.NUnit.Tests/ParameterTests.cs index 42c6f25b..ca07a3b1 100644 --- a/tests/Allure.NUnit.Tests/ParameterTests.cs +++ b/tests/Allure.NUnit.Tests/ParameterTests.cs @@ -5,13 +5,11 @@ namespace Allure.NUnit.Tests; class ParameterTests { - public static IEnumerable> GetSingleParameterSamples() + public static IEnumerable> GetParameterSamples() { IEnumerable samples = [ - AllureSampleRegistry.AddParameterFromSetUp, - AllureSampleRegistry.AddParameterFromTest, - AllureSampleRegistry.AddParameterFromTearDown, - AllureSampleRegistry.OneNUnitTestCaseWithOneParameter, + AllureSampleRegistry.AddTestParameter, + AllureSampleRegistry.ParameterAttributesOnTestCaseParameters, ]; return samples.Select(static (sample) => @@ -19,64 +17,45 @@ public static IEnumerable> GetSingleParam } [Test] - [MethodDataSource(nameof(GetSingleParameterSamples))] - public async Task CheckParameterIsAdded(AllureSampleRegistryEntry sample) + [MethodDataSource(nameof(GetParameterSamples))] + public async Task AddTestParameterApiWorks(AllureSampleRegistryEntry sample) { var results = await AllureSampleRunner.RunAsync(sample); await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); - var nodes = results.TestResults[0]["parameters"].AsArray().Cast(); - await Assert.That(nodes).ContainsOnly( - p => (string)p["name"] == "foo" && (string)p["value"] == "\"bar\"" - ); - } - - [Test] - public async Task CheckMaskedParameter() - { - var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddMaskedParameter); - await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var parameters = results.TestResults[0]["parameters"].AsArray().Cast().ToList(); - var parameters = results.TestResults[0]["parameters"].AsArray().Cast(); - await Assert.That(parameters).HasSingleItem().And.All( - static (p) => (string)p["mode"] == "masked" + await Assert.That(parameters.Count).IsEqualTo(5); + await Assert.That(parameters[0]).Satisfies( + static (p) => (string)p["name"] == "name1" + && (string)p["value"] == "\"value-1\"" + && p["mode"] is null + && (bool)p["excluded"] is false ); - } - - [Test] - public async Task CheckHiddenParameter() - { - var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddHiddenParameter); - - await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); - - var parameters = results.TestResults[0]["parameters"].AsArray().Cast(); - await Assert.That(parameters).HasSingleItem().And.All( - static (p) => (string)p["mode"] == "hidden" + await Assert.That(parameters[1]).Satisfies( + static (p) => (string)p["name"] == "name2" + && (string)p["value"] == "\"value-2\"" + && (string)p["mode"] == "masked" + && (bool)p["excluded"] is false ); - } - - [Test] - public async Task CheckExcludedParameter() - { - var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddExcludedParameter); - - await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(2); - - var testResult1 = results.TestResults[0]; - var testResult2 = results.TestResults[1]; - - var testResult1Parameters = testResult1["parameters"].AsArray().Cast(); - var testResult2Parameters = testResult2["parameters"].AsArray().Cast(); - await Assert.That(testResult1Parameters).Any( - static (p) => (string)p["name"] == "timestamp" && (bool)p["excluded"] == true + await Assert.That(parameters[2]).Satisfies( + static (p) => (string)p["name"] == "name3" + && (string)p["value"] == "\"value-3\"" + && (string)p["mode"] == "hidden" + && (bool)p["excluded"] is false ); - await Assert.That(testResult2Parameters).Any( - static (p) => (string)p["name"] == "timestamp" && (bool)p["excluded"] == true + await Assert.That(parameters[3]).Satisfies( + static (p) => (string)p["name"] == "name4" + && (string)p["value"] == "\"value-4\"" + && p["mode"] is null + && (bool)p["excluded"] is true + ); + await Assert.That(parameters[4]).Satisfies( + static (p) => (string)p["name"] == "name5" + && (string)p["value"] == "\"value-5\"" + && (string)p["mode"] == "masked" + && (bool)p["excluded"] is true ); - - // It must not affect historyId - await Assert.That((string)testResult1["historyId"]).IsEqualTo((string)testResult2["historyId"]); } } \ No newline at end of file diff --git a/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs deleted file mode 100644 index b2de9c9e..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddExcludedParameter.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddExcludedParameter -{ - [AllureNUnit] - public class TestsClass - { - [TestCase(0)] - [TestCase(0)] - public void TestMethod(int _) - { - AllureApi.AddTestParameter("timestamp", DateTime.Now, true); - } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs deleted file mode 100644 index 88cc4467..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddHiddenParameter.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddHiddenParameter -{ - [AllureNUnit] - public class TestsClass - { - [Test] - public void TestMethod() - { - AllureApi.AddTestParameter("foo", "bar", ParameterMode.Hidden); - } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs deleted file mode 100644 index 02efc9ad..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddMaskedParameter.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddMaskedParameter -{ - [AllureNUnit] - public class TestsClass - { - [Test] - public void TestMethod() - { - AllureApi.AddTestParameter("foo", "bar", ParameterMode.Masked); - } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs deleted file mode 100644 index 9281692a..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromSetUp.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddParameterFromSetUp -{ - [AllureNUnit] - public class TestsClass - { - [SetUp] - public void SetUp() - { - AllureApi.AddTestParameter("foo", "bar"); - } - - [Test] - public void TestMethod() { } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs deleted file mode 100644 index 3fbdfced..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTearDown.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddParameterFromTearDown -{ - [AllureNUnit] - public class TestsClass - { - [TearDown] - public void TearDown() - { - AllureApi.AddTestParameter("foo", "bar"); - } - - [Test] - public void TestMethod() { } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs b/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs deleted file mode 100644 index 5cdc5480..00000000 --- a/tests/Allure.NUnit.Tests/Samples/AddParameterFromTest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.AddParameterFromTest -{ - [AllureNUnit] - public class TestsClass - { - [Test] - public void TestMethod() - { - AllureApi.AddTestParameter("foo", "bar"); - } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs b/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs new file mode 100644 index 00000000..3f1c58f8 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/AddTestParameter.cs @@ -0,0 +1,31 @@ +using Allure.Net.Commons; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.AddTestParameters +{ + [AllureNUnit] + public class TestsClass + { + [SetUp] + public void SetUp() + { + AllureApi.AddTestParameter("name1", "value-1"); + } + + [TestCase] + public void TestMethod( + + ) + { + AllureApi.AddTestParameter("name2", "value-2", ParameterMode.Masked); + AllureApi.AddTestParameter("name3", "value-3", ParameterMode.Hidden); + AllureApi.AddTestParameter("name4", "value-4", excluded: true); + } + + [TearDown] + public void TearDown() + { + AllureApi.AddTestParameter("name5", "value-5", ParameterMode.Masked, true); + } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs b/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs deleted file mode 100644 index 81e7d0bd..00000000 --- a/tests/Allure.NUnit.Tests/Samples/OneNUnitTestCaseWithOneParameter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Allure.Net.Commons; -using NUnit.Framework; - -namespace Allure.NUnit.Tests.Samples.OneNUnitTestCaseWithOneParameter -{ - [AllureNUnit] - public class TestsClass - { - [TestCase("bar")] - public void TestMethod(string foo) { } - } -} diff --git a/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs b/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs new file mode 100644 index 00000000..fb90cd56 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/ParameterAttributesOnTestCaseParameters.cs @@ -0,0 +1,20 @@ +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.ParameterAttributesOnTestCase +{ + [AllureNUnit] + public class TestsClass + { + [TestCase("value-1", "ignored", "value-2", "value-3", "value-4", "value-5")] + public void TestMethod( + string name1, + [AllureParameter(Ignore = true)] string ignored, + [AllureParameter(Name = "name2", Mode = ParameterMode.Masked)] string renamed1, + [AllureParameter(Mode = ParameterMode.Hidden)] string name3, + [AllureParameter(Excluded = true)] string name4, + [AllureParameter(Name = "name5", Mode = ParameterMode.Masked, Excluded = true)] string renamed2 + ) { } + } +} From 80ae2a6a24f53d6b7ef774f07ce844567218884f Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:40:26 +0700 Subject: [PATCH 27/80] docs(commons): add details to AllureParameterAttribute.Excluded --- .../Attributes/AllureParameterAttribute.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs index e687dee4..987a351b 100644 --- a/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs +++ b/src/Allure.Net.Commons/Attributes/AllureParameterAttribute.cs @@ -30,10 +30,14 @@ public class AllureParameterAttribute : Attribute public ParameterMode Mode { get; init; } = ParameterMode.Default; /// - /// If set to true, the parameter doesn't affect the test's historyId. + /// 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. /// /// - /// Use for timestamps, random values, and other values that may change across runs by design. + /// Setting this property doesn't remove the parameter from the report. To remove the parameter + /// entirely, use . + ///

+ /// Has no effect when applied to a step's parameter. ///
public bool Excluded { get; init; } = false; } \ No newline at end of file From 7337f520ea290a2c024a17b0e8d5357a161db2de Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:31:52 +0700 Subject: [PATCH 28/80] test(nunit): fix step attribute tests --- tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj index e58dd346..4b91a6ea 100644 --- a/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj +++ b/tests/Allure.NUnit.Tests/Allure.NUnit.Tests.csproj @@ -7,7 +7,7 @@ - + From 1a21dc581c8ac342feb422b8b6de79cf2ac93ebe Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:32:12 +0700 Subject: [PATCH 29/80] test(nunit): add new step attribute tests --- .../Samples/StepAttributes.cs | 19 ++++---- tests/Allure.NUnit.Tests/StepTests.cs | 44 ++++++++++++++----- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs index 95ba38b4..d333a53a 100644 --- a/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs +++ b/tests/Allure.NUnit.Tests/Samples/StepAttributes.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Allure.Net.Commons; using Allure.Net.Commons.Attributes; using NUnit.Framework; @@ -15,9 +16,7 @@ public async Task TestMethod() await this.Async(); await this.AsyncReturn(); this.Named(); - this.Parameters(1, "baz"); - this.SkippedParameter(2); - this.RenamedParameter(3); + this.Parameters(1, 2, 3, 4, 5); } [AllureStep] @@ -43,12 +42,12 @@ async Task AsyncReturn() 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) { } + void Parameters( + int plain, + [AllureParameter(Ignore = true)] int ignored, + [AllureParameter(Name = "Bar")] int renamed, + [AllureParameter(Mode = ParameterMode.Masked)] int masked, + [AllureParameter(Mode = ParameterMode.Hidden)] int hidden + ) { } } } diff --git a/tests/Allure.NUnit.Tests/StepTests.cs b/tests/Allure.NUnit.Tests/StepTests.cs index b365fe2f..0cc531af 100644 --- a/tests/Allure.NUnit.Tests/StepTests.cs +++ b/tests/Allure.NUnit.Tests/StepTests.cs @@ -5,11 +5,12 @@ namespace Allure.NUnit.Tests; class StepTests { - record class ParameterExpectations(string Name, string Value) + record class ParameterExpectations(string Name, string Value, string Mode = null) { public bool Check(JsonObject parameter) => (string)parameter["name"] == this.Name - && (string)parameter["value"] == this.Value; + && (string)parameter["value"] == this.Value + && (this.Mode is null || (string)parameter["mode"] == this.Mode); public static bool CheckAll( List expectations, JsonArray parameters @@ -48,20 +49,41 @@ JsonArray steps .All(static (p) => p.Second.Check(p.First.AsObject())); } - public static IEnumerable> GetStepSamples() + [Test] + public async Task StepAttributeWorks() { - IEnumerable samples = [ - AllureSampleRegistry.StepAttributes, - AllureSampleRegistry.LegacyStepAttributes, - ]; + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.StepAttributes); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var steps = results.TestResults[0]["steps"].AsArray().Cast().ToArray(); + await Assert.That(steps).Count().IsEqualTo(6); + + 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)); - return samples.Select(static (sample) => - new TestDataRow(sample, DisplayName: sample.Id)); + await Assert.That(steps[2]).Satisfies(static (step) => + new StepExpectations("Async", "passed", [], []).Check(step)); + + await Assert.That(steps[3]).Satisfies(static (step) => + new StepExpectations("AsyncReturn", "passed", [], []).Check(step)); + + await Assert.That(steps[4]).Satisfies(static (step) => + new StepExpectations("Renamed", "passed", [], []).Check(step)); + + await Assert.That(steps[5]).Satisfies(static (step) => + new StepExpectations("Parameters", "passed", [ + new("plain", "1"), + new("Bar", "3"), + new("masked", "4", "masked"), + new("hidden", "5", "hidden"), + ], []).Check(step)); } [Test] - [MethodDataSource(nameof(GetStepSamples))] - public async Task CheckStepsFromAnnotatedMethodCalls(AllureSampleRegistryEntry sample) + public async Task LegacyStepAttributeWorks() { var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyStepAttributes); From 1cf7009beaeb2f5a09e636f5623e841462d11280 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:57:29 +0700 Subject: [PATCH 30/80] test(nunit): fix suite and bdd label class test name --- tests/Allure.NUnit.Tests/BddLabelTests.cs | 2 +- tests/Allure.NUnit.Tests/SuiteLabelTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Allure.NUnit.Tests/BddLabelTests.cs b/tests/Allure.NUnit.Tests/BddLabelTests.cs index 69ffb6d7..53476d26 100644 --- a/tests/Allure.NUnit.Tests/BddLabelTests.cs +++ b/tests/Allure.NUnit.Tests/BddLabelTests.cs @@ -3,7 +3,7 @@ namespace Allure.NUnit.Tests; -class BddHierarchyTests +class BddLabelTests { public static IEnumerable> GetBddHierarchySamples() { diff --git a/tests/Allure.NUnit.Tests/SuiteLabelTests.cs b/tests/Allure.NUnit.Tests/SuiteLabelTests.cs index 54e3cb11..1a381bdc 100644 --- a/tests/Allure.NUnit.Tests/SuiteLabelTests.cs +++ b/tests/Allure.NUnit.Tests/SuiteLabelTests.cs @@ -3,7 +3,7 @@ namespace Allure.NUnit.Tests; -class SuiteHierarchyTests +class SuiteLabelTests { public static IEnumerable> GetSuiteHierarchySamples() { From fe640fe5f5dde6896bda0f474f3ad0b1d91be08f Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:57:44 +0700 Subject: [PATCH 31/80] test(nunit): add severity tests --- .../LegacySeverityAttributeOnBaseClass.cs | 16 +++++++ .../Samples/LegacySeverityAttributeOnClass.cs | 14 +++++++ .../LegacySeverityAttributeOnMethod.cs | 14 +++++++ .../Samples/SetSeverityFromSetUp.cs | 18 ++++++++ .../Samples/SetSeverityFromTearDown.cs | 18 ++++++++ .../Samples/SetSeverityFromTest.cs | 15 +++++++ .../Samples/SeverityAttributeOnBaseClass.cs | 16 +++++++ .../Samples/SeverityAttributeOnClass.cs | 14 +++++++ .../Samples/SeverityAttributeOnInterface.cs | 16 +++++++ .../Samples/SeverityAttributeOnMethod.cs | 14 +++++++ tests/Allure.NUnit.Tests/SeverityTests.cs | 42 +++++++++++++++++++ 11 files changed, 197 insertions(+) create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs create mode 100644 tests/Allure.NUnit.Tests/SeverityTests.cs diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs new file mode 100644 index 00000000..f7a49c8b --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnBaseClass.cs @@ -0,0 +1,16 @@ +using Allure.Net.Commons; +using Allure.NUnit.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnBaseClass +{ + [AllureSeverity(SeverityLevel.critical)] + public class BaseClass {} + + [AllureNUnit] + public class TestsClass : BaseClass + { + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs new file mode 100644 index 00000000..54539a31 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnClass.cs @@ -0,0 +1,14 @@ +using Allure.Net.Commons; +using Allure.NUnit.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnClass +{ + [AllureNUnit] + [AllureSeverity(SeverityLevel.critical)] + public class TestsClass + { + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs new file mode 100644 index 00000000..2bd4d740 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/LegacySeverityAttributeOnMethod.cs @@ -0,0 +1,14 @@ +using Allure.Net.Commons; +using Allure.NUnit.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.LegacySeverityAttributeOnMethod +{ + [AllureNUnit] + public class TestsClass + { + [Test] + [AllureSeverity(SeverityLevel.critical)] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs new file mode 100644 index 00000000..46583b4c --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromSetUp.cs @@ -0,0 +1,18 @@ +using Allure.Net.Commons; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SetSeverityFromSetUp +{ + [AllureNUnit] + public class TestsClass + { + [SetUp] + public void SetUp() + { + AllureApi.SetSeverity(SeverityLevel.critical); + } + + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs new file mode 100644 index 00000000..267248b6 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTearDown.cs @@ -0,0 +1,18 @@ +using Allure.Net.Commons; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SetSeverityFromTearDown +{ + [AllureNUnit] + public class TestsClass + { + [TearDown] + public void TearDown() + { + AllureApi.SetSeverity(SeverityLevel.critical); + } + + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs new file mode 100644 index 00000000..a3d52293 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SetSeverityFromTest.cs @@ -0,0 +1,15 @@ +using Allure.Net.Commons; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SetSeverityFromTearDown +{ + [AllureNUnit] + public class TestsClass + { + [Test] + public void TestMethod() + { + AllureApi.SetSeverity(SeverityLevel.critical); + } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs new file mode 100644 index 00000000..aed6b53b --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnBaseClass.cs @@ -0,0 +1,16 @@ +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnBaseClass +{ + [AllureSeverity(SeverityLevel.critical)] + public class BaseClass {} + + [AllureNUnit] + public class TestsClass : BaseClass + { + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs new file mode 100644 index 00000000..3115211e --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnClass.cs @@ -0,0 +1,14 @@ +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnClass +{ + [AllureNUnit] + [AllureSeverity(SeverityLevel.critical)] + public class TestsClass + { + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs new file mode 100644 index 00000000..4907d5e6 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnInterface.cs @@ -0,0 +1,16 @@ +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnInterface +{ + [AllureSeverity(SeverityLevel.critical)] + public interface IMetadataInterface {} + + [AllureNUnit] + public class TestsClass : IMetadataInterface + { + [Test] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs new file mode 100644 index 00000000..ad7266e5 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/SeverityAttributeOnMethod.cs @@ -0,0 +1,14 @@ +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.SeverityAttributeOnMethod +{ + [AllureNUnit] + public class TestsClass + { + [Test] + [AllureSeverity(SeverityLevel.critical)] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/SeverityTests.cs b/tests/Allure.NUnit.Tests/SeverityTests.cs new file mode 100644 index 00000000..4e78fb3b --- /dev/null +++ b/tests/Allure.NUnit.Tests/SeverityTests.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Nodes; +using Allure.Testing; + +namespace Allure.NUnit.Tests; + +class SeverityTests +{ + public static IEnumerable> GetSeveritySamples() + { + IEnumerable samples = [ + AllureSampleRegistry.SetSeverityFromSetUp, + AllureSampleRegistry.SetSeverityFromTest, + AllureSampleRegistry.SetSeverityFromTearDown, + AllureSampleRegistry.SeverityAttributeOnClass, + AllureSampleRegistry.SeverityAttributeOnMethod, + AllureSampleRegistry.SeverityAttributeOnBaseClass, + AllureSampleRegistry.SeverityAttributeOnInterface, + AllureSampleRegistry.LegacySeverityAttributeOnClass, + AllureSampleRegistry.LegacySeverityAttributeOnMethod, + AllureSampleRegistry.LegacySeverityAttributeOnBaseClass, + ]; + + return samples.Select(static (sample) => + new TestDataRow(sample, DisplayName: sample.Id)); + } + + [Test] + [MethodDataSource(nameof(GetSeveritySamples))] + public async Task CheckSuiteLabelsAreAdded(AllureSampleRegistryEntry sample) + { + var results = await AllureSampleRunner.RunAsync(sample); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var labels = results.TestResults[0]["labels"].AsArray().Cast(); + await Assert.That(labels).Any( + static (l) => + { + return (string)l["name"] == "severity" && (string)l["value"] == "critical"; + } + ); + } +} From 7e4041465b5fecfbe008441641e224ba3f19999f Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 20:27:25 +0700 Subject: [PATCH 32/80] test(nunit): add tag tests --- .../Samples/AddTagsApiCalls.cs | 27 +++++++ .../Samples/LegacyTagAttributes.cs | 17 ++++ .../Samples/NUnitCategoryAttributes.cs | 13 ++++ .../Samples/TagAttributes.cs | 20 +++++ tests/Allure.NUnit.Tests/TagTests.cs | 77 +++++++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/TagAttributes.cs create mode 100644 tests/Allure.NUnit.Tests/TagTests.cs diff --git a/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs b/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs new file mode 100644 index 00000000..2a59d698 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/AddTagsApiCalls.cs @@ -0,0 +1,27 @@ +using Allure.Net.Commons; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.AddTagsApiCalls +{ + [AllureNUnit] + public class TestsClass + { + [SetUp] + public void SetUp() + { + AllureApi.AddTags("foo"); + } + + [Test] + public void TestMethod() + { + AllureApi.AddTags("bar", "baz"); + } + + [TearDown] + public void TearDown() + { + AllureApi.AddTags("qux"); + } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs b/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs new file mode 100644 index 00000000..5980cb1a --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/LegacyTagAttributes.cs @@ -0,0 +1,17 @@ +using Allure.NUnit.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.LegacyTagAttributes +{ + [AllureTag("foo")] + public class BaseClass { } + + [AllureNUnit] + [AllureTag("bar")] + public class TestsClass : BaseClass + { + [Test] + [AllureTag("baz", "qux")] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs b/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs new file mode 100644 index 00000000..a43c62df --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/NUnitCategoryAttributes.cs @@ -0,0 +1,13 @@ +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.NUnitCategoryAttributes +{ + [AllureNUnit] + [Category("foo")] + public class TestsClass + { + [Test] + [Category("bar")] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs b/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs new file mode 100644 index 00000000..95b94531 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/TagAttributes.cs @@ -0,0 +1,20 @@ +using Allure.Net.Commons.Attributes; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.TagAttributes +{ + [AllureTag("foo")] + public interface IMetadata { } + + [AllureTag("bar")] + public class BaseClass { } + + [AllureNUnit] + [AllureTag("baz")] + public class TestsClass : BaseClass, IMetadata + { + [Test] + [AllureTag("qux", "qut")] + public void TestMethod() { } + } +} diff --git a/tests/Allure.NUnit.Tests/TagTests.cs b/tests/Allure.NUnit.Tests/TagTests.cs new file mode 100644 index 00000000..274cc54b --- /dev/null +++ b/tests/Allure.NUnit.Tests/TagTests.cs @@ -0,0 +1,77 @@ +using System.Text.Json.Nodes; +using Allure.Testing; + +namespace Allure.NUnit.Tests; + +class TagTests +{ + [Test] + public async Task AddTagsApiWorks() + { + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.AddTagsApiCalls); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var tags = results.TestResults[0]["labels"] + .AsArray() + .Cast() + .Where(static (l) => (string)l["name"] == "tag") + .Select(static (l) => (string)l["value"]) + .ToArray(); + await Assert.That(tags).IsEquivalentTo( + ["foo", "bar", "baz", "qux"], + TUnit.Assertions.Enums.CollectionOrdering.Matching + ); + } + + [Test] + public async Task TagAttributeWorks() + { + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.TagAttributes); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var tags = results.TestResults[0]["labels"] + .AsArray() + .Cast() + .Where(static (l) => (string)l["name"] == "tag") + .Select(static (l) => (string)l["value"]); + await Assert.That(tags).IsEquivalentTo( + ["foo", "bar", "baz", "qux", "qut"], + TUnit.Assertions.Enums.CollectionOrdering.Matching + ); + } + + [Test] + public async Task LegacyTagAttributeWorks() + { + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.LegacyTagAttributes); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var tags = results.TestResults[0]["labels"] + .AsArray() + .Cast() + .Where(static (l) => (string)l["name"] == "tag") + .Select(static (l) => (string)l["value"]); + await Assert.That(tags).IsEquivalentTo( + ["baz", "qux", "bar", "foo"], + TUnit.Assertions.Enums.CollectionOrdering.Matching + ); + } + + [Test] + public async Task NUnitCategoriesAreConvertedToTags() + { + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.NUnitCategoryAttributes); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + var tags = results.TestResults[0]["labels"] + .AsArray() + .Cast() + .Where(static (l) => (string)l["name"] == "tag") + .Select(static (l) => (string)l["value"]); + Console.WriteLine(string.Join(", ", tags)); + await Assert.That(tags).IsEquivalentTo( + ["foo", "bar"], + TUnit.Assertions.Enums.CollectionOrdering.Matching + ); + } +} From b5043a27e4768e618055f3632e9263054b91df61 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 21:24:57 +0700 Subject: [PATCH 33/80] test(nunit): add meta attribute tests --- .../Allure.NUnit.Tests/MetaAttributeTests.cs | 66 +++++++++++++++++++ .../Samples/MetaAttributes.cs | 43 ++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 tests/Allure.NUnit.Tests/MetaAttributeTests.cs create mode 100644 tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs diff --git a/tests/Allure.NUnit.Tests/MetaAttributeTests.cs b/tests/Allure.NUnit.Tests/MetaAttributeTests.cs new file mode 100644 index 00000000..fd667626 --- /dev/null +++ b/tests/Allure.NUnit.Tests/MetaAttributeTests.cs @@ -0,0 +1,66 @@ +using System.Text.Json.Nodes; +using Allure.Testing; + +namespace Allure.NUnit.Tests; + +class MetaAttributeTests +{ + [Test] + public async Task MetaAttributeShouldWork() + { + var results = await AllureSampleRunner.RunAsync(AllureSampleRegistry.MetaAttributes); + + await Assert.That(results.TestResults.Cast()).Count().IsEqualTo(1); + + var labels = results.TestResults[0]["labels"].AsArray().Cast(); + var links = results.TestResults[0]["links"].AsArray().Cast(); + + await Assert.That(labels).Any( + static (l) => + { + return (string)l["name"] == "epic" && (string)l["value"] == "Foo"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "owner" && (string)l["value"] == "John Doe"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "feature" && (string)l["value"] == "Bar"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "tag" && (string)l["value"] == "foo"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "tag" && (string)l["value"] == "bar"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "story" && (string)l["value"] == "Baz"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "severity" && (string)l["value"] == "critical"; + } + ).And.Any( + static (l) => + { + return (string)l["name"] == "suite" && (string)l["value"] == "Qux"; + } + ); + await Assert.That(labels).Any( + static (l) => + (string)l["url"] == "https://foo.bar/" + && l["name"] is null + && l["type"] is null + ); + } +} diff --git a/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs b/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs new file mode 100644 index 00000000..05e3fb78 --- /dev/null +++ b/tests/Allure.NUnit.Tests/Samples/MetaAttributes.cs @@ -0,0 +1,43 @@ +using System; +using Allure.Net.Commons; +using Allure.Net.Commons.Attributes; +using Allure.NUnit; +using NUnit.Framework; + +namespace Allure.NUnit.Tests.Samples.MetaAttributes +{ + [AllureEpic("Foo")] + [AllureOwner("John Doe")] + [AttributeUsage(AttributeTargets.Interface)] + public class EpicOwnerAttribute : AllureMetaAttribute { } + + [AllureFeature("Bar")] + [AllureTag("foo", "bar")] + [AttributeUsage(AttributeTargets.Class)] + public class FeatureTagsAttribute : AllureMetaAttribute { } + + [AllureStory("Baz")] + [AllureLink("https://foo.bar/")] + [AttributeUsage(AttributeTargets.Class)] + public class StoryLinkAttribute : AllureMetaAttribute { } + + [AllureSeverity(SeverityLevel.critical)] + [AllureSuite("Qux")] + [AttributeUsage(AttributeTargets.Method)] + public class SeveritySuiteAttribute : AllureMetaAttribute { } + + [EpicOwner] + public interface IMetadata { } + + [FeatureTags] + public class BaseClass { } + + [AllureNUnit] + [StoryLink] + public class TestsClass : BaseClass, IMetadata + { + [Test] + [SeveritySuite] + public void TestMethod() { } + } +} From da157e852b212adc0617d43b6df6d49bd95c6839 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 30 Jan 2026 22:32:45 +0700 Subject: [PATCH 34/80] feat(commons): add get API for allure attrs --- .../Sdk/AllureMetadataAttribute.cs | 114 ++++++++--- .../AttributeApplicationTests.cs | 193 +++++++++++++++++- 2 files changed, 281 insertions(+), 26 deletions(-) diff --git a/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs b/src/Allure.Net.Commons/Sdk/AllureMetadataAttribute.cs index 1e6274ed..2a2d44d4 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.Collections; +using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -33,18 +35,72 @@ public const AttributeTargets ALLURE_METADATA_TARGETS /// 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); }