Подтвердить что ты не робот

Ешьте, спящий и дышащий блок Тестирование/TDD/BDD

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

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

4b9b3361

Ответ 1

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

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

P.S. получить книгу Боба Чистый код:

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

Мой друг Тим Оттингер (бывший чувак-наставник Object Mentor) 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 Craftsmanship (в этом году они проводились одновременно в Чикаго).

Ответ 2

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

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

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

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

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

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

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

Считайте, что, может быть, это заставляет вас звучать как всасывание? Вы обнаружили, что ваше ворчание оттолкнуло остальных членов вашей команды?

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

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

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

Я бы также посоветовал Rob Conery TekPub screencast Behavior-driven Design with Specflow. Отличное введение в BDD и инструмент (SpecFlow) очень хорошо подходит для выполнения BDD на С#.

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

Ответ 8

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

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

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

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

Ответ 9

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

Ответ 10

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

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

  • посетите блоги и прочитайте упомянутые выше книги.
  • пара с кем-то, кто владеет TDD
  • практика

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

Ответ 11

Чтобы взять цитату из Nike: ТОЛЬКО ДЕЛАТЬ ЭТО.

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

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

YMMV.

Ответ 12

Год назад я понятия не имел, как делать TDD (но действительно хотел (как расстраивает)) и никогда не слышал о BDD... теперь я делаю оба навязчиво. Я был в среде разработки .NET, а не в Java, но я даже заменил кнопку "F5-Run" макросом для запуска Cucumber (BDD) или MBUnit (TDD) в зависимости от того, является ли это Feature/Scenario или Specification. Нет отладчика, если это вообще возможно. $1 в банке, если вы используете отладчик (JOKING (вроде)).

Процесс очень впечатляет. Рамка, которую мы дополнительно используем, - это Oracle, о которой я получил благословение, чтобы понять, и поглотить информацию, и те рамки, которые он/мы используем, - это MavenThought.

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

Характеристика:

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

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

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

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

Пример:

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

Существует еще одна спецификация (файл класса С# 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 должно быть таким же, как и инжектируемый диффузор. Мне пришлось использовать Concrete Diffuser вместо Mock, потому что в этом случае Diffuser является объектом Core/Domain и не имеет уведомления свойства для интерфейса. 95% времени мы ссылаемся на все наши зависимости, такие как Dep(), вместо того, чтобы вводить реальную вещь.

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

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

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

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

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 crappy с жесткими зависимостями и т.д., Вы почувствуете боль от попыток сделать TDD и накормить/бросить ИЛИ укусить пулю и сделать это правильно.

И вот настоящий SUT. Мы получили немного фантазии и используем PostSharp для добавления уведомления о свойствах, измененного на 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. Это заняло один год, но я превращаюсь в образ жизни как образ жизни. Я бы не узнал об этом сам. Я взял все из Oracle http://orthocoders.com/.

Красная или синяя пилюля, выбор за вами.