Модульное тестирование "Ешь, спи и дыши" /TDD/BDD [закрыто]

StackOverflow https://stackoverflow.com/questions/1616090

Вопрос

Я действительно пишу модульные тесты при написании API и основных функциональных возможностей.Но я хочу быть крутым фанатом, который ест, спит и дышит TDD и BDD.Каков наилучший способ правильно начать работу с TDD / BDD?Какие-нибудь книги, ресурсы, фреймворки, лучшие практики?

Моя среда - это серверная часть Java с интерфейсом Grails, интегрированная с несколькими внешними веб-сервисами и базами данных.

Это было полезно?

Решение

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

Мартин "Дядя Боб" и ребята из Object Mentor:http://blog.objectmentor.com/

P.S.получите Чистый код Bobs book:

http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

Мой друг Тим Оттингер (бывший объектный наставник) http://agileinaflash.blogspot.com/ http://agileotter.blogspot.com/

Ребята из Jetbrains:http://www.jbrains.ca/permalink/285

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

http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530

он также ведет блог по адресу:

http://www.threeriversinstitute.org/blog/?p=29

другие "известные" сторонники TDD включают:

Все они замечательные люди, за которыми стоит следить.Вам также следует подумать о посещении некоторых конференций, таких как Agile 2010 или Software Mastermanship (в этом году они проходили в одно и то же время в Чикаго).

Другие советы

Мне не нравится, когда люди говорят: "Практика X никогда не бывает плохой;если это не работает, вы делаете это неправильно ". Извините, это похоже на любую другую чрезмерно рьяную религиозную догму.Я на это не куплюсь.

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

Любой, кто возражает против TDD, не должен автоматически обвиняться в пренебрежении качеством.("Так когда же вы перестали избивать свою жену?") Дело в том, что в программном обеспечении есть ошибки, и стоимость устранения всех из них должна быть сопоставлена с выгодой.

То же самое справедливо и в производстве.Допуски по размерам и отделке поверхностей не у всех одинаковы, поскольку иногда строгий допуск и зеркальная отделка не гарантируются.

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

Но я бы косо посмотрел на любого товарища по команде, который начал бы доставать меня по поводу "модульного тестирования еды, сна и дыхания и TDD".

Мой менеджер говорит, что единственный способ добиться для меня повышения - это перевести команду на TDD / BDD.

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

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

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

Блин, в Grails встроена генерация тестов.Если вы работаете в команде, использующей Grails, насколько больше продаж необходимо?

Лучшая практика ИМХО: делайте то, что практично, а не только потому, что это процесс. Не забывайте, какова цель написания приложений, а в деловом мире это не написание тестов. Не поймите меня неправильно, у них есть свое место, но это не должно быть целью.

Найдите кого-нибудь, кто занимался TDD / BDD, и создайте пару программ с ними.

Метрики, имхо, лучший способ добраться отсюда туда. Следите за тем, насколько хорошо ваш код покрыт, сохраняйте дельты сложности кода для каждого коммита, используйте тест-бегуны, которые следят за вашим кодом на предмет изменений и постоянно перезапускают соответствующие тесты. Никогда не позволяйте длинам теста превышать несколько строк, чтобы все ваши инструменты работали хорошо. И я бы порекомендовал раз в месяц взять выходной, чтобы прогнать код через тестер мутаций. Этот день должен быть посвящен только написанию тестов. Все эти вещи принесут вам боль, если вы еще не делаете хороший TDD. Учитесь на боли, и совсем скоро вы все сделаете правильно.

И никогда не упускайте из виду то, для чего предназначены тесты: описывать желаемое поведение. Это ваша исполняемая спецификация. (Именно поэтому мне нравится огурец ; теперь вы можете попросить своего PHB написать свои тесты для вас! Ну, возможно, нет довольно хорошо, но это близко!)

" PS: мой менеджер говорит, что единственный способ получить мне повышение в должности - это получить команду в TDD / BDD. "

Единственный реалистичный способ заставить команду что-то сделать (не убивая вас в процессе) - это продемонстрировать им, что им будет полезно изменить свои привычки. Другими словами, напишите код. Много кода. Тонны кода. И затем, когда приходит критическое электронное письмо, которое радикально меняет спецификацию, покажите им, что вы можете легко изменить свой код с помощью рефакторинга, и что еще хуже, потому что вы были подготовлены к нему с вашими тестами на месте. Бар был зеленым, взломать взломать, RED BAR !!!!, взломать взломать взломать, зеленый бар, иди домой.

