2013-04-16 15 views
26

現在進行中のプロジェクトや開発プロセスの改善については、開発の理念としてTDDを採用することを検討しました。ベストプラクティスを研究し、同僚/開発者に新しいアプローチを「売る」方法を探究している間に私はBDDに出くわして、それがもっと必要であれば何かに、そして何とかしてTDDの次の反復になるように、問題は今まで私がDan NorthJBehaveによって開発されたばかりのtoolを試してみましたが、私は驚いているとは言えません。Javaの動作駆動開発 - どのフレームワークを使用するのですか?

セットアップが面倒で、とても適切なドキュメントが見つかりませんでした。一方、私はspockのグルーヴィーツールを試してみましたが、今のところ私はそれに似ています。

Q: BDDには適切なツールがありますか?
Q:代わりにspockを使用し、別の言語を導入するオーバーヘッドを処理しますか?

+1

こんにちはOlimpiu、[BDDの別のフレーバー](https://stackoverflow.com/questions/3359327/atdd-versus-bdd-and-the-properuse-of-a-framework/26524511#26524511 )。技術以外のステークホルダーも含めることは価値があるでしょうか?はいの場合は、[FitNesse](http://fitnesse.org/)や[Concordion](http://concordion.org/)などのツールを使用するとどうなりますか? – user3632158

+0

@ user3632158 - はい、技術的でないステークホルダーも含めていただければ幸いです。この方向で実験しましたか? –

+0

私たちのチームでは[Concordion](http://concordion.org)を使用しています。非技術的なビジネススペシャリストは、無料のWYSIWYG htmlエディタ(http://www.microsoft.com/en-us/download/details.aspx?id=36179)で仕様書を作成しています。仕様は開発者によって自動受入れテストを作成するために計測されます。 – user3632158

答えて

33

動作駆動型開発は、ツールなしで使用できる単なる技術です。 BDDスタイルでテストを書くことができます。テストメソッドをshouldで開始し、このメソッドで別の機能を導入してください。 Whenthenセクションは、コメントだけで置き換えることができます。言及したフレームワーク上

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

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

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

私の意見は:

  • JBehaveの問題は、テストが複雑な宇宙船のように見えるということです。一方、それはあなたの仕様のためのかなりの出力を持っています。

  • spockは本当にクールです。コンパクトな構文、かなりの出力、強力なGroovy言語で書かれた多くの機能は、gebと組み合わせて使用​​することを意味します。 BUTこれは面白く、誰かにとって非常に重要なことです。

  • scalatest(scalaと書かれています)とeasyb(groovyと書かれています)の両方がspockと同じ欠点を持っています。 "... should ..."と "Given ... Then"という表記があります。仕様は.storyファイルにあり、ステップの実装はJavaクラスになっています。このアプローチは、仕様を定義するためのコラボレーションとコミュニケーションツールとして非常にうまく機能しますが、通常、低レベルのコーディングではあまりにもオーバーヘッドになります。

私はまた、Java言語がDSLには、このような柔軟性のGroovyやScalaは持っている(ドメイン固有言語)の作成を持っていないため、Javaのための最も成功したBDDフレームワークは、Javaで書かれていないものであると思います。

+0

ありがとうございました。 –

+10

一人の意見。私はスポークで素晴らしい経験をしてきました。 Javaコードのテストには問題ありません.Groovyは、Javaプログラマがピックアップするのは非常に簡単です。あなたは通常のJavaを書くことから始めることができ、作業を続けて、望むならGroovyを学ぶときに徐々にもっと控えめなスタイルを徐々に採用することができます。私はGroovyに懐疑的でしたが、SpockはGroovyを少しでも学ぶための最小限の努力を返す以上にそれを使用するような喜びです。 –

12

製品のオーナー/ qa /お客様がテストを読むことができる場合を除き、Spockを使用してください。これは非常にシンプルなツールですが、テストの可読性を向上させます。それが強力な機能のおかげで、Mockito、Hamcrest、AssertJは必要ありません。そしてそれは優れたパラメータテストを持っています。実際、単純なタスクの自動実行、単体テスト、統合テスト、受け入れテストのための一般的なツールであるJUnitが「ちょうど良い」ものです。

恐怖グルーヴィー?どうして?これはjavaと非常によく似ています。より多くのことを学ぶほど、表現力豊かでコードが短くなります。あなたのテストは短くて読みやすくなります。 Groovyは、JVMの優れた側面を提供するゲートウェイ薬です。

動的言語が嫌いですか?さて、それはテストであり、テストはコミット後にすべてのサーバ、右か?コードが壊れた場合、数分後にコードが分かります。 CIサーバを持っていない、あるいは定期的にテストを行っていない次に、テストフレームワークを選ぶことに気を使わず、プロセスを修正してください。壊れたテストは役に立たず、定期的にテストを実行しないとすぐにテストが中断されます。

必要に応じてJBehave/Cucumberに移動します。それ以外の場合は、Spockを使用します。

14

JGivenの著者は、JavaがDSL作成に十分な柔軟性を持っていないという意見に同意する必要があります。

@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でテストを書く:次のようにJGivenで、BDDテストが見えます。

+2

私はあなたと私の友人に同意しなければならない。あなたが提示したことは、DSLとは何の関係もありません。 Java(静的メソッドに基づく)のための流暢なAPIのようなものですが、IMHOはそれほど読みにくく使えません。 –

+1

さて、Groovy DSLとの違いを教えてください。 Btw、静的メソッドはありません。これらはすべてインスタンスメソッドです。さらに、私が示した例は、上記の例よりはるかに複雑です。しかし、それが有用かどうかは誰もが自分自身のために決定するべきである。 JGivenはCucumberやJBehaveよりはるかに使いやすく、ビジネスオーナーが読めるシナリオレポートを提供します。 –

+0

かっこやドットの量のために、そのようなAPIをDSLと呼ぶのは難しいです。 Javaでは、単にスキップすることはできません。それは私の個人的な感情です。 –

1

素敵な議論!私はJGivenを知らなかったが、私はそれを見るだろう。

また、フルガキの構文(Cucumberとまったく同じ)をサポートする新しいフレームワークであるCOLA Testsの著者です。JBehaveと比べてセットアップがとても簡単で、JUnitランナーを必要としません。

基本的には、すでに使用しているライブラリを使用してください。 Ginkgo4jに行くを与える

@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

:ここ

は、たとえば春コントローラテスト(物語がファイルからロードすることができます)です。 RubyのRSpecとGoのGinkgoで使用されているアプローチを反映させるために、Java 8のlamdaを使用しています。

このライブラリを使用すると、充実した内容豊かなテストを作成できます。

`` `

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

` ``

また春をサポートしています。

(私はこのライブラリの著者です)。

3

別の方法としては、スペクトラムだろう - それは、経由などMockito、春と相互運用(JUnitのルールの統合に伴い、https://github.com/greghaskins/spectrum

スペクトラムもガーキン構文をサポートしますRSpecの/モカ構文をサポートし、その次のリリースで見ます@Ruleおよび@ClassRuleのメンバー)。

全開示 - Iこの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); 
     }); 
    }); 
}} 

スペクトラムは、あなたのJUnitコンソールの階層的なテスト結果を出力します。その強みは、仕様実行のJava実装を仕様定義とミックスすることです。これは、フィーチャー・ファイルとそれを解析するコードを使用するフレームワークよりも直接的であり、特に1つのステップから結果を渡す必要がある場合のテストの別の。

Spectrumは多言語であることを目指しているため、既存の複数のフレームワークのユーザーにはよく知られているはずです。

関連する問題