# Тестируйте требуемое поведение, а не случайное

(В оригинале - Test for Required Behavior, not Incidental Behavior)

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

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

Например, сравнение вроде `strcmp` в С или `String.compareTo` в Java требует, чтобы результат был отрицательным, если левая часть меньше правой, положительным, если наоборот и нулевым, если обе части равны. Этот стиль сравнения используется множеством API, включая `comparator` для функции `qsort` в С и `CompareTo` в `Comparable` интерфейсе в Java. И хотя в реализациях очень часто используются значения `+1` и `-1`, считать, что эти значения являются требованием к реализации, будет ошибкой. Написание теста исходя из этого предположения приведет к тому, что ошибочное предположение материализуется.

Подобные вещи происходят с тестами, проверяющими количество пробелов, точное написание слов и другие аспекты форматирования, часто являющиеся случайными. Кроме случаев, когда вы пишете XML-генератор, предлагающий настраиваемое форматирование, количество пробелов не должно быть значимым для итогового результата. Точно также жесткая привязка к позициям элементов GUI снижает возможность дальнейшего изменения. Небольшое и незначимое изменение в реализации или форматировании в результате внезапно становится «убийцей» сборки.

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

Чтобы быть эффективными, тесты должны проверять только контрактные обязательства, а не реализацию. Тестируемый юнит должен рассматриваться как «черный ящик», предоставляющий интерфейс в исполняемом виде. Поэтому старайтесь, чтобы тестируемое поведение было идентичным требуемому.

Автор оригинала - [Kevlin Henney](http://programmer.97things.oreilly.com/wiki/index.php/Kevlin_Henney)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://97-things-every-x-should-know.gitbook.io/97-things-every-programmer-should-know/ru/thing_82.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
