Как запустить код установки только один раз в тесте xUnit.net

19

Я пытаюсь настроить мои тесты с помощью Xunit. У меня есть требование удалить все изображения в начале запуска тестов, а затем каждый метод выполняет изменение размера изображения и сохраняет копию его вывода в папку. Папка должна быть очищена только один раз, а затем каждый метод сохранит их собственное изображение в папке.

Когда я использую IUseFixture<T> , функция ClearVisualTestResultFolder все еще вызывается перед каждым тестом, поэтому я получаю только одно изображение в папке.

public class Fixture
{
    public void Setup()
    {
        ImageHelperTest.ClearVisualTestResultFolder();
    }
}

public class ImageHelperTest : IUseFixture<EngDev.Test.Fixture>
{
    public void SetFixture(EngDev.Test.Fixture data)
    {
        data.Setup();
    }

    public static void ClearVisualTestResultFolder()
    {
        // Logic to clear folder
    }
}

Если я помещаю ClearVisualTestResultFolder в конструктор, он также вызывается один раз для каждого тестового метода. Мне нужно это просто запустить один раз, прежде чем все методы тестирования будут выполнены, как я могу достичь этого?

Если это имеет значение, я использую тестовый бегун ReSharper.

    
задан Chris 12.09.2012 в 03:03
источник

3 ответа

27

Следуя инструкциям в этом разделе обсуждения xUnit , похоже, что вам нужно реализовать конструктор на Fixture, а также реализовать IDisposable. Вот полный образец, который ведет себя так, как вы хотите:

using System;
using System.Diagnostics;
using Xunit;
using Xunit.Sdk;

namespace xUnitSample
{
    public class SomeFixture : IDisposable
    {
        public SomeFixture()
        {
            Console.WriteLine("SomeFixture ctor: This should only be run once");
        }

        public void SomeMethod()
        {
            Console.WriteLine("SomeFixture::SomeMethod()");
        }

        public void Dispose()
        {
            Console.WriteLine("SomeFixture: Disposing SomeFixture");
        }
    }

    public class TestSample : IUseFixture<SomeFixture>, IDisposable
    {
        public void SetFixture(SomeFixture data)
        {
            Console.WriteLine("TestSample::SetFixture(): Calling SomeMethod");
            data.SomeMethod();
        }

        public TestSample()
        {
            Console.WriteLine("This should be run once before every test " + DateTime.Now.Ticks);
        }

        [Fact]
        public void Test1()
        {
            Console.WriteLine("This is test one.");
        }

        [Fact]
        public void Test2()
        {
            Console.WriteLine("This is test two.");
        }

        public void Dispose()
        {
            Console.WriteLine("Disposing");
        }
    }
}

При запуске этого из консольного бегуна вы увидите следующий вывод:

  

D: \ xUnit & gt; xunit.console.clr4.exe test.dll / html foo.htm xUnit.net   консольный тестовый бегун (64-разрядный .NET 4.0.30319.17929) Авторское право (C)   2007-11 Корпорация Microsoft.

     

xunit.dll: Версия 1.9.1.1600 Тестовая сборка: test.dll

     

SomeFixture ctor: это нужно запускать только один раз

     

Тесты завершены: 2 из 2

     

SomeFixture: Disposing SomeFixture

     

2 всего, 0 не удалось, 0 пропущено, заняло 0,686 секунды

Затем, когда вы вскрываете тестовый выходной файл foo.htm, вы увидите другой тестовый результат.

    
ответ дан nithins 12.09.2012 в 04:13
12
  

Старый IUseFixture<T> интерфейс в xUnit.net v1.x был заменен   двумя новыми интерфейсами: IClassFixture<T> и ICollectionFixture<T> . В   Кроме того, механизм впрыскивания значений прибора в ваши тесты   изменилось с атрибутов свойств на аргументы конструктора. Класс   светильники создаются один раз и распределяются между всеми тестами в одном и том же   класса (очень похоже на старое IUseFixture). Коллекционные светильники работают   таким же образом, за исключением того, что один экземпляр является общим для всех тестов   в той же коллекции тестов.

    
ответ дан CodeZila 24.08.2015 в 08:02
6

IUseFixture<T>.SetFixture получает один раз для каждого теста. Сам Fixture создается только один раз.

Другими словами, вы не должны ничего делать в своем методе SetFixture, но вместо этого вы должны запускать его в конструкторе Fixture.

При однократной очистке реализуйте IDisposable.Dispose на Fixture (это не требуется)

Обратите внимание, что плохая идея - быть (даже потенциально) разделять состояние между тестами. Лучше всего использовать TemporaryDirectoryFixture как этот .

    
ответ дан Ruben Bartelink 12.09.2012 в 10:07