On Github janschaefer / etk16-slides
@Test public void shouldInsertPetIntoDatabaseAndGenerateId() { Owner owner6 = this.clinicService.findOwnerById(6); int found = owner6.getPets().size(); Pet pet = new Pet(); pet.setName("bowser"); Collection<PetType> types = this.clinicService.findPetTypes(); pet.setType(EntityUtils.getById(types, PetType.class, 2)); pet.setBirthDate(new DateTime()); owner6.addPet(pet); assertThat(owner6.getPets().size()).isEqualTo(found + 1); this.clinicService.savePet(pet); this.clinicService.saveOwner(owner6); owner6 = this.clinicService.findOwnerById(6); assertThat(owner6.getPets().size()).isEqualTo(found + 1); // checks that id has been generated assertThat(pet.getId()).isNotNull(); }Beispiel von github.com/spring-projects/spring-petclinic
Scenario: Pets can be assigned to pet owners Given an existing pet owner And a dog named "bowser" When assigning the pet to the pet owner Then the pet owner owns an additional pet
Feature: Finding Owners Scenario: Owners can be found by last name Given an owner with last name "Müller" When searching for "Müller" Then exactly the given owner is found
public class CustomerStepdefs { @Given("an owner with last name (.*)") public void anOwnerWithLastName(String lastName) { ... } @When("searching for (.*)") public void searchingFor(String lastName) { ... } @Then("exactly the given owner is found") public void exactlyTheGivenOwnerIsFound() { ... } }
import org.junit.Test; import com.tngtech.jgiven.junit.SimpleScenarioTest; public class FindOwnerTest extends SimpleScenarioTest<StepDefs> { @Test public void owners_can_be_found_by_last_name() { given().an_owner_with_last_name("Müller"); when().searching_for("Müller"); then().exactly_the_given_owner_is_found(); } }
Scenario: owners can be found by last name Given an owner with last name "Müller" When searching for "Müller" Then exactly the given owner is found
import com.tngtech.jgiven.(junit|testng).ScenarioTest; public class SomeScenarioTest extends ScenarioTest<...> { }*Oder SimpleScenarioTest
import com.tngtech.jgiven.junit.ScenarioTest; public class SomeScenarioTest extends ScenarioTest<MyGivenStage, MyWhenStage, MyThenStage> { }
import org.junit.Test; import com.tngtech.jgiven.junit.ScenarioTest; public class SomeScenarioTest extends ScenarioTest<MyGivenStage, MyWhenStage, MyThenStage> { @Test public void my_first_scenario() { ... } }
import org.junit.Test; import com.tngtech.jgiven.junit.ScenarioTest; public class SomeScenarioTest extends ScenarioTest<MyGivenStage, MyWhenStage, MyThenStage> { @Test public void my_first_scenario() { given().some_initial_state(); when().some_action(); then().the_result_is_correct(); } }
import com.tngtech.jgiven.Stage; public class MyGivenStage extends Stage<MyGivenStage> { int state; public MyGivenStage some_initial_state() { state = 42; return this; } }
public class MyGivenStage extends Stage<MyGivenStage> { @ProvidedScenarioState int state; public MyGivenStage some_initial_state() { state = 42; return self(); } } public class MyWhenStage extends Stage<MyWhenStage> { @ExpectedScenarioState int state; @ProvidedScenarioState int result; public MyWhenStage some_action() { result = state * state; } }
given().a_customer_with_name( "John" );
Given a customer with name John
Given there are 5 coffees left
given().there_are_$_coffees_left( 5 );
@Test @DataProvider({ "1, 0", "3, 2", "5, 4"}) public void the_stock_is_reduced_when_a_book_is_ordered( int initial, int left ) { given().a_customer() .and().a_book() .with().$_items_on_stock( initial ); when().the_customer_orders_the_book(); then().there_are_$_items_left_on_stock( left ); }Verwendet den DataProviderRunner (github.com/TNG/junit-dataprovider). Parameterized Runner und Theories von JUnit sind auch unterstützt.
Scenario: the stock is reduced when a book is ordered Given a customer And a book With <initial> items on stock When the customer orders the book Then there are <left> items left on stock Cases: | # | initial | left | Status | +---+---------+------+---------+ | 1 | 1 | 0 | Success | | 2 | 3 | 2 | Success | | 3 | 5 | 4 | Success |
@Test @DataProvider({"1", "3", "5"}) public void the_stock_is_reduced_when_a_book_is_ordered( int initial ) { given().a_customer() .and().a_book() .with().$_items_on_stock( initial ); when().the_customer_orders_the_book(); then().there_are_$_items_left_on_stock( initial - 1 ); }
Scenario: the stock is reduced when a book is ordered Given a customer And a book With <initial> items on stock When the customer orders the book Then there are <numberOfItems> items left on stock Cases: | # | initial | numberOfItems | Status | +---+---------+---------------+---------+ | 1 | 1 | 0 | Success | | 2 | 3 | 2 | Success | | 3 | 5 | 4 | Success |
@Test @DataProvider({ "3, 2, true", "0, 0, false" }) public void the_stock_is_only_reduced_when_possible( int initial, int left, boolean orderExists) { given().a_customer() .and().a_book() .with().$_items_on_stock( initial ); when().the_customer_orders_the_book(); if ( orderExists ) { then().a_corresponding_order_exists_for_the_customer(); } else { then().no_corresponding_order_exists_for_the_customer(); } }
Scenario: the stock is only reduced when possible Case 1: initial = 3, left = 2, orderExists = true Given a customer And a book With 3 items on stock When the customer orders the book Then there are 2 items left on stock And a corresponding order exists for the customer Case 2: initial = 0, left = 0, orderExists = false Given a customer And a book With 0 items on stock When the customer orders the book Then there are 0 items left on stock And no corresponding order exists for the customer
@Format( value = BooleanFormatter.class, args = { "on", "off" } ) @Retention( RetentionPolicy.RUNTIME ) @interface OnOff {}
public SELF the_machine_is_$( @OnOff boolean onOrOff ) { ... }
given().the_machine_is_$( false );
Given the machine is off
SELF the_following_books_are_on_stock( @Table String[][] stockTable ) { ... }
@Test public void ordering_a_book_reduces_the_stock() { given().the_following_books_on_stock(new String[][]{ {"id", "name", "author", "stock"}, {"1", "The Hitchhiker's Guide to the Galaxy", "Douglas Adams", "5"}, {"2", "Lord of the Rings", "John Tolkien", "3"}, }); when().a_customer_orders_book("1"); then().the_stock_looks_as_follows(new String[][]{ {"id", "name", "author", "stock"}, {"1", "The Hitchhiker's Guide to the Galaxy", "Douglas Adams", "4"}, {"2", "Lord of the Rings", "John Tolkien", "3"}, }); }
Scenario: ordering a book reduces the stock Given the following books on stock | id | name | author | stock | +----+--------------------------------------+---------------+-------+ | 1 | The Hitchhiker's Guide to the Galaxy | Douglas Adams | 5 | | 2 | Lord of the Rings | John Tolkien | 3 | When a customer orders book 1 Then the stock looks as follows | id | name | author | stock | +----+--------------------------------------+---------------+-------+ | 1 | The Hitchhiker's Guide to the Galaxy | Douglas Adams | 4 | | 2 | Lord of the Rings | John Tolkien | 3 |
SELF the_following_books_are_on_stock( @Table List<BookOnStock> books) { ... }
SELF the_following_book( @Table(includeFields = {"name", "author", "priceInEurCents"}, header = VERTICAL) Book book) { ... }
public class GivenSteps extends Stage<GivenSteps> { @ProvidedScenarioState File temporaryFolder; @BeforeScenario void setupTemporaryFolder() { temporaryFolder = ... } @AfterScenario void deleteTemporaryFolder() { temporaryFolder.delete(); } }
public class TemporaryFolderRule { File temporaryFolder; public void before() { temporaryFolder = ... } public void after() { temporaryFolder.delete(); } } public class GivenSteps extends Stage<GivenSteps> { @ScenarioRule TemporaryFolderRule rule = new TemporaryFolderRule(); }
public class GivenCustomer extends Stage<GivenSteps> { CustomerBuilder builder; @ProvidedScenarioState Customer customer; public void a_customer() { builder = new CustomerBuilder(); } public void with_age(int age) { builder.withAge(age); } @AfterStage void buildCustomer() { customer = builder.build(); } }
@Test @FeatureEmail void the_customer_gets_an_email_when_ordering_a_book() { ... }
@Test @Story( "ABC-123" ) void the_customer_gets_an_email_when_ordering_a_book() { ... }
@Hidden public SELF doSomethingTechnical() { ... }
@ExtendedDescription("The Hitchhiker's Guide to the Galaxy, " + "by default the book is not on stock" ) public SELF a_book() { ... }
public class Html5ReportStage { @ExpectedScenarioState protected CurrentStep currentStep; // provided by JGiven protected void takeScreenshot() { String base64 = ( (TakesScreenshot) webDriver ) .getScreenshotAs( OutputType.BASE64 ); currentStep.addAttachment( Attachment.fromBase64( base64, MediaType.PNG ) .withTitle( "Screenshot" ) ); } }