Как выполнить юнит-тест последовательной логики? - PullRequest
4 голосов
/ 08 июня 2009

Предположим, у меня есть класс Car со следующими методами:

  • LoadGasoline (топливный газ)
  • InsertKey (клавиша IKey)
  • StartEngine ()
  • IDrivingSession Go ()

Цель Car - настроить и вернуть IDrivingSession, который остальная часть приложения использует для управления автомобилем. Как мне протестировать мой автомобиль?

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

Test1: LoadGasoline, Assert

Test2: LoadGasoline, InsertKey, Assert

Test3: LoadGasoline, InsertKey, StartEngine, Assert

Test4: LoadGasoline, InsertKey, StartEngine, Go, Assert

Нет ли лучшего способа последовательной логики для модульного тестирования, или это проблема моего автомобиля?

--- РЕДАКТИРОВАТЬ ---- Спасибо за ответы на все вопросы. Как многие заметили, у меня также должны быть тесты на недопустимые сценарии, и у меня они тоже есть, но этот вопрос сосредоточен на том, как проверить правильную последовательность.

Ответы [ 6 ]

3 голосов
/ 08 июня 2009

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

ИМХО, вы должны подготовить среду для каждого случая, поэтому только тест LoadGasoline будет прерван, если вы измените метод LoadGasoline, и вам не нужно будет видеть, что все тесты прерываются из-за одной ошибки.

Я не знаю, как выглядит состояние вашего автомобиля, но перед InsertKey вы должны подготовиться с помощью метода, например, car.SetTotalGasoline (20); или какая-либо переменная установлена ​​в этом методе, но не зависит от сложной логики метода LoadGasoline.

Позже вам понадобится тест (в данном случае, а не модульный тест), чтобы проверить всю последовательность.

2 голосов
/ 08 июня 2009

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

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

В результате ваша тестовая последовательность будет выглядеть примерно так:

Test1: 
    LoadGasoline, Assert

Test2 Setup:
    LoadGasoline

Test2:
    InsertKey, Assert

Test3 Setup: 
    LoadGasoline, InsertKey

Test3:
    StartEngine, Assert

Test4 Setup: 
    LoadGasoline, InsertKey, StartEngine

Test4:
    Go, Assert

На самом деле, поскольку все тесты выполняются в последовательности, нет никакой вероятности сбоя установки теста, если предыдущий тест пройден.

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

1 голос
/ 08 июня 2009

Я бы, вероятно,

Test 1: LoadGasoline, Assert, InsertKey Assert, StartEngine Assert, Go Assert
Test 2: LoadGasoline, Go, Assert
Test 3: Go, Assert
Test 4: StartEngine, Go, Assert

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

Edit:

После некоторых размышлений у меня могут быть такие тесты, как:

  • Заведите ключ от машины, в котором нет газа
  • Завести автомобиль с бензином и неправильным ключом
  • Завести автомобиль с помощью газа и правого ключа (тест 1 выше)
  • Нажмите Peddle перед запуском автомобиля.
1 голос
/ 08 июня 2009

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

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

1 голос
/ 08 июня 2009

Почему вы не хотите все эти тесты?

Go ведет себя очень по-разному, если вы вызываете его до или после, скажем, InsertKey, верно? Так что, по моему мнению, вы должны проверить оба поведения.

0 голосов
/ 08 июня 2009

Технически вы должны использовать как минимум следующие тесты:

testLoadGasoline

testInsertKeyGasolineNotLoaded

testStartEngineKeyNotInserted

testGoEngineNotStarted

testGo

Если вы можете напрямую просмотреть промежуточные шаги, вы можете добавить

testInsertKeyGasolineLoaded

testStartEngineKeyInserted

Обратите внимание: если вы можете напрямую установить состояние (которое зависит от языка и дизайна), то testInsertKeyGasolineLoaded может на самом деле не звонить LoadGasoline.

...