2013-04-16 3 views
26

Для текущих проектов и улучшения нашего процесса разработки мы рассмотрели вопрос о принятии TDD в качестве философии развития. Изучая лучшие практики и как «продавать» новый подход к моим коллегам/разработчикам, я столкнулся с BDD и нашел его еще более подходящим для того, что нам нужно, и каким-то образом стать следующей итерацией TDD. Проблема в том, что до сих пор я пробовал только tool, разработанный Dan North, JBehave, и я не могу сказать, что я поражен.Разработка поведения для Java - какие рамки использовать?

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

Q: Есть ли подходящие инструменты для использования BDD?
Q: Вы использовали бы вместо этого spock и справляетесь с накладными расходами на введение другого языка?

+1

Hi Olimpiu, есть [различные ароматы BDD] (https://stackoverflow.com/questions/3359327/atdd-versus-bdd-and-the-proper-use-of-a-framework/26524511#26524511). Было бы также полезно включить в него также нетехнических заинтересованных сторон? Если да, то как насчет использования таких инструментов, как [FitNesse] (http://fitnesse.org/) или [Concordion] (http://concordion.org/)? – user3632158

+0

@ user3632158 - да, было бы высоко оценено включение также нетехнических заинтересованных сторон. Вы экспериментировали в этом направлении? –

+0

мы используем [Concordion] (http://concordion.org) в нашей команде. нетехнические специалисты по бизнесу пишут спецификации со свободным редактором html WYSIWYG (http://www.microsoft.com/en-us/download/details.aspx?id=36179). технические характеристики затем устанавливаются разработчиками для создания автоматических приемочных испытаний. – user3632158

ответ

33

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

@Test 
public void should_do_something() { 
    // given 
    Something something = getSomething(); 

    // when 
    something.doSomething(); 
    // then 
    assertSomething(); 

    // when 
    something.doSomethingElse(); 
    // then 
    assertSomethingElse(); 
} 

Мое мнение на вышеуказанных структур:

  • Проблема JBehave в том, что тесты выглядят как сложный космический корабль. С другой стороны, он имеет довольно высокую производительность для ваших спецификаций.

  • spock действительно круто. Компактный синтаксис, неплохой вывод, множество функций, написанных мощным звуковым языком, что означает возможность использования в сочетании с geb. BUT это отличный, и для кого-то это может быть очень важно.

  • scalatest (написанный с помощью scala) и easyb (написанный с groovy) оба имеют тот же недостаток, что и спок. Значения «... должны ...» и «Дано ... Затем». Спецификации находятся в файлах .story, а реализации шагов - в классах Java. Этот подход очень хорошо работает как инструмент совместной работы и коммуникации для определения спецификаций, но, как правило, слишком много накладных расходов для низкоуровневого кодирования.

Я также считаю, что наиболее успешные структуры BDD для Java являются те, которые не написаны на Java, так как язык Java не имеет такой гибкости для DSL (Domain Specific Language) создание, что Groovy или Scala имеет.

+0

Спасибо, хороший обзор. –

+10

мнение одного человека. У меня были фантастические впечатления от спока. Нет проблем с тестированием Java-кода, а groovy невероятно просто для программиста Java. Вы можете начать писать регулярную Java и продолжать работать, а затем постепенно применять более тонкий стиль, когда будете изучать Groovy, если хотите. Я скептически относился к Groovy, но спок - это такая радость, что он больше, чем возлагает минимальные усилия на изучение немного Groovy. –

12

Если ваш владелец продукта/qa/клиент не имеет возможности прочесть тесты, используйте Spock. Это очень простой инструмент, но улучшает читаемость тестов. Благодаря мощным функциям вам не нужны Mockito, Hamcrest и AssertJ. И он имеет превосходные параметризованные тесты. Фактически, это «просто» лучший JUnit - общий инструмент для автоматического выполнения простых задач, будь то модульные тесты, интеграционные тесты или приемочные тесты.

Опасаясь Groovy? Зачем? Он очень похож на java. Чем больше вы его узнаете, тем более выразительным и короче ваш код. Ваши тесты будут короче и читабельнее. Groovy - это лекарство шлюза к лучшей стороне JVM.

Не нравится динамические языки? Ну, это тесты, а тесты выполняются сервером CI после каждый фиксатор, правильно? Если ваш код сломается, вы узнаете его через несколько минут. У вас нет сервера CI или не выполняются тесты? Тогда не беспокойтесь при выборе тестовой среды и исправьте свой процесс. Сломанные тесты бесполезны, и если вы не будете регулярно запускать тесты, они скоро прервутся.

Пойдите с JBehave/Cucumber, если вам это нужно; В противном случае используйте Spock.

14

Как автор JGiven Я должен не согласиться с тем, что Java не обладает достаточной гибкостью для создания DSL. В JGiven, BDD тесты выглядит следующим образом:

@Test 
public void users_can_login { 
    given() 
     .a_registered_user() 
     .and().the_login_page_is_shown(); 

    when() 
     .the_user_enters_correct_credentials() 
     .and().the_login_button_is_pressed(); 

    then() 
     .the_welcome_page_is_shown(); 
} 

JGiven используется вместе с JUnit или TestNG, и вы пишете тесты на простом Java.

+2

Я должен не согласиться с Тобой, мой друг. То, что вы представили, не имеет ничего общего с DSL. Это своего рода свободный API для Java (основанный на статических методах), но IMHO не очень читабельна и непригодна для использования. –

+1

Хорошо, тогда, пожалуйста, объясните мне разницу с Groovy DSL. Кстати, здесь нет статического метода, это все методы экземпляров. Кроме того, пример, который я показал, намного сложнее, чем приведенный выше пример. Однако, независимо от того, является ли он пригодным для использования или нет, все должны решить для себя. JGiven предоставляет вам инструмент, который намного проще в использовании, чем Cucumber или JBehave, и по-прежнему предоставляет отчеты о сценариях, которые читаются владельцами бизнеса. –

+0

Мне сложно назвать такой API DSL из-за количества круглых скобок и точек. В Java вы не можете просто пропустить их. Это просто мое личное чувство. –

1

Хорошая дискуссия! Я не знал Дж. Гивена, но я посмотрю.

Кроме того, я являюсь автором COLA Tests, нового фреймворка, который поддерживает полный синтаксис gherkin (точно такой же, как Cucumber), его очень легко настроить, особенно по сравнению с JBehave, и не требует JUnit runner.

В основном используйте все, что вы уже привыкли!

Вот пример Spring Test Controller (истории могут быть загружены из файла):

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes = { WebAppContext.class }) 
public class HelloWorldControllerTest extends BaseColaTest { 

    private final String stories = 
     "Feature: Introduce REST endpoint\n" 
      + "Scenario: Should say hello\n" 
      + "Given a web endpoint\n" 
      + "When hit by a get request\n" 
      + "Then the HTTP status will be OK\n" 
      + "And the body will say hello world"; 

    @Resource 
    private WebApplicationContext webApplicationContext; 
    private MockMvc mockMvc; 
    private ResultActions result; 

    @Given("a web endpoint") 
    public void given() { 
     mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
    } 

    @When("hit by a get request") 
    public void when() throws Exception { 
     result = mockMvc.perform(get("/helloWorld")); 
    } 

    @Then("the HTTP status will be OK") 
    public void thenOk() throws Exception { 
     result.andExpect(status().isOk()); 
    } 

    @Then("the body will say hello world") 
    public void thenHello() throws Exception { 
     result.andExpect(content().string("Hello World!")); 
    } 
} 
1

Дайте Ginkgo4j идти. Он использует lamda для Java 8, чтобы отразить подход, используемый RSpec и Ruby's Ginkgo.

Эта библиотека позволяет создавать выразительные, насыщенные содержанием тесты.

`` `

package com.github.paulcwarren.ginkgo4j.examples; 

import static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.*; 
import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.MatcherAssert.assertThat; 

import org.junit.runner.RunWith; 

import com.github.paulcwarren.ginkgo4j.Ginkgo4jRunner; 

@RunWith(Ginkgo4jRunner.class) 
public class BookTests { 
    private Book longBook; 
    private Book shortBook; 
    { 
     Describe("Book",() -> { 
      BeforeEach(() -> { 
       longBook = new Book("Les Miserables", "Victor Hugo", 1488); 
       shortBook = new Book("Fox In Socks", "Dr. Seuss", 24); 
     }); 

     Context("Categorizing book length",() -> { 
      Context("With more than 300 pages",() -> { 
       It("should be a novel",() -> { 
        assertThat(longBook.categoryByLength(), is("NOVEL")); 
       }); 
      }); 

      Context("With fewer than 300 pages",() -> { 
       It("should be a short story",() -> { 
        assertThat(shortBook.categoryByLength(), is("NOVELLA")); 
       }); 
      }); 
     }); 
     }); 
    } 
} 

` ``

поддерживает также Spring.

(Полное раскрытие. Я являюсь автором этой библиотеки).

3

Другой альтернативой было бы Spectrum - см https://github.com/greghaskins/spectrum

Spectrum поддерживает синтаксис RSpec/мокко и в следующем выпуске будет также поддерживать синтаксис корнишоны, наряду с интеграцией правил JUnit (так взаимодействует с Mockito, Spring и т.д. через @Rule и @ClassRule членов).

Полное раскрытие - Я вклад в этот проект OS

Пример:

@RunWith(Spectrum.class) 
public class TestSomething {{ 
    Supplier<Something> freshTestObject = let(Something::new); 

    describe("The component",() -> { 
     it("is tested by specs",() -> { 
      // the "let` above gives us a new instance of the object 
      // in each spec 
      freshTestObject.get().doSomething(); 

      // using your favourite assertion framework 
      assertThat(something.get().getSomething()).isEqualTo(42); 
     }); 
    }); 
}} 

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

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

Смежные вопросы