Single Statement Unit Tests

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

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

Посмотрите на этот метод тестирования из RandomStreamTest из OpenJDK 8, созданный Брайаном Гоэцом:

В этом методе есть две части: алгоритм и проверка. Алгоритм подготавливает два массива целых чисел, а проверка сравнивает их и вызывает исключение AssertionError, если они не равны.

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

Если бы в Java были моникеры, этот код выглядел бы еще более элегантно:

Как видите, в этом методе есть только одна “инструкция”: assertEquals().

Hamcrest, со своим assertThat() и своей коллекцией базовых матчеров, идеально подходит для сделать наши одноинструкционные тестовые методы еще более связанными и читаемыми.

Если мы согласимся следовать этому принципу, у нас будет несколько практических преимуществ.

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

  • Читаемость. С помощью единственного assert всегда будет ясно, какая цель у тестирующего метода. Он начнется с объявления намерения, в то время как все остальные низкоуровневые детали будут выровнены отступом.

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

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

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-17 at 14:39

sixnines availability badge   GitHub stars