Skip to content

Base class XUnit Allure attributes are not applied when child class has attributes #384

@mingazhev

Description

@mingazhev

I'm submitting a ...

  • bug report
  • feature request

What is the current behavior?

There are 2 test classes, one inherits from another:

[AllureLabel("layer", "unit")]
public class BaseTest
{
// Test methods
}

[AllureStory("User registration")]
public class UserRegistrationTests : BaseTest
{
// Test methods
}

When test methods are executed, there is only "story" label in "labels" in results JSON:

"labels": [
    // Other labels
    {
      "name": "story",
      "value": "User registration"
    }
  ],

However, if I remove "AllureStory" like the following:

[AllureLabel("layer", "unit")]
public class BaseTest
{
// Test methods
}

public class UserRegistrationTests : BaseTest
{
// Test methods
}

resulting JSON will have the property from the base BaseTest class I need:

"labels": [
    // Other labels
    {
      "name": "layer",
      "value": "unit"
    }
  ],

What is the expected behavior?

I want all the attributes from the base classes to be added to Allure report

What is the motivation / use case for changing the behavior?

It is convenient to have a base class for the service to provide common Allure information for the whole service or project, such as:

  • layer
  • service name
  • component
    without the need to copy them everywhere.

Environment:

  • Allure version: 2.10-SNAPSHOT
  • Test framework: XUnit

Other information

This behaviour exists because of a, bit strange, logic inside XUnits GetCustomAttributes method:

        internal static IEnumerable<IAttributeInfo> GetCustomAttributes(Type type, Type attributeType, AttributeUsageAttribute attributeUsage)
        {
            IEnumerable<IAttributeInfo> results = Enumerable.Empty<IAttributeInfo>();

            if (type != null)
            {
                List<ReflectionAttributeInfo> list = null;
                foreach (CustomAttributeData attr in type.GetTypeInfo().CustomAttributes)
                {
                    if (attributeType.GetTypeInfo().IsAssignableFrom(attr.AttributeType.GetTypeInfo()))
                    {
                        if (list == null)
                            list = new List<ReflectionAttributeInfo>();

                        list.Add(new ReflectionAttributeInfo(attr));
                    }
                }

                if (list != null)
                    list.Sort((left, right) => string.Compare(left.AttributeData.AttributeType.Name, right.AttributeData.AttributeType.Name, StringComparison.Ordinal));

                results = list ?? Enumerable.Empty<IAttributeInfo>();

                if (attributeUsage.Inherited && (attributeUsage.AllowMultiple || list == null))
                    results = results.Concat(GetCustomAttributes(type.GetTypeInfo().BaseType, attributeType, attributeUsage));
            }

            return results;
        }

It seems that it gets attributes from the base class only if there are no attributes in current one

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions