NUnit глобальная инициализация - плохая идея? - PullRequest
36 голосов
/ 01 сентября 2010

Нам нужен глобальный однократный установочный код в нашем тестовом наборе.Мы можем сделать это не раз, но это займет довольно много времени.

  • Требуется всеми приборами, поэтому [TestFixtureSetUp] не работает.Он должен выполняться до всего кода [TestFixtureSetUp].

  • Поместите его в Main(), поскольку мы сохраняем тестовые сборки как исполняемые файлы.Однако Main не выполняется в клиенте GUI.

  • Создание отдельного класса со статическим конструктором для инициализации работает только тогда, когда вы ссылаетесь на класс, который мы не одобряем в каждом из них.и каждый класс.

  • Наследование всех тестовых приборов из базового класса и добавление в него статического конструктора вызывает многократные вызовы кода инициализации.

Теперь, учитывая обстоятельства, у меня есть два вопроса:

1) Является ли "глобальная настройка" очень плохой идеей, что она не поддерживается NUnit?

2) Что является наименее болезненным, наиболее распространеннымспособ достичь этого?

Ответы [ 5 ]

85 голосов
/ 29 апреля 2011

[SetUpFixture]

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

Метод SetUp в SetUpFixture выполняется один раз перед любым из приборов, содержащихся в его пространстве имен. Метод TearDown выполняется один раз после того, как все приборы завершили выполнение.

Инициализация всей сборки. Если вы не поместите класс в какое-либо пространство имен, он будет применяться ко всем тестам в сборке.

например.

// using statements

[SetUpFixture]
public class GlobalSetup {
  [SetUp]
  public void ShowSomeTrace() {
    Trace.WriteLine("It works..."); // won't actually trace
  }
}

http://www.nunit.org/index.php?p=setupFixture&r=2.4

11 голосов
/ 09 февраля 2011

Как отмечалось в моем комментарии, вы можете добиться инициализации всей сборки, используя SetUpFixture, расположенную на уровне сборки. Мне нужно было отключить пользовательский интерфейс на слушателе трассировки по умолчанию:

[SetUpFixture]
public class AssemblySetup
{
    [SetUp]
    public void Setup()
    {
        var traceListener = Debug.Listeners.Cast<TraceListener>().FirstOrDefault(listener => listener is DefaultTraceListener) as DefaultTraceListener;

        if (traceListener != null)
            traceListener.AssertUiEnabled = false;
    }
}

Подробнее о сборке или настройке пространства имен: http://www.nunit.org/index.php?p=setupFixture&r=2.4

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

6 голосов
/ 18 октября 2018

Начиная с NUnit 3.0, атрибут Setup больше не поддерживается внутри классов, помеченных атрибутом SetUpFixture.Текущий действительный синтаксис:

  [SetUpFixture]
  public class MySetUpClass
  {
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
      // ...
    }

    [OneTimeTearDown]
    public void RunAfterAnyTests()
    {
      // ...
    }
  }

Метод OneTimeSetUp в SetUpFixture выполняется один раз перед любым из приборов, содержащихся в его пространстве имен.Метод OneTimeTearDown выполняется один раз после того, как все приборы завершили выполнение.

Текущая страница документации SetUpFixture

1 голос
/ 02 сентября 2010

Я не думаю, что есть хороший, встроенный способ для достижения этого, к сожалению - вероятно, потому что NUnit предназначен для использования в основном для модульных тестов, и вам не нужна глобальная настройка для модульных тестов (все должно бытьлокально издевались в каждом испытательном приспособлении).

Тем не менее, довольно часто используется NUnit для интеграционных тестов, и там очень распространены глобальные настройки - как в вашем случае.Здесь есть несколько разумных вариантов:

  1. В моем текущем проекте мы обычно используем сценарий msbuild, который выполняет тесты.Преимущества в том, что вам не нужно помнить о каких-либо специальных настройках при написании новых тестов.Недостаток - вы должны убедиться, что у вас все настроено при запуске тестов из IDE.

  2. Если вышеприведенное не подходит, вы можете использовать свою последнюю идею - наследоватьтесты из общего базового класса.Затем базовый класс может ссылаться на одноэлементный класс (вы можете найти, например, статью Jon Skeets о том, как реализовать одноэлементный класс), который будет выполнять настройку.Таким образом, он будет запущен только один раз.

0 голосов
/ 02 сентября 2010

1) Я думаю, это зависит от контекста.Мне никогда не требовалась глобальная настройка ни для одного проекта, но я могу представить сценарии, например, приложение, которое только читает данные, и общую глобальную настройку данных.

2) Вы можете выполнить глобальную настройку, напримерв базе приборов, которую вы упоминаете, с состоянием.Т.е. есть свойство HasRun или подобное, которое проверяется перед выполнением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...