Прочитайте книгу Кента Бекса о тестовом дизайне. Начните с тестов, а затем сделайте код. Получите сервер сборки, который запускает тесты! Вам не нужно иметь это для всей команды - сделайте это для себя и ПОКАЖИТЕ им, что это помогает.

Проповедь раздражает только туземцев:)

Я занимаюсь TDD уже пару лет, но в последнее время я начал больше интересоваться BDD-способом управления своим дизайном и разработкой.Ресурсами, которые помогли мне начать работу с BDD, был блог Дэна Норта ("основателя" BDD).Взгляните на Представляем BDD.Есть также "официальная" BDD-вики по адресу behaviour-driven.org с каким-нибудь хорошим постом, который стоит прочитать.

Единственное, что мне было действительно сложно, когда я начинал работать с BDD (и до сих пор нахожу немного сложным), - это как сформулировать эти сценарии, чтобы сделать их подходящими для BDD.Скотт Беллвер - человек, хорошо разбирающийся в BDD (или Спецификации контекста, как он любит это называть) и его статье Развитие, основанное на поведении журнал in Code Magazine очень помог мне понять образ мышления BDD и сформулировать истории пользователей.

Я бы также порекомендовал скринкаст TekPub Проектирование, ориентированное на поведение, с помощью Specflow автор: Роб Конери.Отличное введение к BDD и инструменту (SpecFlow), очень хорошо подходящему для выполнения BDD на C #.

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

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

Вам также понадобится правильный процесс сборки - использование сервера сборки, который соберет ваш код и запустит тестирование. Я рекомендую использовать TeamCity (бесплатно с ограничениями).

Научиться правильно составлять хорошие модульные тесты - сложная часть - некоторые из них вы узнаете сами (до тех пор, пока вы продолжаете модульное тестирование), а остальное вы можете узнать из поиска в Интернете.

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

Помните, что Agile означает, что вы не полностью распроданы каким-либо конкретным методом. Если вы работаете над чем-то, в чем преимущества TDD не стоят (например, редактирование методом проб и ошибок в интерфейсе Swing), не используйте TDD.

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

Чтобы узнать его, я бы предложил (суммируя сказанное другими и добавив одно из моих):

