Skip to content

Instantly share code, notes, and snippets.

@dhemery
Created December 10, 2011 00:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhemery/1453976 to your computer and use it in GitHub Desktop.
Save dhemery/1453976 to your computer and use it in GitHub Desktop.
DSLs to verify and wait for conditions: Which style do you prefer?
verifyThat(masterView, isPresent());
verifyThat(masterView, eventually(isPresent()));
// What would the "when the subject satisfies a condition" example look like? Maybe this?
when(masterView, isPresent()).touch();
masterView.verify().isPresent();
masterView.verify().eventually().isPresent();
masterView.whenPresent().touch();
verifyThat(masterView).isPresent();
verifyThat(masterView).eventually().isPresent();
when(masterView).isPresent().touch();
// Assertions
assertThat(SUBJECT).is(IN_SOME_CONDITION);
assertThat(SUBJECT).has(ATTRIBUTE, IN_SOME_CONDITION);
assertThat(SUBJECT).has(ATTRIBUTE).that(MATCHES_SOME_CRITERIA);
// Polled assertions
assertThat(SUBJECT).eventually().is(IN_SOME_CONDITION);
assertThat(SUBJECT).eventually().has(ATTRIBUTE, IN_SOME_CONDITION);
assertThat(SUBJECT).eventually().has(ATTRIBUTE).that(MATCHES_SOME_CRITERIA);
// Polled conditions
waitUntil(SUBJECT).is(IN_SOME_CONDITION);
waitUntil(SUBJECT).has(ATTRIBUTE, IN_SOME_CONDITION);
waitUntil(SUBJECT).has(ATTRIBUTE).that(MATCHES_SOME_CRITERIA);
// Polled preconditions
when(SUBJECT).is(IN_SOME_CONDITION).TAKE_AN_ACTION();
when(SUBJECT).has(ATTRIBUTE, IN_SOME_CONDITION).TAKE_AN_ACTION();
when(SUBJECT).has(ATTRIBUTE).that(MATCHES_SOME_CRITERIA).TAKE_AN_ACTION();
// SUBJECT is any object that implements SelfDescribing.
//
// ATTRIBUTE is a sampler that samples the value of some aspect
// of a subject. Typical use supplies ATTRIBUTE via a factory method.
//
// IN_SOME_CONDITION and MATCHES_SOME_CRITERIA are matchers that evaluate
// either the subject or a sampled value. Typical use supplies the matcher
// via a factory method.
//
// TAKE_AN_ACTION is any method of SUBJECT.
// The two forms of has() function similarly. They differ only in
// sentence structure and diagnostics: The ".that()" form injects
// the word "that" into the diagnostic message.
@jbrains
Copy link

jbrains commented Dec 10, 2011

Sentence-like fits English better. I think Noun-first would do better in topic-comment languages. :)

@dhemery
Copy link
Author

dhemery commented Dec 10, 2011

Thanks, JB. Over the past year I've tended to go with noun-first, because I'm working with clients who are new-ish to DSLs like these, and noun-first is more learnable. You type the noun, then a dot, and Eclipse shows all of the possibilities.

But I do like the readability of the sentence-like format. I'm also toying with a more Hamcrest-ish syntax. Maybe I'll add an example.

@jbrains
Copy link

jbrains commented Dec 10, 2011

I prefer verifyThat(object).method() because code completion helps more.

@dhemery
Copy link
Author

dhemery commented Dec 10, 2011

Yeah, I'm trying to write some real tests in Hamcrest style, and I feel buried under nested parentheses:
assertThat(masterView, eventually(is(not(present()))));

@npryce
Copy link

npryce commented Dec 11, 2011

I would make the action something passed in too. E.g.

when(masterView, both(isPresent(), displaysText("Ready!")), tap())

This means you don't need to repeat the wait condition in order to do multiple things to a screen element. And you can compose gestures out of gestures.

E.g.:

Gesture tap = sequence(touch(), shortDelay(), release())
Gesture doubleTap = sequence(tap, shortDelay(), tap)
when(masterView, both(isPresent(), displaysText("Ready!")), doubleTap)

I see your point about nested parentheses, although I configure my IDE to color parentheses pale grey and names black so they don't bother me very much! But you could chain methods together to act like keywords:

when(masterView).is(present(), displayingText("Ready!")).then(doubleTap);

This is now looking very like WebLicker. I thought it was very cool :-). But I found in practice that I needed the DSL at the layer above -- to express in the tests what was being tested -- and a DSL style at the "how it is being tested" level rather got in the way of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment