Skip to content

RedDeer basics

Josef Kopriva edited this page Apr 16, 2019 · 6 revisions

Matchers

Matchers are widely used in RedDeer to perform selection based on given criteria like comparing if given widget fits required class or if test corresponds with given regex expression. RedDeer is currently using hamcrest matchers.

Lets take a look at RedDeer's DefaultText widget constructor which accepts matchers:

public DefaultText(Matcher... matchers)

For example if you want to find DefaultText with text that contains version in standard (major,minor,build) format inside you can perform something like this:

Matcher regexMatcher = new RegexMatcher(".*\\d+\\.\\d+\\.\\d+.*")
Text t = new DefaultText(new WithTextMatcher(regexMatcher));

WithTextMatcher extracts text from widget and compares it to given RegexMatcher.

You can use multiple matcher classes provided by RedDeer like

  • RegexMatcher
  • VersionMatcher
  • WithTextMatcher
  • WithStyleMatcher
  • WithTooltipTextMatcher
  • WithLabelMatcher
  • and others.

Implementing your own matcher

You can also implement your own matcher by extending BaseMatcher. Lets create a matcher that will match all widgets with SWT.PUSH style.

public class PushStyleMatcher extends BaseMatcher<Object>{

	@Override
	public boolean matches(Object item) {
		if(item instanceof Widget) {
			int style = Display.syncExec(new ResultRunnable<Integer>() {

				@Override
				public Integer run() {
					return ((Widget)item).getStyle();
				}
			});
			return style == SWT.PUSH;
		}
		return false;
	}

	@Override
	public void describeTo(Description description) {
		description.appendText(" matching widgets with style SWT.PUSH");
		
	}
}

Remember that all operations done on SWT widgets inside matcher (matches method) have to be done inside UI thread (by calling Display.syncExec).

Wait conditions

Wait conditions are used in cases when tests have to wait until condition is met. Test continues only when specific wait condition pass and therefore developer can be sure that the test environment is in proper state.

RedDeer implements two basic waits to perform conditional waiting:

  • WaitUntil - waiting until a specific condition is met, then testing ends

  • WaitWhile - wait while a specific condition is met, then testing ends

If we want to wait for all jobs to finish, we can use:

new WaitWhile(new JobIsRunning());

or the opposite - wait until at least one job is running:

new WaitUntil(new JobIsRunning());

Every wait has a timeout which can be set by TimePeriod. If timeout is not specified TimePeriod.DEFAULT is used as a default (10 seconds). Once the wait condition timeout, a new WaitTimeoutExpiredException

In case we have a long running jobs, we can specify TimePeriod.LONG timeout (60s):

new WaitWhile(new JobIsRunning(), TimePeriod.LONG);

Group waits

Group wait consists of various waits in a sequence execution with a common timeout. Group wait can be used for various processes/actions as a complex wait consisting of several waitings with 1 shared(decreasing) timeout. If timeout time outs and not all waitings passed WaitTimeoutExpiredException is thrown.

Lets say we want to wait for running jobs to finish and until a table has at least one row and we also want all this to be done within 60 seconds:

new GroupWait(TimePeriod.LONG, WaitProvider.waitWhile(new JobIsRunning()), WaitProvider.waitUntil(new TableHasRows(new DefaultTable())));

Waiting for exact time period (not recommended)

To pause test for exact time period use static method sleep(timePeriod) of class AbstractWait. It will sleep current thread for a specified time period.

Pauses test for 5 seconds:

AbstractWait.sleep(TimePeriod.getCustom(5));

We do not recommend this approach. Remember that on different machines the execution speed may vary quite a lot. So a test using sleep may work in your environment but it may not work in another environent (like CI).

Implementing your own wait condition

You can implement your own wait condition by implementing WaitCondition interface or by extending AbstractWaitCondition.

Clone this wiki locally