<Ол>
  • посещайте блоги и читайте книги, упомянутые выше
  • соединитесь с кем-то, кто опытен в TDD
  • практика
  • Я практиковал ката Боулинг (упражнение) примерно 20 раз (примерно по 30 минут), прежде чем начал видеть свет. Начнем с анализа описания этого дяди Боба здесь . На сайте codingdojo.org есть множество катов, включая решения и обсуждения. Попробуйте их!

    Возьмем цитату из Nike:ПРОСТО СДЕЛАЙ ЭТО.

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

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

    ИММВ.

    Год назад я слабо представлял, как сделать TDD (но действительно хотел (как это неприятно)) и никогда не слышал о BDD...теперь я делаю и то, и другое навязчиво.Я был в ...Сетевая среда разработки, не Java, но я даже заменил кнопку "F5 - Run" макрокомандой для запуска Cucumber (BDD) или MbUnit (TDD) в зависимости от того, является ли это функцией / сценарием или Спецификацией.Никакого отладчика, если это вообще возможно.1 доллар в банке, если вы используете отладчик (ШУТКА (вроде как)).

    Этот процесс очень потрясающий.Фреймворк, который мы дополнительно используем, создан Оракулом, с которым мне посчастливилось столкнуться и от которого я получаю информацию, и этот фреймворк, который он / мы используем, является продуманным.

    Все начинается с BDD.Наш BDD - это настоящий огурец поверх железного рубина.

    Особенность:

    Сценарий:....Учитывая, что я занимаюсь ерундой...
    Когда я делаю что-то еще...Затем происходят удивительные вещи...

    Сценарий:...

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

    И TDD, который мы использовали, в некотором роде является разновидностью BDD, потому что мы смотрим на поведение, требуемое SUT (тестируемой системой), и одно поведение задается для каждой спецификации (файл класса "test").

    Пример:

    Вот спецификация для одного поведения:Когда тестируемая система будет создана.

    Существует еще одна спецификация (файл класса C # When_blah_happens) для другого поведения при изменении свойства, но она выделена в отдельный файл.

    using MavenThought.Commons.Testing;
    using SharpTestsEx;
    
    namespace Price.Displacement.Module.Designer.Tests.Model.Observers
    {
        /// <summary>
        /// Specification when diffuser observer is created
        /// </summary>
        [ConstructorSpecification]
        public class When_diffuser_observer_is_created
            : DiffuserObserverSpecification
        {
            /// <summary>
            /// Checks the diffuser injection
            /// </summary>
            [It]
            public void Should_return_the_injected_diffuser()
            {
                Sut.Diffuser.Should().Be.SameInstanceAs(this.ConcreteDiffuser);
            }
        }
    }
    

    Вероятно, это самое простое поведение для SUT, потому что в этом случае при его создании свойство Diffuser должно быть таким же, как у инжектируемого диффузора.Мне пришлось использовать конкретный диффузор вместо макета, потому что в этом случае диффузор является объектом ядра / Домена и не имеет уведомления о свойстве для интерфейса.в 95% случаев мы ссылаемся на все наши зависимости, такие как Dep(), вместо того, чтобы внедрять реальную вещь.

    Часто у нас есть более одной функции [It] Should_do_xyz(), и иногда требуется довольно много настроек, например, до 10 строк заглушки.Это всего лишь очень простой пример, в котором нет GivenThat() или AndGivenThatAfterCreated() в этой спецификации.

    Для настройки каждой спецификации нам обычно требуется переопределить только пару методов спецификации:

    GivenThat() ==> это происходит до создания SUT.

    CreatSut() ==> Мы автоматически создаем макет sut с помощью StructureMap, и в 90% случаев никогда не нужно переопределять это, но если вы конструктор, вводящий бетон, вы должны переопределить это.

    AndGivenThatAfterCreated() => это происходит после создания SUT.

    WhenIRun() => если это не [ConstructorSpecification], мы используем это для запуска ОДНОЙ строки кода, которая соответствует поведению, которое мы указываем для SUT

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

    Все, что мне нужно сделать, чтобы запустить спецификацию, это выделить ее имя, например "When_diffuser_observer_is_created" и нажать F5, потому что помните, для меня F5 запускает задачу Rake либо test:feature [tag], если Cucumber, либо test: class [SUT].Для меня это имеет смысл, потому что каждый раз, когда вы запускаете отладчик, это бесполезно, код не создается (о, и это стоит 1 доллар (шутка)).

    Это очень, очень чистый способ определения поведения с помощью TDD и имеющий действительно, действительно простые SUT и простые спецификации.Если вы попытаетесь быть ковбойским кодером и написать дерьмовый SUT с жесткими зависимостями и т.д., вы почувствуете боль от попыток сделать TDD и устанете / сдадитесь ИЛИ стиснете зубы и сделаете это правильно.

    А вот и сам SUT.Мы немного пофантазировали и использовали PostSharp для добавления измененного свойства notify в Diffuser, отсюда и Post.Cast<>.И опять же, именно поэтому я ввел Бетон, а не Макет.В любом случае, как вы можете видеть, отсутствующее поведение, определенное в другой спецификации, возникает, когда что-либо меняется в диффузоре.

    using System.ComponentModel;
    using MavenThought.Commons.Events;
    using PostSharp;
    using Price.Displacement.Core.Products;
    using Price.Displacement.Domain;
    
    namespace Price.Displacement.Desktop.Module.Designer.Model.Observers
    {
        /// <summary>
        /// Implementation of current observer for the selected product
        /// </summary>
        public class DiffuserObserver : AbstractNotifyPropertyChanged, IDiffuserObserver
        {
            /// <summary>
            /// gets the diffuser
            /// </summary>
            public IDiffuser Diffuser { get; private set; }
    
            /// <summary>
            /// Initialize with a diffuser
            /// </summary>
            /// <param name="diffuser">The diffuser to observe</param>
            public void Initialize(IDiffuser diffuser)
            {
                this.Diffuser = diffuser;
                this.NotifyInterface().PropertyChanged += (x, e) => this.OnPropertyChanged(e.PropertyName);
            }
    
            /// <summary>
            /// Gets the notify interface to use
            /// </summary>
            /// <returns>The instance of notify property changed interface</returns>
            protected INotifyPropertyChanged NotifyInterface()
            {
                return Post.Cast<Diffuser, INotifyPropertyChanged>((Diffuser)Diffuser);
            }
        }
    }
    

    В заключение, этот стиль разработки BDD / TDD потрясает.Это заняло один год, но я полностью перешел в новый образ жизни.Я бы не научился этому сам.Я все узнал от Оракула http://orthocoders.com/.

    Красная или синяя таблетка - выбор за вами.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top