TDD: пригодность теста - PullRequest
       10

TDD: пригодность теста

2 голосов
/ 25 апреля 2019

Я начинаю с TDD и JUnit. После проверки руководств и документов у меня возникнут вопросы, и я был бы рад, если бы получил отзыв о наилучшей практике.

A) Все примеры, которые я видел, относятся к методам, которые имеют своего рода семантику / логику.

вход -> логика -> выход

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

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

Что делать, если такого ввода нет (или существует большая зависимость от внешних результатов)?

, например

String getName (int id)
{
  // read the name of a staffmember out of the DB and return it
} 

Я не вижу реальной логики, которую можно было бы проверить независимо от контекста во время компиляции / развертывания.

Какое утверждение имело бы смысл или это образец, где ни один тест не был бы справедливым?

Я думаю, что только тесты для контекстно-независимого ввода будут иметь смысл. Внешняя база данных или результат веб-запроса таковы (я думаю - вы согласны?).

B) Как вы думаете, каково соотношение "методов существуют" к "методам с тестовым набором"? Конечно, это зависит от проекта или темы, но меня могут заинтересовать некоторые цифры.

Ответы [ 3 ]

3 голосов
/ 25 апреля 2019

Как указал де Хаар в своем комментарии, есть много крайних случаев, которые вы хотите охватить. При тестировании БД можно сделать следующее:

  • Вы издеваетесь над Базой данных (в проекте Spring вашего хранилища) и настраиваете ее на возврат / выброс. Затем в своем тесте вы тестируете такие вещи, как: givenNoCustomerInDB_thenNotFoundExceptionThrownIsWrappedToXXX(). Здесь вы должны проверить, что метод службы, который вызывает БД, перехватывает исключение и соответствующим образом переносит его. Для этого подхода вы можете обратиться к Mockito, «де-факто» фреймворку для Java.
  • Другим вариантом является наличие базы данных в памяти (например, H2), которая используется при выполнении тестов.

Следует помнить одну вещь: вы несете ответственность за то, чтобы макеты (или H2) вели себя как ваша настоящая БД. @Kraylog предлагает интеграционные тесты для записи адаптеров на устройства ввода-вывода и контрактные тесты для проверки того, что макет ведет себя одинаково.

2 голосов
/ 25 апреля 2019

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

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

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

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

1 голос
/ 25 апреля 2019

В тесте, который изолирует испытуемого от его обычной среды, вы часто будете видеть шаблон input -> logic -> output, поскольку входные данные должны быть предоставлены средой, а тест равен среда, которую испытывает субъект.

TDD очень часто использует изолированные тесты; они, как правило, бывают как быстрыми, так и смущающими параллелями, что означает, что запуск их на этапе проектирования имеет низкую альтернативную стоимость.

String getName (int id)
{
    // read the name of a staffmember out of the DB and return it
} 

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

// Copy input to database
// connect test subject to database
// invoke query, thereby retrieving the output

Это один и тот же шаблон, просто вырезанный по-разному.

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

Такая вещь иногда называется двойной тест .

// Use the input to initialize the test double
// connect test subject to test double
// invoke query, thereby retrieving the output

Снова появляется та же картина, детали "логики" несколько меняются.

logic из input -> logic -> output не обязательно ваш производственный код. Обычно пишут тесты, которые интегрируются с фасадом, который координирует протокол взаимодействия между испытуемым и его (удвоенными) зависимостями.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...