// codeart.ru / Вопрос/Ответ / Немного про State тестирование в TDD Форум

Немного про State тестирование в TDD rss подписка

Автор: Evgeny Sergeev

Насколько я понимаю, в Unit тестировании существует два основных способа построения тестов: State-based testing (Тестирования состояния объекта) и behavior-base testing (Тестирование поведения объекта). Новичкам в TDD обычно предлагают освоиться с первым, а только потом переходить ко второму. В связи с тем, что TDD я изучаю не так давно, у меня возникает куча вопросов и предположений. В этом посте я хочу немного поразмыслить над Тестированием состояния объекта и по возможности получить комментарии о том, что я понимаю правильно, а что нет.

Итак, state bases testing - это такое тестирование, при котором проверяется состояние объекта. В прошлых постах я уже размышлял на тему состояний у модели, а так же о том, как они могут выражаться. Поэтому мне вроде бы понятно, что при использовании данного метода тестирования следует проверять значение набора переменных в контексте состояния объекта.

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

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

И еще один момент - при тестировании состояния объекта вряд ли можно добиться 100% покрытия кода (если его вообще можно добиться). В любом случае тесты будут покрывать какое-то ограниченное количество интересующих нас состояний. А все остальные недокументированные состояния, которые по сути и являются источником проблем, останутся непроверенными. Поэтому опять же возникает вопрос: как определить минимально необходимое количество состояний, которое позволит получить более менее высокую надежность кода? Очень интересует практический опыт. Если есть, что сказать, то очень прошу поделиться своим мнением в комментариях.

Предвидя вопросы, сразу скажу, что я “вкурил” огромную кучу теории, но на практике, когда сложность системы значительно превышает сложность демонстрационных примеров, возникает такое ощущение, что тестировать можно бесконечно.

  1. Немного о behaviour тестировании в TDD

    Лучшие комментарии

  1. “State-based testing” подразумевает не то, что ты будешь воспринимать обьект как state machine, а то, что ты будешь проверять результат работы методов постфактум.

    Например - проверить то, что ты опубликовал статью можно двумя способами:

    1. Вызвать “article.publish”. Проверить, что “article.published_at == Time.now”.
    2. Создать message expectation на то, что будет вызван метод “article.update_attributes” с параметром “{ :published_at => Time.now}”. Вызвать “article.publish”. Таким образом ты убираешь из тестирования работу с бд (и подразумеваешь, что update_attributes будут правильно отработаны), завязываешь метод publish на метод update_attributes (с одной стороны - плохо, ибо ты не сможешь потом переписать метод по-другому без изменения теста, с другой стороны - ты более явно описываешь интерфейс обьекта article).

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

    Да, и во втором случае ты надеешься на то, что update_attributes протестирован и работает как надо.

  1. А может ну его нафиг, TDD? )

  2. “State-based testing” подразумевает не то, что ты будешь воспринимать обьект как state machine, а то, что ты будешь проверять результат работы методов постфактум.

    Например - проверить то, что ты опубликовал статью можно двумя способами:

    1. Вызвать “article.publish”. Проверить, что “article.published_at == Time.now”.
    2. Создать message expectation на то, что будет вызван метод “article.update_attributes” с параметром “{ :published_at => Time.now}”. Вызвать “article.publish”. Таким образом ты убираешь из тестирования работу с бд (и подразумеваешь, что update_attributes будут правильно отработаны), завязываешь метод publish на метод update_attributes (с одной стороны - плохо, ибо ты не сможешь потом переписать метод по-другому без изменения теста, с другой стороны - ты более явно описываешь интерфейс обьекта article).

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

    Да, и во втором случае ты надеешься на то, что update_attributes протестирован и работает как надо.

  3. fxposter, ИМХО, идея как раз в том, чтобы представить объект как кончены автомат.
    В твоем примере четко прослеживается два состояние (наверняка их больше, но не суть): во-первых, состояние “статья не опубликована”, во-вторых состояние “статья опубликована”.

    Относительного второго варианта, я правильно понимаю, что это behavior-base testing?

  4. Тормоз, :-) Нет, тестирование штука полезная, только главное определить некий необходимый минимум - что тестировать, а что нет. Это как раз сложно.

Leave a Reply

« Про Agile методологию Немного о behavior тестировании в TDD »

 

обучение по пожарно-техническому минимуму | ремонт iphone | куплю инструмент санкт-петербург . | муфта оптическая санкт-петербург.