утверждение против выхода функции на его собственном модульном тесте? - PullRequest
2 голосов
/ 02 декабря 2009

Если этот заголовок не имеет смысла (что я ожидаю =)) вот что я спрашиваю:

У меня есть функция с именем ParseFile (). Он принимает строку в качестве параметра и DataTable в качестве возвращаемого значения.

Я хочу протестировать эту функцию. Это неправильно с моей стороны сначала кодировать функцию, запускать ее, принимать выходные данные, сериализовать их в XML, сохранять как ожидаемые выходные данные, а затем писать мой модульный тест для вызова функции и подтверждения этих десериализованных данных?

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

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

И, черт возьми, если то, что я говорю, все еще хорошая идея - как бы вы сделали этот истинный стиль TDD и написали тест сначала ? Без утомительной записи вызовов Assert () для каждого ожидаемого поля в файле? Я еще не совсем в режиме TDD 'mode' - но я пытаюсь туда попасть ... и в таких случаях я иногда задаюсь вопросом, как можно сначала написать тест для него, когда ожидаемый результат представляет собой набор данных для пример ...

Спасибо

Ответы [ 6 ]

4 голосов
/ 02 декабря 2009

Это не так, но это не TDD.

При этом я хотел бы предупредить вас об утверждении в строках XML: когда что-то идет не так, когда размер XML достаточно велик, вы заканчиваете тем, что сравниваете две строки XML вручную, ошибочно, визуально.

Был там, сделал это. Я помню, как находился в такой ситуации, копируя XML в два файла, изменяя его так, чтобы он содержал один атрибут в строке, и сравнивая два файла с diff. Я сказал, что в следующий раз попробую утвердить XML с помощью XPath и / или XQuery.

Кроме того, разве ваша функция не делает слишком много вещей: разбирает строку и , генерируя XML? Вы могли бы хотеть рассмотреть, чтобы отделить это.

Как бы вы сделали этот настоящий TDD? стиль и написать тест в первую очередь?

Если вы действительно хотите использовать TDD и оставить одну функцию, тогда вы можете начать с теста: как должен выглядеть вывод XML с пустой строкой? Это ваш первый тест. Как только это пройдет, перезапустите строку с простым элементом, напишите тест, сделайте его успешным и возьмите более сложную строку. Вспенить, промыть, повторить.

3 голосов
/ 02 декабря 2009

Я использовал подобные тесты в прошлом - они часто невероятно полезны.

Они совершенно не TDD. Я обнаружил, что пишу такой тест, когда у меня есть код, который лучше построен без TDD: Glue Code. Это особенно заметно при извлечении данных (иначе говоря: «Запросите базу данных для этих (существующих) данных, отформатируйте ее таким образом и отправьте ее клиенту».) для этого вида кода, если вы производите данный (большой) вывод для данного (большого) ввода. Превращение кода наизнанку для введения тестовых швов не стоит хлопот.

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

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

3 голосов
/ 02 декабря 2009

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

2 голосов
/ 02 декабря 2009

Обычно я стараюсь держаться подальше от функций тестирования, которые являются такими «широкими». Я предпочитаю тестировать более детальные функции. Я собираюсь предположить, что ваш метод ParseFile () использует несколько служебных методов, которые сами используют другие служебные методы. Это те методы, которые я пытаюсь проверить. Как правило, любой подобный ввод состоит из нескольких разных частей данных. Вместо того, чтобы пытаться проверить, правильно ли был проанализирован весь файл, вы можете просмотреть метод ParseFile () и анализируемые данные и разбить его на несколько меньших тестов, которые, будучи взятыми в их совокупности, дают вам такую ​​же уверенность?

Мое личное оправдание предпочтения такого подхода состоит в том, что если мне когда-либо понадобится изменить какой-либо из этого кода синтаксического анализа и тест не пройден, у меня будет гораздо более быстрый путь к поиску источника ошибки, чем «ParseFile () не возвращается ожидаемые результаты ". :)

2 голосов
/ 02 декабря 2009

Зависит от того, почему вы пишете тесты.

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

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

Как вы разбили такой метод?

Начните думать о том, как бы вы организовали это в частные вспомогательные методы. Затем подумайте о том, могут ли некоторые (или все) из этих вспомогательных методов быть представлены объектом самостоятельно. Шаблоны проектирования, такие как Стратегия и Абстрактная фабрика , могут быть чрезвычайно полезны в этом смысле.

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

1 голос
/ 02 декабря 2009

Вы не должны сравнивать сериализованную форму вашего объекта в качестве теста. Это слишком специфично для реализации. Вы должны только тестировать интерфейс.

Вам следует протестировать определенные свойства вашего объекта DataTable, например, чтобы он имел четыре строки, пять столбцов и чтобы в ячейке [1,2] содержалась строка «Рыба».

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