понедельник, 25 ноября 2013 г.

Заметки о тестировании

Ещё раз хочу повторить вот что:

1. тест должен быть линейным
2. похожим на тест-кейс
3. читаться человеком
4. оперировать терминами предметной области

К чему это я?

Я сегодня просматривал код. Много разного кода. И некоторые вещи заставили меня задуматься о том, что есть вещи которые видимо стоит повторять неоднократно.


Итак.

Повторю ещё раз:

1. тест должен быть линейным
2. похожим на тест-кейс
3. читаться человеком
4. оперировать терминами предметной области

Для начала хочется сказать о линейности.

Предположим, что мы пишем тест на Паскале.

Так вот вот это:

OpenDocument(DocumentNumber);

if (SomeButton.Checked) then
 SomeButton.Checked := false;

DoOurWork;

-- не самый лучший тест.



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

1. Этот тест на самом деле с точки зрения пользователя распадается на два теста (сценария) - когда кнопка нажата или когда она не нажата.

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

А вот если она вдруг нажата - это означает, что "что-то пошло не так". Пользователь не ожидал этого. И значит у него "глаза на лоб полезли". Он судорожно пытается сообразить "что-же делать". Т.е. мы явно имеем дело с двумя сценариями взаимодействия пользователя и системы.

А следовательно надо писать - два или более тестов. Ну мне так кажется.

2. Проблема вся в том, что мы имеем дело с "ненастроенной системой" или с неправильными данными.

Тогда тест скорее всего надо писать так:

OpenDocument(DocumentNumber);
Assert(SomeButton.Checked);
DoOurWork;

- т.е. тест в данном случае однозначно не должен проходить.

Потому, что систему в "нестабильном состоянии" - нет смысла тестировать каким-либо образом, кроме как проверить её состояние.

3. Самый сложный для понимания случай. Т.е. он - прост вроде бы.

Но вот способ написания теста для него - неочевиден.

Итак - случай такой. Мы на самом деле имеем дело с последовательностью автоматических тестов, которые так или иначе могут "портить состояние системы".

И тесты написаны так, (ну или система ведёт себя так), что мы не можем обеспечить детерминированное поведение.

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

Тогда тест надо бы написать так:

OpenDocument(DocumentNumber);
MakeSureThatButtonIsNotChecked(SomeButton);
DoOurWork;

А "под капотом" или "за ширмой" мы имеем всё то же:

procedure MakeSureThatButtonIsNotChecked(aButton);
begin
 if aButton.Checked then
 begin
  OutToLog('a button' + aButton.Name + 'was expected to be unchecked');
  aButton.Checked := false;
 end;
end;

Вроде то же самое... "В чём разница спросите вы" и будете правы.

Попробую объяснить.

Вернёмся вот к каким тезисам - "читаться человеком" и "похожим на тест-кейс". В варианте с If в теле теста - имеем вот что - человек который прогоняет тест руками прочитав этот If будет считать, что ему необходимо "убрать с кнопки SomeButton состояние Checked".

Однако это не так. При тестировании руками на "неразваленной" системе этот случай как раз-таки говорит о том, что "что-то пошло не так" и что не надо продолжать ручное тестирование, а надо начать процесс разбирательства - "а как же так вышло".

Этим ручное тестирование и отличается от автоматического.

Именно поэтому там написано MakeSure. Убедиться что это так.

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

А записи в логе - по-моему - вполне достаточно, чтобы получить сигнал о проблеме.

Тут тонкая грань. На уровне "декларативность" против "императивности". Но надеюсь, что я смог её для вас прояснить.

Это вот совсем не из разряда - "верьте мне". Нет. Просто - захотелось поделиться.

2 комментария: