Imports to use

import static org.testingisdocumenting.webtau.WebTauGroovyDsl.*

Response Mapping

Identifiers inside validation closure are automatically mapped to a response body. Groovy http.get("/end-point-simple-object") { k1.should == 'v1' } Java http.get("/end-point-simple-object", (header, body) -> { body.get("k1").should(equal("v1")); }); List responses are handled by using index chain Groovy http.get("/end-point-simple-list") { body[0].k1.should == 'v1' } Note: Groovy API implicitly assumes body , but if you need to deal with array response you need to access values using body explicitly. Java http.get("/end-point-simple-list", (header, body) -> { body.get(0).get("k1").should(equal("v1")); });

Should and Should Not

Matchers in webtau are triggered with should and shouldNot keywords. Additionally shouldBe and shouldNotBe alias keywords are available to make certain matcher combinations easier to read. Groovy http.get("/example") { year.shouldNot == 2000 year.should != 2000 // alternative shortcut genres.should contain('RPG') rating.shouldBe > 7 } Java http.get("/example", (header, body) -> { body.get("year").shouldNot(equal(2000)); body.get("genres").should(contain("RPG")); body.get("rating").shouldBe(greaterThan(7)); });

Equality

Webtau defines its own set of equality rules to simplify testing. Groovy http.get("/end-point") { id.should != 0 amount.should == 30 list.should == [1, 2, 3] object.k1.should == ~/v\d/ // regular expression matching object.should == [k1: 'v1', k3: 'v3'] // matching only specified fields and can be nested multiple times complexList.should == ["k1" | "k2"] { // matching only specified fields, but number of entries must be exact ________________ "v1" | 30 "v11" | 40 } } Java http.get("/end-point", (header, body) -> { body.get("id").shouldNot(equal(0)); body.get("amount").should(equal(30)); body.get("list").should(equal(Arrays.asList(1, 2, 3))); body.get("object").get("k1").should(equal( Pattern.compile("v\\d"))); // regular expression matching body.get("object").should(equal(aMapOf( "k1", "v1", "k3", "v3"))); // matching only specified fields and can be nested multiple times body.get("complexList").should(equal(table("k1" , "k2", // matching only specified fields, but number of entries must be exact ________________, "v1" , 30, "v11", 40))); }); http.doc.capture("end-point-object-equality-matchers"); Groovy http.get("/end-point") { complexList.should == [ "*id" | "k1" | "k2"] { // order agnostic key based match ________________________ "id2" | "v11" | 40 "id1" | "v1" | 30 } } Java http.get("/end-point", (header, body) -> { body.get("complexList").should(equal(table("*id", "k1" , "k2", // order agnostic key based match ________________, "id2", "v11", 40, "id1", "v1" , 30))); });

Greater/Less/Equal

Use greaterThan , greaterThanOrEqual , lessThan , and lessThanOrEqual to assert numeric values. Groovy http.get("/end-point-numbers") { id.shouldBe > 0 price.shouldBe >= 100 amount.shouldBe < 150 list[1].shouldBe <= 2 id.shouldNotBe <= 0 price.shouldNotBe < 100 amount.shouldNotBe >= 150 list[1].shouldNotBe > 2 } Note: Groovy can use shortcuts > , >= , < , <= . Java http.get("/end-point-numbers", (header, body) -> { body.get("id").shouldBe(greaterThan(0)); body.get("price").shouldBe(greaterThanOrEqual(100)); body.get("amount").shouldBe(lessThan(150)); body.get("list").get(1).shouldBe(lessThanOrEqual(2)); body.get("id").shouldNotBe(lessThanOrEqual(0)); body.get("price").shouldNotBe(lessThan(100)); body.get("amount").shouldNotBe(greaterThanOrEqual(150)); body.get("list").get(1).shouldNotBe(greaterThan(2)); }); http.doc.capture("end-point-numbers-matchers");

Contain

Use contain when you cannot rely on order of values in a response. Groovy http.get("/end-point-list") { body.should contain([k1: 'v1', k2: 'v2']) body[1].k2.shouldNot contain(22) } Java http.get("/end-point-list", (header, body) -> { body.should(contain(aMapOf( "k1", "v1", "k2", "v2"))); body.get(1).get("k2").shouldNot(contain(22)); }); http.doc.capture("end-point-list-contain-matchers");

Contain All

Use containAll when you cannot rely on order of values in a response and need to check more than one value. Groovy http.get("/end-point-list") { body[1].k2.should containAll(10, 30) body[1].k2.shouldNot containAll(40, 60, 80) } Java http.get("/end-point-list", (header, body) -> { body.get(1).get("k2").should(containAll(10, 30)); body.get(1).get("k2").shouldNot(containAll(40, 60, 80)); }); http.doc.capture("end-point-list-contain-all-matchers");

Nested Contain All

Use containingAll alias to make it easier to read containAll matcher nested inside contain . Groovy http.get("/prices") { body.prices.should contain(containingAll(10, 30)) } Java http.get("/prices", (header, body) -> { body.get("prices").should(contain(containingAll(10, 30))); }); http.doc.capture("prices-contain-containing-all");

Date and Time

You can assert actual string against LocalDate and ZonedDateTime . String will be automatically converted using ISO formatter. Groovy http.get("/end-point-dates") { def expectedDate = LocalDate.of(2018, 6, 12) def expectedTime = ZonedDateTime.of(expectedDate, LocalTime.of(9, 0, 0), ZoneId.of("UTC")) tradeDate.should == expectedDate transactionTime.should == expectedTime transactionTime.shouldBe >= expectedDate paymentSchedule.should contain(expectedDate) } Java http.get("/end-point-dates", (header, body) -> { LocalDate expectedDate = LocalDate.of(2018, 6, 12); ZonedDateTime expectedTime = ZonedDateTime.of(expectedDate, LocalTime.of(9, 0, 0), ZoneId.of("UTC")); body.get("tradeDate").should(equal(expectedDate)); body.get("transactionTime").should(equal(expectedTime)); body.get("transactionTime").shouldBe(greaterThanOrEqual(expectedDate)); body.get("paymentSchedule").should(contain(expectedDate)); }); http.doc.capture("end-point-dates-matchers");

Mixing Matchers

You can use matchers in place of expected values to build a more complex expectation. Groovy http.get("/end-point-mixed") { list.should contain(lessThanOrEqual(2)) // lessThanOrEqual will be matched against each value object.should == [k1: 'v1', k3: ~/v\d/] // regular expression match against k3 complexList[0].should == [k1: 'v1', k2: lessThan(120)] // lessThen match against k2 complexList[1].should == [ k1: notEqual('v1'), // any value but v1 k2: greaterThanOrEqual(120)] complexList.should == ["k1" | "k2"] { ___________________________ ~/v\d/ | lessThan(120) "v11" | greaterThan(150) } // using matchers as cell values } Java Pattern withNumber = Pattern.compile("v\\d"); http.get("/end-point-mixed", (header, body) -> { body.get("list").should(contain(lessThanOrEqual(2))); // lessThanOrEqual will be matched against each value body.get("object").should(equal(aMapOf( "k1", "v1", "k3", withNumber))); // regular expression match against k3 body.get("complexList").get(0).should(equal(aMapOf( "k1", "v1", "k2", lessThan(120)))); // lessThen match against k2 body.get("complexList").get(1).should(equal(aMapOf( "k1", notEqual("v1"), // any value but v1 "k2", greaterThanOrEqual(120)))); TableData expected = table("k1" , "k2", // matching only specified fields, but number of entries must be exact ________________________________, withNumber , lessThan(120), "v11" , greaterThan(150)); body.get("complexList").should(equal(expected)); }); http.doc.capture("end-point-mixing-matchers");