2013-04-16 32 views
26

Đối với các dự án đang diễn ra và để cải thiện quy trình phát triển của chúng tôi, chúng tôi coi việc áp dụng TDD làm triết lý phát triển. Trong khi nghiên cứu các phương pháp hay nhất và cách "bán" phương pháp tiếp cận mới cho đồng nghiệp/nhà phát triển của tôi, tôi đã xem qua số BDD và thấy nó phù hợp hơn với những gì chúng tôi cần và bằng cách nào đó là lần lặp lại tiếp theo của TDD. Vấn đề là đến nay tôi đã thử chỉ có tool được phát triển bởi Dan North, JBehave và tôi không thể nói rằng tôi ngạc nhiên.Hành vi Thúc đẩy phát triển cho java - khuôn khổ nào cần sử dụng?

Quá trình thiết lập có vẻ khiến tôi cồng kềnh và tôi không thể tìm thấy tài liệu phù hợp cho nó. Mặt khác, tôi cũng đã thử công cụ groovy spock và cho đến bây giờ tôi rất thích nó.

Q: có công cụ phù hợp nào để sử dụng cho BDD không?
Q: bạn có thể sử dụng thay vì đánh và đối phó với chi phí giới thiệu ngôn ngữ khác không?

+1

Hi Olimpiu, có [hương vị khác nhau của BDD] (https://stackoverflow.com/questions/3359327/atdd-versus-bdd-and-the-proper-use-of-a-framework/26524511#26524511). Nó sẽ có giá trị để bao gồm các bên liên quan phi kỹ thuật không? Nếu có, điều gì về việc sử dụng các công cụ như [FitNesse] (http://fitnesse.org/) hoặc [Concordion] (http://concordion.org/)? – user3632158

+0

@ user3632158 - có nó sẽ được đánh giá cao để bao gồm cả các bên liên quan không kỹ thuật. Bạn đã thử nghiệm theo hướng này? –

+0

chúng tôi đang sử dụng [Concordion] (http://concordion.org) trong nhóm của chúng tôi. các chuyên gia kinh doanh phi kỹ thuật đang viết thông số kỹ thuật với trình soạn thảo html WYSIWYG miễn phí (http://www.microsoft.com/en-us/download/details.aspx?id=36179). các thông số kỹ thuật sau đó được các nhà phát triển thiết lập để tạo các kiểm tra chấp nhận tự động. – user3632158

Trả lời

33

Hành vi Thúc đẩy phát triển chỉ là một kỹ thuật có thể được sử dụng mà không cần bất kỳ công cụ nào. Bạn chỉ có thể viết các bài kiểm tra theo kiểu BDD - ví dụ: bắt đầu phương pháp thử nghiệm với should và giới thiệu một số tính năng riêng biệt với phương pháp này. Các phần Whenthen có thể được thay thế bằng chỉ các nhận xét, ví dụ:

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

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

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

Ý kiến ​​của tôi về các khuôn khổ đề cập:

  • Vấn đề với JBehave là xét nghiệm trông giống như một con tàu vũ trụ phức tạp. Mặt khác nó có đầu ra khá cho thông số kỹ thuật của bạn.

  • spock thực sự tuyệt vời. Cú pháp nhỏ gọn, đầu ra khá, rất nhiều tính năng, được viết bằng ngôn ngữ groovy mạnh mẽ, có nghĩa là khả năng sử dụng kết hợp với geb. NHƯNG nó rất hấp dẫn và có thể rất quan trọng đối với một người nào đó.

  • scalatest (bằng văn bản với scala) và easyb (bằng văn bản với groovy) cả hai đều có những bất lợi tương tự như Spock. Ký hiệu "... nên ..." và "Cho ... Sau đó". Thông số kỹ thuật nằm trong các tệp .story và các bước triển khai thực hiện trong các lớp Java. Cách tiếp cận này hoạt động rất tốt như một công cụ cộng tác và truyền thông để xác định các thông số kỹ thuật, nhưng thường là quá nhiều chi phí cho việc viết mã mức thấp.

Tôi cũng nghĩ rằng các khuôn khổ BDD thành công nhất cho Java là những người không được viết bằng Java, vì ngôn ngữ Java không có tính linh hoạt như thế cho DSL (Domain Ngôn ngữ cụ thể) tạo mà Groovy hoặc Scala có.

+0

Cảm ơn bạn, tổng quan tốt. –

+10

Ý kiến ​​của một người. Tôi đã có những trải nghiệm tuyệt vời với spock. Không có vấn đề gì khi thử nghiệm mã Java, và groovy là cực kỳ dễ dàng cho một lập trình viên Java để đón nhận. Bạn có thể bắt đầu viết Java thông thường và tiếp tục làm việc, sau đó dần dần áp dụng phong cách ngắn hơn khi bạn học Groovy nếu muốn. Tôi đã hoài nghi về Groovy, nhưng spock là một niềm vui để sử dụng nó hơn là trả lại nỗ lực tối thiểu để tìm hiểu một chút về Groovy. –

12

Trừ khi chủ sở hữu sản phẩm/qa/khách hàng của bạn cần để có thể đọc các bài kiểm tra, hãy sử dụng Spock. Nó là công cụ rất đơn giản, nhưng cải thiện khả năng đọc của các bài kiểm tra. Nhờ có các tính năng mạnh mẽ mà bạn không cần Mockito, Hamcrest hay AssertJ. Và nó có các thử nghiệm tuyệt vời. Trong thực tế, nó là "chỉ" một JUnit tốt hơn - một công cụ chung để thực hiện tự động các nhiệm vụ đơn giản, có thể là các bài kiểm tra đơn vị, các bài kiểm tra tích hợp hoặc các bài kiểm tra chấp nhận.

Loét Groovy? Tại sao? Nó rất giống với java. Bạn càng tìm hiểu nó, mã của bạn càng có tính biểu cảm và ngắn hơn. Các bài kiểm tra của bạn sẽ ngắn hơn và dễ đọc hơn. Groovy là thuốc cửa ngõ cho phía tốt hơn của JVM.

Không thích ngôn ngữ động? Vâng, đó là kiểm tra và kiểm tra được chạy bởi máy chủ CI sau mọi cam kết, phải không? Nếu mã của bạn bị hỏng, bạn sẽ biết nó sau vài phút. Không có máy chủ CI hoặc không chạy thử nghiệm thường xuyên? Sau đó, không bận tâm với việc lựa chọn một khuôn khổ thử nghiệm và đi sửa chữa quá trình của bạn. Kiểm tra bị hỏng là vô ích và nếu bạn không chạy thử nghiệm thường xuyên, chúng sẽ sớm bị hỏng.

Đi kèm với JBehave/Cucumber nếu bạn cần; Nếu không, hãy sử dụng Spock.

14

Là tác giả của JGiven Tôi phải không đồng ý với sody rằng Java không đủ linh hoạt để tạo DSL. Trong JGiven, các xét nghiệm BDD có dạng như sau:

@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 được sử dụng cùng với JUnit hoặc TestNg và bạn viết thử nghiệm của bạn trong Java thuần.

+2

Tôi phải không đồng ý với Bạn của tôi. Những gì bạn đã trình bày không liên quan gì đến DSL. Đó là một số loại API thông thạo cho Java (dựa trên các phương pháp tĩnh), nhưng IMHO không dễ đọc và không thể sử dụng được. –

+1

Vâng, sau đó xin vui lòng giải thích cho tôi sự khác biệt với một DSL Groovy. Btw, không có phương pháp tĩnh ở đây, đây là tất cả các phương pháp thể hiện. Ngoài ra, ví dụ tôi đã trình bày phức tạp hơn nhiều so với ví dụ trên. Tuy nhiên, cho dù đó là có thể sử dụng hay không nên mọi người quyết định cho mình. JGiven cung cấp cho bạn một công cụ dễ sử dụng hơn Cucumber hoặc JBehave và vẫn cung cấp các báo cáo kịch bản có thể đọc được bởi các chủ doanh nghiệp. –

+0

Thật khó để tôi gọi một API DSL như vậy do số lượng dấu ngoặc đơn và dấu chấm. Trong Java, bạn không thể bỏ qua chúng. Đó chỉ là cảm giác cá nhân của tôi. –

1

Thảo luận hay! Tôi không biết JGiven, nhưng tôi sẽ có một cái nhìn trong đó. Ngoài ra, tôi là tác giả của COLA Tests, một khung công tác mới hỗ trợ cú pháp gherkin đầy đủ (chính xác giống như Cucumber), nó rất dễ cài đặt, đặc biệt khi so sánh với JBehave và không yêu cầu JUnit runner.

Về cơ bản, chỉ cần sử dụng bất kỳ thư viện nào bạn đã sử dụng!

Dưới đây là một ví dụ Xuân điều khiển thử nghiệm (câu chuyện có thể được nạp từ một tập tin):

@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

Cho Ginkgo4j một đi. Nó sử dụng Java 8 của Java để phản ánh cách tiếp cận được sử dụng bởi RSpec của Ruby và Go's Ginkgo.

Thư viện này cho phép bạn tạo các thử nghiệm nội dung phong phú, mang tính biểu cảm.

`` `

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

` ``

Cũng hỗ trợ mùa xuân.

(Tiết lộ đầy đủ. Tôi là tác giả của thư viện này).

3

Một lựa chọn khác sẽ là Spectrum - xem https://github.com/greghaskins/spectrum

Spectrum hỗ trợ cú pháp RSpec/Mocha và trong phiên bản tiếp theo của nó cũng sẽ hỗ trợ cú pháp Gherkin, cùng với hội nhập quy tắc JUnit (vì vậy nó vận hành được với Mockito, Spring vv qua @Rule@ClassRule thành viên).

tiết lộ đầy đủ - Tôi là một người đóng góp cho dự án hệ điều hành này

Ví dụ:

@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 kết quả đầu ra là kết quả thử nghiệm thứ bậc trong giao diện điều khiển JUnit của bạn.Sức mạnh của nó là trong việc trộn Java thực hiện việc thực hiện spec với định nghĩa spec - điều này có thể trực tiếp hơn các khung dựa trên các tệp tính năng và mã keo để phân tích cú pháp chúng, đặc biệt nếu có nhu cầu chuyển kết quả từ một bước của thử nghiệm khác.

Spectrum nhằm mục đích trở thành đa ngôn ngữ, vì vậy có vẻ quen thuộc với người dùng một số khung công tác hiện có.