In the Xunit.Sdk.ITraitDiscoverer interface GetTraits method's argument 'traitAttribute' is having actual attribute value, but unfortunately the is no direct way to get it as Xunit.Abstractions.IAttributeInfo has no getter which is weird. Here is just another solution without calling GetConstructorArguments()
Enum for exact categories we need
public enum Category
{
UiSmoke,
ApiSmoke,
Regression
}
Custom attribute definition
[TraitDiscoverer("Automation.Base.xUnit.Categories.CategoryDiscoverer", "Automation.Base")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class TestCategoryAttribute : Attribute, ITraitAttribute
{
public string Category { get; }
public TestCategoryAttribute(Category category)
{
Category = category.ToString();
}
}
And here is the category resolver/discoverer
public sealed class CategoryDiscoverer : ITraitDiscoverer
{
public const string Key = "Category";
public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)
{
var category = traitAttribute.GetNamedArgument<string>(Key);
yield return new KeyValuePair<string, string>(Key, category);
}
}
Here is the catch we need to know exact property name in the TestCategoryAttribute type, in discoverer its defined using Key constant.
Anyway, both GetConstructorArguments() and GetNamedArgument() are based on reflection, while discoverer is executed per each test once being run which is not that super-fast.