Код: http://mac-blog.org.ua/xunit-category-trait/.
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
using XunitCategoriesSample.Traits;
namespace XunitCategoriesSample.Traits
{
public class CategoryDiscoverer : ITraitDiscoverer
{
public const string KEY = "Category";
public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)
{
var ctorArgs = traitAttribute.GetConstructorArguments().ToList();
yield return new KeyValuePair<string, string>(KEY, ctorArgs[0].ToString());
}
}
//NOTICE: Take a note that you must provide appropriate namespace here
[TraitDiscoverer("XunitCategoriesSample.Traits.CategoryDiscoverer", "XunitCategoriesSample")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CategoryAttribute : Attribute, ITraitAttribute
{
public CategoryAttribute(string category) { }
}
}
namespace XunitCategoriesSample
{
public class Class1
{
[Fact]
[Category("Jobsearcher")]
public void PassingTest()
{
Assert.Equal(4, Add(2, 2));
}
[Fact]
[Category("Employer")]
public void FailingTest()
{
Assert.Equal(5, Add(2, 2));
}
int Add(int x, int y)
{
return x + y;
}
}
}
ВНИМАНИЕ вы должны обеспечить правильные пространства имен в атрибуте TraitDiscoverer.
Но здесь больше, позволяет сделать еще более специализированные атрибуты:
public class JobsearcherTraitDiscoverer : ITraitDiscoverer
{
public const string VALUE = "Jobsearcher";
public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)
{
yield return new KeyValuePair<string, string>(CategoryDiscoverer.KEY, VALUE);
}
}
[TraitDiscoverer("XunitCategoriesSample.Traits.JobsearcherTraitDiscoverer", "XunitCategoriesSample")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class JobsearcherTraitAttribute : Attribute, ITraitAttribute
{
public JobsearcherTraitAttribute()
{
}
}
Так теперь вы сможете просто ввести [JobsearcherTrait]
Ссылки:
https://github.com/xunit/xunit/issues/394 - обсуждение о том, почему TraitAttribute был отмечен как запечатанный
https://github.com/xunit/samples.xunit/tree/master/TraitExtensibility - образец от xunit как сделать пользовательские атрибуты
https://github.com/wespday/CategoryTraits.Xunit2 - еще один образец
https://github.com/xunit/xunit/blob/47fdc2669ae6aa28f6d642e202840193dfc7dbd7/test/test.xunit.execution/Common/TraitHelperTests.cs - XUnit тестовый образец реализации пользовательских атрибутов
Это, безусловно, запрос функции. Не знаете, где бы вы остановились, есть другие атрибуты, и вы можете думать о внешних атрибутах или о любых шаблонах (например, соглашениях об именах), которые вы, возможно, захотите снова сопоставить. У вас будет комбинаторный взрыв в представлении свойств без пользовательского интерфейса, чтобы выбрать то, что вы хотите. В конце концов, это может быть больше возможностей запросить команду VS для Test Explorer (т. Е. Способ указать богатые запросы для тестов), чем функция xUnit для полуинструмента. – tne