2013-04-16 16 views
26

Für die laufenden Projekte und zur Verbesserung unseres Entwicklungsprozesses haben wir die Entwicklung der Philosophie TDD in Betracht gezogen. Während ich nach Best Practices forschte und wie ich den neuen Ansatz für meine Kollegen/Entwickler "verkaufen" konnte, stieß ich auf BDD und stellte fest, dass es für das, was wir brauchen würden, und für die nächste Iteration von TDD noch besser geeignet wäre. Das Problem ist, dass ich bis jetzt nur die tool von Dan North, JBehave entwickelt habe und ich kann nicht sagen, dass ich erstaunt bin.Behavior Driven Development für Java - welches Framework zu verwenden?

Das Setup scheint mir umständlich und ich konnte nicht die passende Dokumentation dafür finden. Auf der anderen Seite versuchte ich auch spock das groovy Werkzeug und bis jetzt mag ich es irgendwie.

Q: Gibt es irgendwelche geeigneten Tools für BDD?
F: würden Sie statt spock verwenden und mit dem Overhead der Einführung einer anderen Sprache umgehen?

+1

Hallo Olimpiu, gibt es [verschiedene Aromen von BDD] (https://StackOverflow.com/Questions/3359327/atdd-versus-bdd-and-the-proper-use-of-a-framework/26524511#26524511). Wäre es sinnvoll, auch nichttechnische Akteure einzubeziehen? Wenn ja, wie wäre es mit Tools wie [FitNesse] (http://fitnesse.org/) oder [Concordion] (http://concordion.org/)? – user3632158

+0

@ user3632158 - Ja, es wäre sehr zu begrüßen, auch nicht-technische Interessengruppen einzubeziehen. Hast du in diese Richtung experimentiert? –

+0

wir verwenden [Concordion] (http://concordion.org) in unserem Team. Nicht-technische Business-Spezialisten schreiben Spezifikationen mit einem kostenlosen WYSIWYG-HTML-Editor (http://www.microsoft.com/en-us/download/details.aspx?id=36179). Die Spezifikationen werden dann von Entwicklern instrumentiert, um automatisierte Akzeptanztests zu erstellen. – user3632158

Antwort

33

Verhalten Driven Development ist nur eine Technik, die ohne Werkzeuge verwendet werden kann. Sie können Tests nur im BDD-Stil schreiben - z. Starten Sie die Testmethoden mit should und führen Sie eine separate Funktion mit dieser Methode ein. When und then Abschnitte können durch nur Kommentare, z.B.

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

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

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

Meine Meinung zu den genannten Rahmenbedingungen:

  • Das Problem mit JBehave ist, dass Tests wie ein komplexes Raumschiff aussehen. Auf der anderen Seite hat es hübsche Ergebnisse für Ihre Spezifikationen.

  • spock ist wirklich cool. Kompakte Syntax, schöne Ausgabe, viele Funktionen, geschrieben mit der mächtigen groovy Sprache, die die Möglichkeit der Verwendung in Verbindung mit geb bedeutet. aber es ist groovy und es kann sehr wichtig für jemanden sein.

  • scalatest (mit scala geschrieben) und easyb (geschrieben mit groovy) haben beide den gleichen Nachteil wie Spock. Die Notation "... sollte ..." und "Gegeben ... Dann". Spezifikationen sind in .story-Dateien und die Schrittimplementierungen sind in Java-Klassen. Dieser Ansatz funktioniert sehr gut als Kollaborations- und Kommunikationswerkzeug, um die Spezifikationen zu definieren, würde aber normalerweise zu viel Aufwand für die Codierung auf niedriger Ebene bedeuten.

Ich denke auch, dass die erfolgreichsten BDD-Frameworks für Java sind diejenigen, die in Java geschrieben werden, da die Java-Sprache für DSL (Domain Specific Language) Schöpfung, die Groovy oder Scala hat keine solche Flexibilität aufweist.

+0

Danke, gute Übersicht. –

+10

Meinung eines Menschen. Ich habe fantastische Erfahrungen mit Spock gemacht. Kein Problem beim Testen von Java-Code, und groovy ist unglaublich einfach für einen Java-Programmierer zu holen. Sie können anfangen, normales Java zu schreiben und weiter zu arbeiten, und dann allmählich den etwas knapperen Stil übernehmen, wenn Sie Groovy lernen, wenn Sie es wünschen. Ich war groovy skeptisch, aber Spock ist so eine Freude zu benutzen, dass es mehr als nur die minimale Anstrengung rettet, um ein bisschen Groovy zu lernen. –

12

Wenn Ihr Produktbesitzer/qa/Kunde die Tests nicht lesen kann, verwenden Sie Spock. Es ist ein sehr einfaches Werkzeug, verbessert aber die Lesbarkeit von Tests. Dank seiner leistungsstarken Funktionen brauchen Sie Mockito, Hamcrest und AssertJ nicht. Und es hat hervorragende parametrisierte Tests. Tatsächlich ist es "nur" eine bessere JUnit - ein allgemeines Werkzeug zur automatisierten Ausführung einfacher Aufgaben, sei es Unit-Tests, Integrationstests oder Abnahmetests.

Angst vor Groovy? Warum? Es ist sehr ähnlich wie Java. Je mehr Sie es lernen, desto expressiver und kürzer ist Ihr Code. Ihre Tests werden kürzer und besser lesbar sein. Groovy ist ein Einstiegsdroge auf die bessere Seite von JVM.

Sie mögen keine dynamischen Sprachen? Nun, es ist Tests und Tests ausgeführt werden durch CI-Server nach jedem Commit, nicht wahr? Wenn dein Code kaputt geht, wirst du es nach ein paar Minuten wissen. Haben Sie keinen CI-Server oder führen Sie keine regelmäßigen Tests durch? Dann kümmern Sie sich nicht darum, ein Testframework zu wählen und Ihren Prozess zu reparieren. Zerbrochene Tests sind nutzlos und wenn Sie die Tests nicht regelmäßig durchführen, werden sie bald ausfallen.

Gehen Sie mit JBehave/Gurke, wenn Sie es brauchen; Ansonsten verwende Spock.

14

Als Autor von JGiven muss ich mit sody widersprechen, dass Java nicht genug Flexibilität für DSL-Erstellung hat. In JGiven sieht BDD-Tests wie folgt:

@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 verwendet wird, zusammen mit JUnit oder TestNG und schreiben Sie Ihre Tests in einfachem Java.

+2

Ich muss dir nicht zustimmen, mein Freund. Was Sie präsentiert haben, hat nichts mit DSL zu tun. Es ist eine Art flüssiges API für Java (basierend auf den statischen Methoden), aber IMHO nicht viel lesbar und nicht verwendbar. –

+1

Naja, dann erkläre mir bitte den Unterschied zu einem Groovy DSL. Übrigens gibt es hier keine statische Methode, dies sind alle Instanzmethoden. Außerdem ist das Beispiel, das ich gezeigt habe, viel komplexer als das obige Beispiel. Ob es aber sinnvoll ist oder nicht, sollte jeder für sich entscheiden. JGiven bietet Ihnen ein Tool, das viel einfacher zu verwenden ist als Cucumber oder JBehave und dennoch Szenarioreports bereitstellt, die von Geschäftsinhabern gelesen werden können. –

+0

Es ist schwer für mich, eine solche API wegen der Menge an Klammern und Punkten als DSL zu bezeichnen. In Java kann man sie nicht einfach überspringen. Es ist nur mein persönliches Gefühl. –

1

Nizza Diskussion! Ich kannte JGiven nicht, aber ich werde es mir ansehen.

Darüber hinaus bin ich der Autor von COLA Tests, ein neues Framework, das vollständige Gherkin-Syntax (genau das gleiche wie Cucumber) unterstützt, es ist wirklich einfach einzurichten, speziell im Vergleich zu JBehave und erfordert keine JUnit Runner.

Verwenden Sie im Prinzip nur die Bibliotheken, an die Sie bereits gewöhnt sind! Hier

ist ein Beispiel Frühlings-Controller Test (Geschichten aus einer Datei geladen werden kann):

@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

Geben Ginkgo4j a go. Es verwendet Java 8's Lamda's, um den Ansatz von Rubys RSpec und Go's Ginkgo zu spiegeln.

Mit dieser Bibliothek können Sie ausdrucksstarke, inhaltsreiche Tests erstellen.

`` `

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")); 
       }); 
      }); 
     }); 
     }); 
    } 
} 

` ``

unterstützt auch Frühling.

(vollständige Offenlegung. Ich bin der Autor dieser Bibliothek).

3

Eine weitere Alternative wäre Spectrum sein - https://github.com/greghaskins/spectrum

Spectrum unterstützt die RSpec/Mokka Syntax und in seiner nächsten Version sieht auch Gherkin Syntax unterstützen, zusammen mit Integration JUnit-Regel (so es mit Mockito, Frühling usw. über die interoperabel @Rule und @ClassRule Mitglieder).

vollständige Offenlegung - ich bin ein Beitrag zu diesem Projekt O

Beispiel:

@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 gibt ein hierarchisches Testergebnis in Ihrer JUnit-Konsole.Die Stärke liegt darin, die Java-Implementierung der Spezifikationsausführung mit der Spezifikationsdefinition zu mischen - dies kann direkter sein als Frameworks, die auf Feature-Dateien und Glue-Code angewiesen sind, um sie zu parsen, insbesondere wenn die Ergebnisse aus einem Schritt übergeben werden müssen vom Test zum anderen.

Spectrum zielt darauf ab, polyglott zu sein, so sollte den Nutzern vertraut mehrerer bestehender Rahmenbedingungen scheinen.