Является ли плохая форма рассчитывать на порядок ваших единичных тестов NUnit - программирование
Подтвердить что ты не робот

Является ли плохая форма рассчитывать на порядок ваших единичных тестов NUnit

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

Можете ли вы определить порядок тестов в NUnit или они всегда выполняются в алфавитном порядке?

Примечание. Я специально спрашиваю о порядке тестирования в одном тестовом файле. Не через тестовые файлы или каким-либо образом более глобально.

Обновление: Спасибо всем, кто ответил - было много хороших ответов, и чувство группы было довольно единодушным. Я выбрал ответ Джона Нолана, поскольку он предоставил наиболее полное объяснение и множество ссылок. Как вы, возможно, догадались, я был очень искушен нарушить это правило, несмотря на то, что думал, что это может быть немного "вонючий", как сказал Джон. Спасибо также Fortyrunner за добавление тега unit-testing.

4b9b3361

Ответ 1

Опираясь на порядок ваших тестов, вы указываете, что вы сохраняете состояние в тестах. Это вонючий

Более чистый способ тестирования - это то, где вы зависите только от одной части функциональности, которую вы хотите проверить. Обычно вы mock другие объекты, необходимые для проверки вашего метода.

Хороший способ подумать о приближающихся модульных тестах - это Упорядочить, Act, Assert.

Ниже приведен фрагмент от Карла Сегина, отличный eBook. Я отредактировал Arrange, Act и Assert.

[TestFixture] public class CarTest 
{ 
    [Test] public void SaveCarCallsUpdateWhenAlreadyExistingCar()   
    {
         //Arrange
         MockRepository mocks = new MockRepository();
         IDataAccess dataAccess = mocks.CreateMock<IDataAccess>();   
         ObjectFactory.InjectStub(typeof(IDataAccess), dataAccess); 
         //Act
         Car car = new Car(); 
         Expect.Call(dataAccess.Save(car)).Return(389); 
         mocks.ReplayAll(); 
         car.Save(); 
         mocks.VerifyAll(); 
         // Assert
         Assert.AreEqual(389, car.Id); 
         ObjectFactory.ResetDefaults();
    } 
}

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

Я действительно не стал бы полагаться на заказ тестов. Вместо этого я бы вытащил общий код установки в отдельный метод и вызвал это как из простого теста, так и из более сложного. Кроме того, просто вызовите тест вставки в начале теста удаления.

Ответ 6

Я бы настоятельно советовал сделать все ваши модульные тесты независимыми.

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

Кроме того, один неудачный unit test не должен перетаскивать многие другие (которые могут отлично работать самостоятельно) вниз.

Ответ 7

К сожалению, порядок работы unit test не предсказуем или, по крайней мере, может быть изменен в будущем. Например. модульная структура тестирования будет изменена, чтобы каждый тест выполнялся в отдельном потоке. Поэтому с моей точки зрения использование тестового заказа нецелесообразно. С другой стороны, вы можете создать набор небольших независимых тестов для проверки небольших частей вашего кода, а затем создать один или несколько крупных тестов, которые будут запускать ваши небольшие тесты в определенном порядке.

Ответ 8

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

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

Было бы очень неразумно зависеть от порядка между (наборами) тестов в разных файлах.