Пропуск целого тестового класса в xUnit.net

Можно ли пропустить все тесты из определенного класса, как в NUnit

[TestFixture]
[Ignore("Reason")]
public class TestClass {
}

person dwonisch    schedule 12.02.2013    source источник


Ответы (10)


Нет — такой возможности в настоящее время нет,

Один из быстрых способов добиться эффекта в xUnit — закомментировать public — частные классы не отражаются (очевидно, что таким образом они не будут отображаться в списке пропуска).

Подумайте о том, чтобы зарегистрировать это как проблему на CodePlex, если вы считаете, что потребность в этом достаточно распространена (лично я не могу представить, чтобы за нее проголосовали, поскольку я просто не сталкиваюсь со случаями, когда мне нужно пропустить целый тестовый класс).

ОБНОВЛЕНИЕ: Другой способ - поместить TraitAttribute в класс, а затем (при условии, что вы используете бегун xunit.console) отфильтровать его, запустив с /-trait traitName. (например, вы можете достичь ExplicitAttribute, некоторых аспектов инфраструктурной техники BDD ожидающих тестов и аналогичной семантики таким образом - конечно, большая проблема в том, что они не отображаются ни в каких отчетах при использовании любого из этих методов фильтрации)

ОБНОВЛЕНИЕ 2: вы можете сделать

const string skip = "Class X disabled";

[Fact(Skip=skip)]
void Test() {}

Затем вы можете перейти на const string skip = null, чтобы отменить пропуск. (Не)преимущество этого заключается в том, что тест по-прежнему отображается как пропущенный тест в списке тестов, как правило, с указанием причины, указанной в отчете о выполнении теста (вместо того, чтобы сделать его private, что делает его, вероятно, забытым)

person Ruben Bartelink    schedule 13.02.2013
comment
@woni Добавлена ​​идея использования черты на случай, если она соответствует вашему контексту (хотя я полагаю, что нет!) - person Ruben Bartelink; 18.02.2013
comment
С xUnit ›= 2.3 вы получите сообщение об ошибке error xUnit1000: Test classes must be public - person andrei.ciprian; 20.10.2017
comment
@andrei.ciprian, можете ли вы пояснить, откуда взялась эта ошибка / как она появилась? (IIRC - это плагин roslyn, который помечает его в среде IDE, а не во время выполнения?) - person Ruben Bartelink; 20.10.2017

Вот мой хак, чтобы избежать ошибки xUnit1000: тестовые классы должны быть общедоступными (проверено на одном факте, я думаю, что теории тоже можно взломать таким образом).

// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!

// Uncomment to disable tests
internal class FactSwitch : Attribute { }

public class MyTests
{
    [FactSwitch]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

(3 года спустя)

При поиске того же решения я обнаружил, что есть лучшие способы сделать то же самое. Перепишем приведенный выше пример так, как предложил Рубен Бартелинк (продолжение его идеи).

public class MyTests
{
    //const string SkipOrNot = null; // Run all tests
    const string SkipOrNot = "reason"; // Skip all tests

    [Fact(Skip = SkipOrNot)]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

Натан Купер предложил хорошее улучшение моей идеи:

public class MyTests
{
    // Uncomment to disable tests
    //private class FactAttribute : Attribute { }

    [Fact]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

Так что мне нравятся обе идеи Рубена и Натана. Есть тонкая разница между использованием Skip=something (Рубен) и отказом от использования Skip вообще. Использование Skip поместит все ваши тесты в зону предупреждения о пропущенных тестах, а FactAttribute : Attribute скроет их.

person Remigijus Pankevičius    schedule 16.01.2018
comment
Использование #define Fact Attribute более компактно и позволит вам продолжать использовать [Fact]. - person Brad Wilson; 19.01.2018
comment
Было бы неплохо, но это не C++, есть ограничения на использование #define - person Remigijus Pankevičius; 22.01.2018
comment
вы также можете сделать const SkipIt = "reason" // change to null to run, а затем сделать Fact(Skip=SkipIt), чтобы сделать это условным - person Ruben Bartelink; 26.10.2018
comment
Старый поток, но вы просто можете поместить private class FactAttribute : Attribute { } внутри класса, чтобы превзойти [Fact], потому что пространства имен. - person Nathan Cooper; 13.11.2019

Добавление причины почти через год после первоначального вопроса. У меня есть набор тестов, которые вызывают API реального сервера, и я хотел бы запускать их по требованию. С nUnit у него есть атрибут Ignore: с этим набором средство запуска тестов пропустит эти тесты, но я все равно могу запустить его вручную.

xUnit не имеет такой функции. Ближайший из них устанавливает такой атрибут уровня класса и комментирует его, когда я хочу его запустить.

person Rana Hossain    schedule 06.02.2014

Вы можете добиться этого с помощью специальной команды ITestClassCommand.

См. http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html

person bob    schedule 15.08.2014

Вот еще один хак, который требует минимальных изменений в коде

using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;

Для замены можно использовать любой совместимый атрибут.

Если вы также используете InlineDataAttribute, вам нужно будет определить замену, поскольку я не думаю, что существует существующий совместимый атрибут.

using InlineDataAttribute = DummyDataAttribute;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
    public DummyDataAttribute(params object[] data)
    {
    }
}
person Andriy Svyryd    schedule 26.11.2018

Вы можете создать LocalOnlyFactAttribute

