Skip to content

Tests configuration

Marián Labuda edited this page Dec 1, 2015 · 50 revisions

There are few ways to configure tests:

  • predefined requirement annotations
  • user defined requirement annotations
  • user defined requirement annotations with xml configuration

Predefined requirement annotations

These requirements live in org.jboss.reddeer.requirements plugin and its usage is super-simple. Just annotate test class by desired annotation and RedDeer takes care of the rest.

package org.jboss.reddeer.snippet.test;

import org.jboss.reddeer.eclipse.ui.perspectives.JavaBrowsingPerspective;
import org.jboss.reddeer.junit.runner.RedDeerSuite;
import org.jboss.reddeer.requirements.cleanworkspace.CleanWorkspaceRequirement.CleanWorkspace;
import org.jboss.reddeer.requirements.openperspective.OpenPerspectiveRequirement.OpenPerspective;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(RedDeerSuite.class)
@CleanWorkspace
@OpenPerspective(JavaBrowsingPerspective.class)
public class TestWithConfiguration {

    @Test
    public void testCase1(){
        //testCase logic
    }
}

source code

In this example, workspace will be cleaned (all projects from workspace will be deleted) and JavaBrowsingPerspective will be opened.

User defined requirement annotations

####Definition of user defined annotations Requirement annotation class must implement interface Requirement<T>, where T is the annotation itself. The interface has 3 methods, which are pretty obvious and we will show them on next example.

package org.jboss.reddeer.snippet.requirement.simple;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jboss.reddeer.junit.requirement.Requirement;
import org.jboss.reddeer.snippet.requirement.simple.TestRequirement.TestReq;

public class TestRequirement implements Requirement<TestReq> {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TestReq{
    }

    public boolean canFulfill() {
        return true;
    }
    
    public void fulfill() {
        System.out.println("Fulfilling requirement.");
    }

    public void setDeclaration(TestReq declaration) {
    	// nothing to do
    }
    
    public void cleanUp() {
    	// nothing to do    	
    }
}

source code

Notice annotation TestReq being declared as inner class of TestRequirement. This is because RedDeer needs to know what enclosing class should he use for each particular annotation. This annotation will be passed to its enclosing class via setDeclaration method. This is for that cases, where annotation has some fields as shown in next example.

package org.jboss.reddeer.snippet.requirement.simple;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jboss.reddeer.junit.requirement.Requirement;
import org.jboss.reddeer.snippet.requirement.simple.TestRequirementWithField.TestReqWithField;

public class TestRequirementWithField implements Requirement<TestReqWithField> {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TestReqWithField{
        String name();
    }

    private TestReqWithField testReqWithField;

    public boolean canFulfill() {
        return true;
    }

    public void fulfill() {
        System.out.println("Fulfilling requirement with parameter: " + testReqWithField.name());
    }

    public void setDeclaration(TestReqWithField declaration) {
        this.testReqWithField = declaration;
    }
    
    public void cleanUp() {
    	// nothing to do
    }
}

source code

####Usage of user defined annotations Usage is pretty straightforward:

package org.jboss.reddeer.snippet.test;


import org.jboss.reddeer.junit.runner.RedDeerSuite;
import org.jboss.reddeer.snippet.requirement.simple.TestRequirement.TestReq;
import org.jboss.reddeer.snippet.requirement.simple.TestRequirementWithField.TestReqWithField;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(RedDeerSuite.class)
@TestReq
@TestReqWithField(name="testParameter")
public class TestsWithRequirements {
	
    @Test
    public void testCase1(){
        System.out.println("Executing test");
    }   
}

source code

This will ensure, that both requirements could be fulfilled (canFulfill() returns true) and consequently will be fulfilled. When any of requirements couldn't be fulfilled (canFulfill() returned false), no requirement will be ateempted to fulfill and this test will be skipped.

User defined requirement annotations with xml configuration

Usage is similar to "regular" annotation requirements. With difference, that requirement class must implement PropertyConfiguration interface along with Requirement<T> and must have setters for each property which will be later defined in XML.

package org.jboss.reddeer.junit.configuration.simple;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jboss.reddeer.junit.requirement.PropertyConfiguration;
import org.jboss.reddeer.junit.requirement.Requirement;
import org.jboss.reddeer.junit.configuration.simple.UserRequirement.User;
/**
 * User requirement using configuration from simple xml file
 */
public class UserRequirement implements Requirement<User>, PropertyConfiguration{

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface User {
	}
	private String name;
	
	private String ip;
	
	public boolean canFulfill() {
		// return true if you can connect to the database
		return true;
	}

	public void fulfill() {
		System.out.println("Fulfilling User requirement with\nName: " + name + "\nIP: " + ip);
		// create an admin user in the database if it does not exist yet
	}
	
	public void setDeclaration(User user) {
		// annotation has no parameters so no need to store it
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setIp(String ip) {
		this.ip = ip;
	}
}

Configuration XML can now look like this:

<?xml version="1.0" encoding="UTF-8"?>
    <testrun
        xmlns="http://www.jboss.org/NS/Req"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.jboss.org/NS/Req https://raw.github.com/jboss-reddeer/reddeer/master/plugins/org.jboss.reddeer.junit/resources/RedDeerRequirements.xsd">

        <requirements>
                <requirement class="org.jboss.reddeer.junit.configuration.simple.UserRequirement" name="userRequirement">
                        <property key="name" value="USERS_ADMINISTRATION" />
                        <property key="ip" value="127.0.0.1" />
                </requirement>
        </requirements>
    </testrun>

We must tell reddeer where are these configuration xmls stored. This can be done by rd.config property. rd.config must point either directly to xml file or to directory with more xml files. When rd.config points to directory with more xml files, test classes annotated with annotation corresponding to configured requirement (in our last example it's annotation @User) will be executed against every corresponding config file.

Injecting Requirements into tests

Requirements can be injected into test. This can be beneficial for example when we need to retrieve configuration from config file (when we have for example different configurations with login credentials)

Example:

@RunWith(RedDeerSuite.class)
@User
public class UserTest {
	
	@InjectRequirement
	private UserRequirement userRequirement;
	
	@Test
	public void test(){
		System.out.println(userRequirement.getPassword());
	}
}
Clone this wiki locally