Подтвердить что ты не робот

Есть ли способ иметь SetUpFixture, который выполняется один раз для каждого класса, а не один раз для пространства имен?

Сценарий
Прежде всего, я новичок в тестировании, поэтому, пожалуйста, несите меня. Внутри моего тестового проекта есть папка Controllers. Папка Controllers может содержать ControllerATest.cs, ControllerBTest.cs и ControllerCTest.cs. Поскольку мое пространство имен совпадает с моей структурой папок, все они разделяют пространство имен MyProject.Tests.Controllers.

Из того, что я читал в NUnit SetUpFixture Documentation, [SetUpFixture] внутри этого пространства имен будет выполняться один раз для всего пространства имен. То есть, если я запустил все мои контрольные тесты сразу - SetUpFixture будет выполняться только один раз.

Проблема
Как я уже сказал, каждый тест контроллера разделяет пространство имен. SetUpFixtures применяются ко всему пространству имен. Что делать, если я хочу, чтобы каждый контроллер имел свой собственный SetUpFixture? Это проблема, когда SetUpFixtures применяются ко всем пространствам имен. То, что я хочу, это то, что выполняется один раз, а не для каждого теста. Одна из вещей, которые я делаю внутри SetUpFixture SetUp, создает экземпляр контроллера. Конечно, я мог бы создать все три контроллера в SetUpFixture, но это кажется уродливым, когда, возможно, я только тестирую ControllerC. Это действительно не кажется чистым. Поэтому я хотел бы, чтобы SetUpFixture применялся только к классу, в котором он появился, например ControllerCTests.

Из того, что я прочитал, эта функция не может быть реализована с помощью NUnit. И если это невозможно с NUnit, это заставляет меня думать, что это не общий сценарий. И если это не общий сценарий, я делаю что-то неправильно. Мой вопрос: что? Возможно, моя структура тестирования отключена, и ее нужно изменить. Или возможно с NUnit?

Код
Пример моей желаемой структуры:

namespace MyProject.Tests.Controllers
{
public class ControllerATests
{
    private static IMyProjectRepository _fakeRepository;
    private static ControllerA _controllerA;

    [SetUpFixture]
    public class before_tests_run
    {
        [SetUp]
        public void ControllerASetup()
        {
            _fakeRepository = FakeRepository.Create();

            _controllerA = new ControllerA(_fakeRepository);
        }
    }

    [TestFixture]
    public class when_ControllerA_index_get_action_executes
    {
        [Test]
        public void it_does_something()
        {
            //
        }

        [Test]
        public void it_does_something_else()
        {
            //
        }
    }
}

public class ControllerBTests
{
    private static IMyProjectRepository _fakeRepository;
    private static ControllerB _controllerB;

    [SetUpFixture]
    public class before_tests_run
    {
        [SetUp]
        public void ControllerBSetup()
        {
            _fakeRepository = FakeRepository.Create();

            _controllerB = new ControllerB(_fakeRepository);
        }
    }

    [TestFixture]
    public class when_ControllerB_index_get_action_executes
    {
        [Test]
        public void it_does_something()
        {
            //
        }

        [Test]
        public void it_does_something_else()
        {
            //
        }
    }
}
}    

Вещи, которые я пробовал

  • Перемещение каждого файла .cs в его собственную папку, поэтому у них разные пространства имен. Технически это решает проблему, просто кажется немного уродливым иметь кучу вложенных папок с одним элементом в каждом из них. Ужасно, и больше не будет соответствовать моей родительской структуре проекта, к которой я шел. Но, возможно, это путь.
  • Не создайте экземпляр моего контроллера в SetUpFixture SetUp и вместо этого сделайте это в TestFixture SetUp, чтобы новый экземпляр был создан для каждого теста (например: 5 тестов = 5 отдельных экземпляров) вместо одного класса или пространства имен. Хотя кажется, что если мне удастся только создать 1 экземпляр, я должен.

Предложения?

4b9b3361

Ответ 1

Используйте TestFixtureSetUpAttribute для метода в вашем классе контроллера:

[TestFixture]
public class when_ControllerA_index_get_action_executes
{
    [TestFixtureSetUp]
    public void FixtureSetUp()
    {
        // this code runs once no matter how many tests are in this class
    }

    [Test]
    public void it_does_something()
    {
        // ...
    }
}

Из документации:

Этот атрибут используется внутри TestFixture для предоставления одного набора функций, которые выполняются один раз до выполнения любого из тестов в приборе.

Здесь "TestFixture" является синонимом class.

Ответ 2

Для NUnit 3.4.1, а затем используйте OneTimeSetUp:

[TestFixture]
public class MyTest
{
    [OneTimeSetUp]
    public void Setup()
    {
        // one time setup code for this class
    }
}

Кстати, TestFixtureSetUp устарел.