Какие режимы отказа могут оставить TDD?

Обратите внимание, что я еще не "видел свет" на TDD и не понял, почему у него есть все преимущества, благовествованные его основными сторонниками. Я не увольняю его - у меня просто есть оговорки, которые, вероятно, рождаются из-за невежества. Поэтому, во что бы то ни стало, смеяться над вопросами ниже, если вы можете исправить меня: -)

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

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

Другие неудачи, которые я могу себе представить, охватывают не-закрытие потоков, исключение объектов GDI + и т.п.

Является ли это даже проблемным доменом TDD, или если интеграция и системное тестирование ловят такие проблемы?

Спасибо в ожидании....

Ответ 1

Некоторые из них относятся к домену TDD.

Дэн Норт говорит, что нет такой вещи, как разработка, основанная на тестах; что то, что мы действительно делаем, - это примерная разработка, и примеры становятся регрессионными тестами только после того, как тестировалась система.

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

Что-то вроде закрытия потока может и должно быть полностью покрыто при использовании TDD.

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

Что я беру, во всяком случае; другие могут видеть это по-другому.

Ответ 2

TDD не является заменой умения. Лучшие программисты становятся еще лучше с TDD. Худшие программисты все еще ужасны.

Тот факт, что вы задаете эти вопросы, является хорошим знаком: это означает, что вы серьезно занимаетесь программированием.

Понятие "наименьшее количество код для удовлетворения теста" предлагает думая в самых суровых особая проблема без обязательно созерцая картина.

Легко принять такое отношение, так же как "Мне не нужно проверять это, я уверен, что он просто работает". Оба наивны.

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

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

Я думаю об объектах, которые зависят от государства.

как бы вы заметили, что метод оставил недействительным состояние?

Зависимости и состояние неприятны. Они делают для тонких ошибок, которые появляются в худшие времена. Они делают рефакторинг и будущее усиление труднее. И они делают модульное тестирование неосуществимым.

К счастью, TDD отлично помогает вам создавать код, который изолирует вашу логику от зависимостей и состояний. Это второй "D" в "TDD".

Ответ 3

Понятие "наименьшее количество код для удовлетворения теста" предлагает думая в самых суровых особая проблема без обязательно созерцая картина.

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

Да, TDD дает нам шторы. Но это нас не ослепляет.

Ответ 4

Хорошие вопросы. Здесь мои два цента, основанные на моем личном опыте:

Может ли использование TDD оставить открытым непреднамеренные побочные эффекты реализация?

Да, да. TDD не является "полноценным" вариантом. Он должен использоваться вместе с другими методами, и вы должны определенно иметь в виду большую картину (независимо от того, являетесь ли вы ею это или нет).

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

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

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

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

В любом случае хороший дизайн на уровне "tdd" не обязательно означает, что ваше программное обеспечение хорошо построено, вам нужно больше, поскольку дядя Боб хорошо объясняет здесь:

http://blog.objectmentor.com/articles/2007/10/17/tdd-with-acceptance-tests-and-unit-tests

Маркус Фаулер написал интересную статью о тестировании Mocks vs Stubs, в которой рассматриваются некоторые темы, о которых вы говорите:

http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting