2015-07-11 1 views
0

Мы пытаемся использовать TDD для создания нашей системы, и мы пришли к ситуации, когда мы не можем понять, что такое правильный курс TDD.TDD - Как протестировать .Read() без .Write()?

Мы спрятали файл IO за интерфейсом, как так:

public interface IFileIo 
{ 
    byte[] Read(string fileName); 
    void Write(string filename, byte[] data); 
} 

и в настоящее время мы создаем InMemoryFileIo, что мы можем использовать вместо реального SystemFileIo класса, который мы будем использовать для производства ,

Мы хотим убедиться, что этот InMemoryFileIo работает правильно, и могут быть случаи, когда мы хотим использовать его вместо фактической файловой системы, поэтому это должно быть «качество продукции».

Вопрос в том, что делает все «правильный путь TDD», как мы можем создать тест для .Read() или .Write(), где они не зависят друг от друга?

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

Допустим, у нас есть два теста, один из которых проверяет .Read() и тот, который проверяет .Write(). Если какая-либо из этих функций не работает, то оба теста терпят неудачу. Это нарушает принцип, согласно которому «Тест должен иметь только одну причину неудачи».

Пример здесь для файла IO, но этот же вопрос возник из-за нас при работе с базой данных (тест put без get).

+1

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

+2

«Правильный» способ (который опять же, не беспокойтесь об этом) был бы для InMemoryFileIo взять 'byte []' в своем конструкторе вместо его создания (инъекция зависимостей), которая позволит вам предварительно установить данные чтобы читать или запускать проверки данных, написанных внешне друг с другом - действительно, не переусердствуйте, просто напишите те тесты, которые имеют для вас смысл, и четко определите недостатки системы. –

+0

Я думаю, что стоит отметить, что если ваш IO-класс в памяти используется только как двойной тест, он должен быть достаточно простым, чтобы не требовать кучу тестирования. точка имеет подделку для других классов, которые вы TDDing, которые зависят от интерфейса правильно? связать их прохождение или не пройти тест на то, является ли ваш фальшивый файл IO в памяти ошибкой без ошибок, кажется мне потенциально плохим идеей. Я предлагаю держать ваши заглушки мертвыми просто. – kai

ответ

2

Весь вопрос сводится к тому, как именно вы определяете свои «единицы». Для меня лично это помогает думать о «единице» как о когерентном наборе поведения, а не о вызове одного метода.

Roy Osherove определяет единицу как:

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^