    public class LocalOnlyFactAttribute : FactAttribute
    {
        //uncomment to run on local
        //const string skip = null; 

        //keep this to avoid slow running tests on other env
        const string skip = "Disabled slow running tests."; 

        public override string Skip { get => skip; set => base.Skip = value; }
    }   
person user2134475    schedule 14.05.2020
comment
base.Skip, а не this.Skip или у вас есть stackoverflow - person Ricibald; 11.01.2021

Насколько я знаю, самый простой способ динамически пропустить весь тестовый класс xUnit во время выполнения — это использовать TestFrameworkAttribute на уровне сборки, чтобы указать на класс, который реализует интерфейс ITestFramework (или наследуется от XunitTestFramework, что проще) и который переопределяет метод CreateDiscoverer() для возврата другого класса, который реализует интерфейс ITestFrameworkDiscoverer (или наследуется от XunitTestFrameworkDiscoverer, что проще), где вы, наконец, можете переопределить метод IsValidTestClass(), чтобы решить, следует ли пропускать класс или нет.

Вот пример кода:

[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]

namespace MyNamespace.Xunit
{
    public class MyTestFramework : XunitTestFramework
    {
        public MyTestFramework(IMessageSink messageSink)
            : base(messageSink)
        {
        }

        protected override ITestFrameworkDiscoverer CreateDiscoverer(
            IAssemblyInfo assemblyInfo)
            => new MyTestFrameworkDiscoverer(
                assemblyInfo,
                SourceInformationProvider,
                DiagnosticMessageSink);
    }

    public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
    {
        public MyTestFrameworkDiscoverer(
            IAssemblyInfo assemblyInfo,
            ISourceInformationProvider sourceProvider,
            IMessageSink diagnosticMessageSink,
            IXunitTestCollectionFactory collectionFactory = null)
            : base(
                assemblyInfo,
                sourceProvider,
                diagnosticMessageSink,
                collectionFactory)
        {
        }

        protected override bool IsValidTestClass(ITypeInfo type)
            => base.IsValidTestClass(type) &&
               FilterType(type);

        protected virtual bool FilterType(ITypeInfo type)
        {
            // Insert your custom filter conditions here.
            return true;
        }
    }
}

Протестировано с помощью xUnit 2.4.1.

Мы используем его в Pomelo.EntityFrameworkCore.MySql (см. -L20" rel="nofollow noreferrer">AssemblyInfo.cs и MySqlXunitTestFrameworkDiscoverer.cs) (немного сложнее, чем пример кода здесь).

person lauxjpn    schedule 24.04.2021

Я нашел еще один способ временного отключения всего класса без предупреждения компилятора.

Неполноценный:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}

чтобы включить перемещение /* на одну строку вверх (т.е. с помощью alt+up):

/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}

Обратите внимание, что использование полного пути к пространству имен для SupressMessage не мешает вашему использованию.

person Miq    schedule 30.03.2020

Рассмотрите возможность создания LocalOnlyFactAttribute, который можно повторно использовать в нескольких тестовых файлах.


    public class LocalOnlyFactAttribute : FactAttribute
    {
        //uncomment to run on local
        //const string skip = null; 

        //keep this to avoid slow running tests on other env
        const string skip = "Disabled slow running tests."; 

        public override string Skip { get => skip; set => this.Skip = value; }
    }   
person Community    schedule 14.05.2020

Вам нужно установить уровень доступа вашего класса как внутренний и подавить сообщение, как это сделал @Miq:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
person Murilo Maciel Curti    schedule 15.06.2020