Понимание юнит-тестирования - PullRequest
4 голосов
/ 28 июня 2011

Я пытаюсь понять, как работает модульное тестирование. Пока я понимаю, что вы тестируете вывод функций в зависимости от того, что вы вставили. Хорошо. Означает ли это, что если у вашей функции есть единственная возможность вернуть один тип данных, вам нужно написать только один тест для него? Так, скажем, я пишу функцию, которая может возвращать только TRUE или FALSE, означает ли это, что я просто проверю, является ли ответ логическим?

А потом также скажите, что у меня есть функция, которая извлекает сообщения из блога из базы данных. Скажем, функция имеет значение: если число строк = 0 возвращает FALSE, иначе возвращает результаты. Так что теперь у меня есть возможность функции, которая может возвращать логическое значение или массив. Как, черт возьми, вы это тестируете? Функция теперь не зависит исключительно от ввода, она зависит от того, что находится в базе данных.

Ответы [ 7 ]

9 голосов
/ 28 июня 2011

Полезная функция не возвращает true или false в случайном порядке.Он возвращает true при определенных обстоятельствах и false при других обстоятельствах .

Таким образом, модульный тест будет выполнять три вещи (в таком порядке):

  1. Создайте среду, из которой вы знаете, должна ли функция возвращать true или false (эта среда называется test fixture ).
  2. Запуститефункция, которая должна быть проверена.
  3. Сравните результат функции с вашими ожиданиями.

Очевидно, что это невозможно сделать со всеми возможными входами (если это можно было бы сделать, этобыть доказательством, а не тестом), поэтому искусство модульного тестирования заключается в выборе подходящих тестовых приборов.Есть два способа сделать это:

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

... если число строк = 0 возвращает FALSE, иначе возвращает результаты.

Если такая функция напрямую отправляет запрос на сервер базы данных, вызывая API СУБД (например, mysql_query), создание тестового устройства будет включать

  1. Настройка базы данных.
  2. Вставка строк в базу данных (или нет, в зависимости от того, должен ли тест проверять, правильно ли возвращены результаты или FALSE возвращается правильно).

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

5 голосов
/ 28 июня 2011

У вас есть суть этого права.Если для единицы есть внешние зависимости, есть два подхода.создание класса Mock или использование какого-либо приспособления.

Используя ваш пример БД, если вы тестируете класс, который должен вызывать класс доступа к данным для извлечения данных из базы данных, тогда вы обычно будете Mock для этого класса доступа к данным, чтобы методы, которые вы планируете вызывать из него, возвращалиответ вы ожидаете.

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

3 голосов
/ 28 июня 2011

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

Относительно вашего второго вопроса, где возвращаемое значение зависит от базы данных. Это строго не юнит-тест (то есть он включает в себя несколько юнитов). Я предлагаю вам потратить некоторое время на чтение о фиктивных объектах .

2 голосов
/ 28 июня 2011

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

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

Надеюсь, это поможет!

2 голосов
/ 28 июня 2011

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

Например, вы можете протестировать в случае, если ваша база данных пуста, содержит несколько строк или заполнена.

Затем для каждого состояния введите разные данные (пара недействительна, пара действительна).

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

EDIT:

В Википедии есть отличная статья о модульном тестировании .

1 голос
/ 05 июля 2011

Если вы позволите мне сделать предложение, возьмите эту книгу: Рой Ошерове: ИСКУССТВО ОБЪЕДИНЕНИЯ ИСПЫТАНИЙ .http://amzn.com/1933988274. Это не огромная книга, похожая на оружие.

Я никогда не читал ничего о UnitTesting до этой книги, но теперь очень ясно, как работает UnitTest.

Надеюсь, это поможет!

0 голосов
/ 28 июня 2011

Я должен отметить, что модульное тестирование - это не только то, что дают ваши функции; это также о том, как они мутируют / влияют на другие объекты. В некотором смысле они проверяют, какие сообщения передаются между объектами.

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