На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (6) « Первая ... 4 5 [6]  все  ( Перейти к последнему сообщению )  
> TDD vs не TDD
    Цитата Fester @
    Функция, которая ничего не делает - это заглушка, т.е. фактически это и есть mock.

    Нет.

    Цитата Fester @
    Я уж как-нибудь обойдуть одним объектом, который полностью описывает "пользователя" и не буду убиваться из-за некоторой избыточности

    Любитель сильной связности. Понятно.

    Цитата Fester @
    В подавляющем случае как раз нет и в 99% случаев функция не использует все поля.

    Только в говнокоде.

    Цитата Fester @
    Просто из-за того, что никто не будет шлепать отдельный объект ради каждой функции.

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

    Цитата Fester @
    В данном тесте - последний параметр - это заглушка и, соответственно Request - это мок-объект.

    Нет. Request даже не объект.
      Вопрос к практикам. Вот начинаем мы какую-то новую штуку кодить по TDD. Мы начинаем же с самых высокоуровневых задач? Т.е. сначала пишем тест на высокоуровневую задачу, верно? Потом, при развитии, проверяемая такими тестами функциональность в любом случае будет раскидана по нескольким юнитам. Так вот вопрос, эти более ранние тесты становятся интеграционными? Ведь у каждого юнита появится свой тест.
      Сообщение отредактировано: D_KEY -
        Цитата D_KEY @
        Так вот вопрос, эти более ранние тесты становятся интеграционными? Ведь у каждого юнита появится свой тест.

        Не обязательно, зависит от архитектуры. У тебя же высокоуровневая задача является некоторой композицией низкоуровневых, вот смотри, в моём примере, я переделал высокоуровневый сервис (относительно Accounts, Transactions, Compliance, Notifier) Transfer, чтобы он не включал зависимости внутрь себя, т.е. вместо
        ExpandedWrap disabled
          Transfer
            + Accounts
            + Transactions
            ...

        получилось
        ExpandedWrap disabled
          Composer
            + Transfer
            + Accounts
            + Transactions
            ...

        где Transfer хоть и реализует высокоуровневую логику посредством остальных компонентов, но расположен на том же (структурном?) уровне фактически.
        Composer в свою очередь может быть абстрактным и тривиальным и иметь свои юнит-тесты. Естественно, можно сделать и интеграционные тесты (они ж не взаимозаменяемы с юнит-тестами), а на самом-самом верхнем уровне ещё добавить функциональные/end-to-end/системные тесты.

        Добавлено
        Ну, собственно, если у тебя правильная инверсия зависимостей, то высокоуровневый модуль полностью независим от низкоуровневых и ты можешь писать нормальные юнит-тесты для него )
        Сообщение отредактировано: korvin -
          Цитата korvin @
          Ну, собственно, если у тебя правильная инверсия зависимостей, то высокоуровневый модуль полностью независим от низкоуровневых и ты можешь писать нормальные юнит-тесты для него )

          Это да. Но вопрос изначальных тестов. Они же исходят из высокоуровневых задач и будут проверять работу целиком. Соответственно, они должны будут или перейти на уровень интеграционных или, став юнит-тестами для самих высокоуровневых юнитов, перестанут проверять высокоуровневые задачи.
            Цитата D_KEY @
            Но вопрос изначальных тестов. Они же исходят из высокоуровневых задач и будут проверять работу целиком

            Э, ты путаешь тёплое с мягким, тип проверки зависит от типа теста и не зависит от уровня тестируемого компонента в системе. Работу целиком проверяют end-to-end и системные тесты. Как только ты принял решение выделить из высокоуровневого модуля под-модуль, сначала ты должен поменять тесты соответствующим образом, в этом же суть TDD: любое изменение начинается с тестов, т.е. сначала нужно убедиться, меняется ли архитектура/требование, потом отразить изменения в тестах, если нужно и только потом — в реализации.

            Тут всё зависит от того, выносишь ты субкомпонент как внешнюю зависимость или оставляешь его деталью внутренней реализации суперкомпонента:

            – если ты делаешь инверсию зависимости для этого субкомпонента, то твой изначальный тест суперкомпонента нужно разбить на два:
            1) юнит-тест, который будет мокать/стабать интерфейс зависимости и проверять корректность входа/выхода суперкомпонента
            2) интеграционный, который также будет мокать/стабать интерфейс зависимости, но проверять само взаимодействие, т.е. например, убеждаться, что суперкомпонент при каком-то входе вызывает метод интерфейса зависимости, нужное количество раз с правильными параметрами

            - если ты не делаешь инвресию зависимости, просто выносишь часть кода суперкомпонента в субкомпонент и используешь последний как некую библиотеку, то объект субкомпонента будет инстанциироваться внутри суперкомпонента (если это не так и ты передаёшь экземпляр субкопонента в публичный конструктор супера, то это уже внешняя зависимость и тебе лучше сделать полноценную инверсию и перейти к первому случаю) и ни мокать, ни стабать ты его не можешь и не должен, он всё также остаётся деталью внутренней реализации и изначальный тест у тебя не меняется.
              Цитата korvin @
              если ты делаешь инверсию зависимости для этого субкомпонента, то твой изначальный тест суперкомпонента нужно разбить на два:
              1) юнит-тест, который будет мокать/стабать интерфейс зависимости и проверять корректность входа/выхода суперкомпонента
              2) интеграционный, который также будет мокать/стабать интерфейс зависимости, но проверять само взаимодействие, т.е. например, убеждаться, что суперкомпонент при каком-то входе вызывает метод интерфейса зависимости, нужное количество раз с правильными параметрами

              Во, кажется это ответ на мой вопрос :)
              Осталось понять, как правильно писать интеграционные тесты в C++ :D
              А то я так понимаю теперь, что у меня всегда были юнит-тесты, которые пишут разрабы, и системные, которые пишут qa.
                Кстати, возможно, в интеграционном тесте лучше не мокать субкомпонент, или добавить к мокнуты ещё тесты с использованием реального инстанса субкомпонента, иначе некоторые изменения не отловятся тестами
                  Цитата applegame @
                  По мне так декларативный код - утопия.
                  Вот погоди, нейронки выйдут из эмбрионального состояния, и всякоразные Плюсы с Питонами уйдут в нишу автокода.

                  Добавлено
                  Цитата Fester @
                  Вводится дополнительный класс с дополнительной логикой.
                  ...
                  Не мути воду. Ты не такую задачу поставил. В том виде. как ты её поставил:
                  Цитата Fester @
                  Ну вот представим, что у тебя есть 2 компоненты: калькулятор и логгер. Все действия калькулятора должны быть запротоколированы. Как должен выглядить идеальный юнит-тест суммы?
                  подход Wound не просто правилен, он единственно праведно верный. Ты же сейчас путём волшебных ментальных манипуляций придумал новую задачу: придумать реализующую исходную задачу архитектуру, которую было бы удобно тестить.

                  Добавлено
                  P.S. Прочитал пока только половину темы.
                    Цитата Qraizer @
                    подход Wound не просто правилен, он единственно праведно верный.

                    Это чистой воды Aspect, вряд ли он это мог предложить,
                    так что подходов уже как минимум два ;) а подход назывется no coupling
                    или по народному private responsibility или has a, предложил его кажется кто то из Борланда году
                    в 1993-1994, ох как Я люблю так много умных слов ;)

                    Добавлено
                    Цитата D_KEY @
                    Осталось понять, как правильно писать интеграционные тесты в C++ :D

                    Включать здравый смысл, и перестать разводить не нужные теории ;)
                    Сообщение отредактировано: sergioK -
                      Цитата Qraizer @
                      Вот погоди, нейронки выйдут из эмбрионального состояния, и всякоразные Плюсы с Питонами уйдут в нишу автокода.
                      И долго еще осталось погождать? :)
                        Цитата applegame @
                        Ну да. Я не против автоматического тестирования вообще, я скорее разочарован в TDD, никак не помогает в конечном итоге, скорее мешает. Особенно если проект не очень крупный.
                        И ещё особенней, если очень крупный. Оракл вон наособничался, когда читал, волосы даже в интимных местах шевелились.

                        Добавлено
                        Цитата Wound @
                        Вот есть скажем требование что размер формы должен быть 100x200, вполне себе нормальный сценарий, который тоже можно протестировать. Или скажем "в случае неудачного соединения N-раз должно выскакивать окно - "Подключение невозможно, проверьте параметры сети", которое должно располагаться по центру экрана". Вполне себе нормальный сценарий, который тоже можно протестировать. Ага?
                        Всё просто: тестировать надо всё, что написано в спецификациях. Ничего там не заявленного, тестировать не надо.

                        Добавлено
                        Цитата D_KEY @
                        Вот начинаем мы какую-то новую штуку кодить по TDD. Мы начинаем же с самых высокоуровневых задач? Т.е. сначала пишем тест на высокоуровневую задачу, верно? Потом, при развитии, проверяемая такими тестами функциональность в любом случае будет раскидана по нескольким юнитам. Так вот вопрос, эти более ранние тесты становятся интеграционными? Ведь у каждого юнита появится свой тест.
                        Хороший вопрос. Готовый функционал лучше всего покрывается тестами снизу вверх. Пишешь юниты на каждый чих, интеграцией проверяешь их ...э-э-э, интеграцию. Разработка обычно идёт так же, а вот проектирование в обратном направлении. Я лично слабо себе представляю создание тестов без проверки их на реализованном поведении, т.к. при наличии фейла и следовательно для выявления его причины легче разобраться в чёткой логике, описанной формальным языком с формальной грамматикой, чем в его формальном описании на нечётком человеческом с множеством потенциальных неточностей, неоднозначностей и недосказанностей и местами противоречий, что не были замечены на извиняюсь спринтах.

                        Добавлено
                        Цитата applegame @
                        И долго еще осталось погождать?
                        Я чего ты ждёшь-то собсвтенно? Итогов по их спору, что ли?
                        По Wound-у требуется один юнит на интерфейс калькулятора, ещё один на интерфейс логгера и отдельный интегрант на их композицию. Этого достаточно на все случаи жизни. Вообще все. Пока не изменятся спецификации интерфейсов, конечно. Сколько ты не будешь мутить их комбинаций, эти три теста всегда будут к ним применимы, и всегда будут адекватны. Любая отдельная реализация обязана будет проходить эти тесты, без вариантов. Откуда у Fester там взялся зоопарк, я не имею ни малейшего понятия. Понятно, что отдельные реализации каждого из этих интерфейсов могут захотеть по-разному его расширить, и тогда на каждое такое расширение потребуется отдельный юнит, дополняющий, но не заменяющий, обобщённый юнит этого интерфейса. В итоге имеем: один общий юнит на каждый интерфейс, опциональный дополняющий его один частный юнит на каждую его реализацию и один интегрант на их композицию. Всё.
                        Проблема лишь в том, что реализации пасскритериев (именно реализации пасскритериев, а не собственно пасскритерии) для каждой частной реализации общего интерфейса могут отличаться в связи с тесной связью с этой самой реализацией, что затруднит создание обобщённых юнитов. Но это же не проблема, ведь, так? Мы тут прогаммеры или куда?
                        Сообщение отредактировано: Qraizer -
                          Цитата Qraizer @
                          Я лично слабо себе представляю создание тестов без проверки их на реализованном поведении, т.к. при наличии фейла и следовательно для выявления его причины легче разобраться в чёткой логике, описанной формальным языком с формальной грамматикой, чем в его формальном описании на нечётком человеческом с множеством потенциальных неточностей, неоднозначностей и недосказанностей и местами противоречий, что не были замечены на извиняюсь спринтах.

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

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

                          Мы, кстати, на работе сейчас пробуем BDD подход, к user story сразу пишем BDD-сценарии, которые потом используем в автотестах для стори. Вроде хорошо пошло. Это так же помогает и в процессе PBR (на грумингах и не только).
                          Попробуем несколько спринтов, потом решим, будет ли с этим жить.
                          Сообщение отредактировано: D_KEY -
                            Цитата Qraizer @
                            Я чего ты ждёшь-то собсвтенно?
                            Я жду когда
                            Цитата Qraizer @
                            нейронки выйдут из эмбрионального состояния, и всякоразные Плюсы с Питонами уйдут в нишу автокода.
                            Ты же сказал "погоди", вот я и спрашиваю долго ли еще погоджать?
                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0486 ]   [ 15 queries used ]   [ Generated: 28.03.24, 09:35 GMT ]