2010-07-27 4 views
1

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

Как я могу использовать технику tdd в такой ситуации?

Я думаю, что проблема в том, что tdd (и в целом модульное тестирование) касается тестирования интерфейсов, а не реализаций. Я прав? Как я могу справиться с этим?

Если вы знаете какую-либо технику для обработки этих случаев, пожалуйста, сообщите мне об этом.

Благодарим за помощь.

ответ

6

Вы правы, что TDD - это тестирование интерфейсов, а не реализация. Сказали, почему вы хотите проверить фактическую реализацию? Дело в том, что если вы достаточно проверите интерфейс, реализация не имеет значения.

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

+0

Если я тестирую только интерфейс в этом случае, у меня нет никакой помощи в создании моего класса и написании моих методов. На практике я свожу на нет преимущества tdd. Вам не кажется? – TheSENDER

+0

Ничто не мешает вам писать тесты для внутренних методов реализации, таких как 'merge()' или 'resizeArray()', но просто имейте в виду, что когда вы это делаете, вы делаете свои тесты более хрупкими. –

+0

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

0

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

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

+0

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

+0

@WW: Это определенно вариант рассмотрения. Мое мнение состоит в том, что это зависит от того, насколько вы повторно используете новый метод. Если он может быть полезен в другом месте, сделайте его общедоступным в другом классе. Если нет, сделайте его приватным. Поскольку первый инстинкт плаката заключался в том, чтобы написать один длинный метод, я предполагал, что он не будет иметь большого значения в другом месте. Однако я согласен, что это необходимо переоценить при реорганизации. – dbyrne

0

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

Я нашел этот щебет разговор очень проницательный: http://twitoaster.com/kentbeck/brunopedroso-i-think-you-could-tdd-quicksort-youd-need-assertions-about-the-of-comparisons-ways-to-incrementally-improve-the-count/

Это говорит об этой идее: TDDing быстрого вида. Мы знаем, что quicksort быстрее, чем сортировка пузырьков. Оба алгоритма будут давать один и тот же результат (сортированный набор), но они имеют разные ограничения.

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

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

+0

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

+0

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

+0

Мертвая ссылка сейчас. Я нахожусь на своем телефоне, или я бы это исправил :) –

0

Я нашел пример TDD/BDD в RSpec книге очень полезный - http://www.pragprog.com/titles/achbd/the-rspec-book это может быть некоторые ориентированные на рельсы, но в книге автор переходит от определения проблемы, к определению простых тестовых случаев для сложных случаев в интуитивном манера. Пример в этой книге - это разработка игры и ее прогресс в направлении прохождения всех тестов.

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

2

Если ваша реализация сложна, тогда было бы неплохо разбить ее на более мелкие модули. Эти меньшие модули будут иметь свой собственный интерфейс, который вы будете тестировать на единицу. Например, если вы решаете Судоку, выполняя поиск по глубине, тогда он заплатит за разработку отдельно алгоритма поиска по глубине и алгоритма нумерации положения Судоку. Я писал об этом некоторое время назад: http://matteo.vaccari.name/blog/archives/416

Смежные вопросы