Глобальная инициализация NUnit - плохая идея?
В нашем тестовом наборе нам нужен какой-то глобальный один установочный код. Мы можем делать это не один раз, но это занимает довольно много времени.
-
Требуется для всех приборов, поэтому [TestFixtureSetUp]
не работает. Он должен выполняться перед всем кодом [TestFixtureSetUp]
.
-
Поместите его в Main()
, поскольку мы сохраняем тестовые сборки как исполняемые файлы. Однако Main
не выполняется при помощи GUI-клиента.
-
Создание отдельного класса со статическим конструктором для инициализации работает только тогда, когда вы ссылаетесь на класс, который нам не нравится делать в каждом классе.
-
Наследование всех тестовых устройств из базового класса и добавление к нему статического конструктора вызывает несколько вызовов кода инициализации.
Теперь, учитывая обстоятельства, у меня есть два вопроса:
1) Является ли "глобальная настройка" очень плохой идеей, что она не поддерживается NUnit?
2) Какой наименее болезненный, самый распространенный способ достичь этого?
Ответы
Ответ 1
[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
Ответ 2
Как указано в моем комментарии, вы можете выполнить сборку init с помощью 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
Примечание. Как указано другими, не используйте это, чтобы испортить изоляцию между вашими тестами.
Ответ 3
Я не думаю, что к сожалению, есть хороший, встроенный способ добиться этого - возможно, потому, что NUnit предназначен для использования в основном для модульных тестов, и вам не нужна глобальная настройка для модульных тестов (все должно быть локально издевались над каждым испытательным прибором).
Однако довольно часто можно использовать NUnit для тестов интеграции, и там очень часто бывает глобальная настройка - как в вашем случае. Здесь есть несколько разумных вариантов:
-
В моем текущем проекте мы обычно делаем в msbuild script, который запускает тесты. Преимущества в том, что вам не нужно помнить о какой-либо специальной настройке при написании новых тестов. Недостаток - вы должны убедиться, что все настроено, когда вы запускаете тесты из среды IDE.
-
Если выше не вариант, вы можете использовать свою последнюю идею - наследовать тесты из общего базового класса. Тогда базовый класс мог бы ссылаться на одноэлементный класс (вы можете найти статью Джона Скита о том, как реализовать синглтон), которая будет выполнять настройку. Таким образом, он будет запускаться только один раз.
Ответ 4
1) Я думаю, это зависит от контекста. Мне никогда не нужна глобальная настройка для любого проекта, но я могу представить сценарии, например. приложение, которое только считывает данные и общую глобальную настройку данных.
2) Вы можете сделать свою глобальную настройку, например. в базе приборов вы упоминаете, состояние. То есть имеют свойство HasRun или тому подобное, которое проверяется перед выполнением.