|
|
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
У меня два фундаментальных вопроса, поэтому вопрос как бы из двух частей. Допустим у нас есть интерфейс, для примера возьмём один метод Код: java 1. 2. 3. 4. 5. как пишут очень вумные дядьки в книжках, для написания кода этого метода нужны приблизительно следующие методы в тесте Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Действия веду в правильном направлении??? Нужно ли писать два метода: который добавляет один элемент и два или более? Или же можно сразу написать метод который добавляет несколько элементов и проверить корректность? Лучше сразу описывать все возможные варианты поведения для метода, или например сначала протестировать основные, а потом(после основных тестов) всякие исключения и прочие отклонения от нормы? Ну и вторая часть: Этот мой класс при работе использует некий другой объект. И для проверки правильности отработки метода, приходиться писать вот такую шнягу Код: java 1. Хотел использовать моки, но не смог понять как проверять такого рода вещи. Например добавление одной ячейки в строку выглядит вот так Код: java 1. 2. 3. 4. 5. 6. и как проверить что метод сделал что должен, я просто не понимаю. пока не придумал как иначе, приходится делать вот так Код: java 1. но это же ппц :( ----- Если дела идут плохо, есть вероятность, что в ближайшее время они пойдут ещё хуже.(с)Мерфи ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2015, 21:33 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
Надо написать несколько отдельных тестов: 1. тест на Cell о том, что Label в этот Cell добавляется 2. тест на Row о том, что Cell в этот Row добавляется 2. тест на Table о том, что Row в этот Table добавляется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 14:36 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
DDiver, я просто скажу несколько ИМХ. Одна имха. Ты немножко зашёл далеко. Тест на интерфейс это ближе к контракту. Вообще в твоём случае глядя на интерфейс TableBuilder совершенно невозможно придумать его поведение. Как он должен добавлять RowItem. А должен ли вообще? Может он его фильтрует? Вобщем непонятно. Вторая имха. Тест должен исходить из того что затраты на сам тест будут хотя-бы не более чем 20% от затрат на кодинг самог вычислительно блока. Ну где-то как 80:20. Закон Парето вобщем-то. В твоём случае получается где-то 55:45 вобщем полная лажа. При таком подходе вероятность "запороть бок" в тесте практически такая-же как и в коде. Тоесть твой тест в свою очередь тоже надо покрыть тестом который надо покрыть тестом.... и так далее. Вобщем тестить надо ПРОСТЫМ образом СЛОЖНЫЕ чёрные ящики. Усёк? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 19:08 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
mayton Вторая имха. .... Ну IMHO оно и на то и IMHO... Но я очень давно слышал кардинально другую точку зрения ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 19:16 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
Давай и другую точку зрения заслушаем. Чего уж тут елейничать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 19:22 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
mayton, По поводу первого ИМХА, это просто кусок интерфейса, тестирую я конечно же конкретную имплиментацию. Там методов больше и из-за этого более понятно что и для чего. По второму, если я правильно понимаю, то сама метода ТДД используется для разработки классов любой сложности, а не только чёрных ящиков. Проблема в тестировании только из-за того, что мой класс использует для работы сторонний класс, который скажем так не очень testable. Так же скорее всего тут так же сыграло не в мою пользу моя собственная неопытность, возможно можно было как-то иначе всё выстроить. Для понимания, класс скрывает низкоуровневую работу с GUI элементом Grid, и позволяет просто и лаконично отрисовыать таблицу с шапкой любой сложности (это чисто для моих внутренних нужд) Используя такой подход, я смог ни разу не запустив GUI написать этот класс, который с первого же раза заработал как нужно и без ошибок. Т.е. время на отлов ошибок в GUI я потратил на написание тестов. Ещё один плюс, что я теперь спокойно могу что-то менять и рефакторить в классе, и после тестов быть полностью уверенным что всё работает и я ничего не сломал правками. Честно сказать, писать тяжко, т.к. постоянно хочется что-то сразу реализовать с заделом на будущее, но по идеологии TDD нужно писать минимум, а потом уже рефакторить. Неужели никто не использует такой подход? Или все пишут код, а потом уже какие-то тесты на него? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 21:24 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
Ну я активно использую ТДД :-) Правда, я склоняюсь больше к стилю BDD, так что буду писать со своей колокольни. Все ниженаписанное относится именно к юнит-тестам, интеграционные и приемочные оставим в стороне. Итак, исходя из примерно 10-летнего опыта коммерческой разработки на Java... Общие соображения: 1. Тестировать имеет смысл в основном небольшие черные ящики. Если для теста требуется мок (или, еще хуже, несколько моков) - это либо ошибка дизайна, либо вы пытаетесь тестировать не логику, а glue код (который связывает между собой уже протестированные блоки. Обоснование: Тесты имеет писать для кода, в котором высока вероятность ошибок и понятно поведение. Также тесты с моками хрупки и часто ломаются, т.к. зависят от большого кол-ва интерфейсов, а то и от реализаций. 2. 100% покрытие юнит-тестами - миф. После выполнения предыдущего пункта, стоимость (сложность написания и время, потраченное на исправление упавших тестов после доработок) юнит-тестов растет экспоненциально и они себя не окупают. 3. "Написание юнит-тестов улучшает структуру программы". Это верно, но верно без фанатизма. Структуру программы улучшают изолированные черные ящики со специфицированным входом и выходом. Также структуру программы улучшают маленькие методы, маленькие классы, минимум состояния в этих классах и разделение ответственности. Но если переборщить - то получается код, где всё построено на фабриках и интерфейсах (это придется делать, чтобы мОчить разные куски кода) . Его очень сложно понимать и поддерживать. По первому примеру: Сначала нужно сформулировать в голове требования к классу, который вы собираетесь писать. Потом изложить эти требования в коде. Потом писать реализацию. Кол-во и качество нужных требований (тестов) определяет программист, исходя из их важности и рисков. Чем важнее требование и чем больше шанс, что на этом месте может быть баг - тем более приоритетен этот тест. В примере с двумя элементами - если есть сомнения, что с одним элементом код будет вести себя не так, как с двумя, или вариант с одним элементом значительно проще для отладки - то да, нужно написать тест с одним элементом. По второму примеру: Этот API категории "сопля" выглядит ужасно. Я не совсем понимаю, как оно работает, но почему бы не сделать вот так: Код: java 1. Если с API совсем-совсем ничего сделать нельзя, то я бы написал тест так: Код: java 1. 2. 3. 4. 5. 6. 7. Или вообще придумал приспособление, которое проверяет всё дерево заголовков одним махом. Еще умеет смысл глянуть вот сюда: https://code.google.com/p/spock/ (для интернационалистов) http://habrahabr.ru/post/137561/ (для патриотов) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2015, 21:55 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
Спасибо за развернутый ответ. С тестирование изолированных классов и поджиков всё понятно, но такое возможно только если всё пишешь сам. Но мы же знаем, что в реальности без сторонних библиотек и фрейморков, это мазохизм. Вот тут и появляется нужда в тестах с моками и прочими извращениями. Например есть у нас некая библиотека, со страшно корявым и не выразительным API (но по каким-то причинам нужна именно она). Логично будет написать свой класс с нормальным API, который будет скрывать всю корявость и прочие потроха библиотеки. Разработчик либы уже протестил свой код, а нам же нужно проверить, что мы его корректно вызываем. Но из-за корявости API просто замокать методы библиотечного класса не получиться, т.к. это жуткий overhead. Приходится использовать реальный класс из библиотеки и проверять результат работы нашего класса, дёргая методы этой библии и проверяя её внутреннее состояние, точно зная что мы должны получить при тех или иных манипуляциях. С помощью какого ещё подхода можно такое проверить? Это как мне кажется уже не совсем юнит тестирование, тут наверное ближе к интеграционному. Где можно почитать об этом, учитывая специфику solo developer, т.е. когда ты сам себе и чтец, и жнец и на дуду игрец. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 09:53 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
DDiver, Обертка вокруг существующей библиотеки - это и есть glue-код. Чего там можно протестировать? Что параметры были переданы в нужном порядке? Не уверен, что это достаточный повод писать юнит-тест. Если же в обертке есть сложный код, то его нужно изолировать и тестировать именно его. Я бы ограничился парой интеграционных тестов, проверяющих, что обертка "в целом работает". Хороших книг по TDD/BDD не знаю. Видел книги из серии "объясняю, что это такое", а дальше - только личный опыт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 10:23 |
|
||
|
Помогите танкисту с TDD
|
|||
|---|---|---|---|
|
#18+
scfТесты имеет писать для кода, в котором высока вероятность ошибок и понятно поведение полностью согласен. и не могу придумать иные случаи, когда они нужны ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2015, 09:53 |
|
||
|
|

start [/forum/topic.php?fid=59&gotonew=1&tid=2125182]: |
0ms |
get settings: |
6ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
57ms |
get topic data: |
8ms |
get first new msg: |
5ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 221ms |
| total: | 367ms |

| 0 / 0 |
