Webtau offers, among other things, some very expressive shortcuts, like TableData. I'm currently using that with JUnit. E.g. for testing expected data from a REST endpoint e.g.:
[
{ "uuid": "1-2-3-4", "directionShort": "N", "direction": "North" },
{ "uuid": "1-2-3-5", "directionShort": "S", "direction": "South" },
{ "uuid": "1-2-3-6", "directionShort": "E", "direction": "East" },
{ "uuid": "1-2-3-7", "directionShort": "W", "direction": "West" }
]
I could write something like (yes, of course this example is a bit exagerated):
import static org.assertj.core.api.Assertions.assertThat;
import static org.testingisdocumenting.webtau.WebTauDsl.http;
import static org.testingisdocumenting.webtau.Matchers.equal;
import static org.testingisdocumenting.webtau.WebTauCore.table;
import static org.testingisdocumenting.webtau.WebTauCore.____________;
http.get(URL_CARDINAL_POINTS,
(header, body) -> {
header.get("statusCode").shouldBe(equal(200));
assertThat(body.isList()).isTrue();
assertThat(body.numberOfElements()).isEqualTo(4);
body.should(equal(table(
"*directionShort", "direction",
____________,
"N", "North",
"S", "South",
"E", "East",
"W", "West"
)));
}
);
That's practicable for small sets of values. For larger data sets I'd like to test with containAll like e.g. this:
[
{ "uuid": "...", "name": "Stockholm", "country": "Sweden", "population": 10.42 },
{ "uuid": "...", "name": "Kiew", "country": "Ukraine", "population": 10.42 },
...
]
import static org.testingisdocumenting.webtau.Matchers.containAll;
http.get(URL_CAPITAL_CITIES,
(header, body) -> {
header.get("statusCode").shouldBe(equal(200));
assertThat(body.isList()).isTrue();
assertThat(body.numberOfElements()).isGreaterThan(10);
body.should(containAll(table(
"*name", "country", "population",
________________________________,
"Paris", "France", 2.161,
"Berlin", "Germany", 3.645,
"Kiew", "Ukraine", 2.884,
"Oslo", "Norway", 0.634,
"Madrid", "Spain", 3.223
)));
}
);
What I tried:
But that doesn't work, it fails with: IllegalArgumentException: column 'name' is not present.
When leaving out the key column marker (the * in front of "name" column), the error changes to:
body.should(containAll(table("name", "country", [...])
-->
"expecting body to contain all [<the table>]: no matches found for [<the table>]"
When using contain() instead of containAll:
body.should(contain(table("name", "country", [...])
-->
"AssertionError: no match found"
Ugly solution:
Check "manually" for matches:
Object dataNode;
dataNode = body.find(it -> "Paris".equals(it.get("name").get()));
assertThat(dataNode).isNotNull();
dataNode = body.find(it -> "Kiew".equals(it.get("name").get()));
assertThat(dataNode).isNotNull();
dataNode = body.find(it -> "Oslo".equals(it.get("name").get()));
assertThat(dataNode).isNotNull();
...
which is very tedious when trying to compare more attributes other then the "key".
Still... ugly solution:
Still far away from the expressiveness of table, because the keys clutter the data:
import static org.testingisdocumenting.webtau.utils.CollectionUtils.map;
body.should(containAll(
map("name", "Paris", "country", "France", "population": 2.161),
map("name", "Berlin", "country", "Germany", "population": 3.645),
map("name", "Kiew", "country", "Ukraine", "population": 2.884),
map("name", "Oslo", "country", "Norway", "population": 0.634),
map("name", "Madrid", "country", "Spain", "population": 3.223)
));
Question:
Is there a way to use DataTable table instead of the map sequence?
body.should(containAll(table(
"*name", "country", "population",
________________________________,
"Paris", "France", 2.161,
"Berlin", "Germany", 3.645,
"Kiew", "Ukraine", 2.884,
"Oslo", "Norway", 0.634,
"Madrid", "Spain", 3.223
)));
I think it is a good suggestion! I will have to add a new rule to WebTau to make it work. I understand the intent and it makes sense.
Syntax will be
This is now released: https://testingisdocumenting.org/webtau/HTTP/matchers#contain-table
Also super glad you are using
table! Feel free to join discord server, I would love to learn more about your experience, ideas and feedback.