Why does tapir use Xtend?

Xtend is a statically-typed programming language which translates to comprehensible Java source code. Syntactically and semantically Xtend has its roots in the Java programming language but improves it on many aspects.

All of Xtend’s features can be used in tapir, but we focus only on the most important ones in this documentation. To get a full set of the advantages over plain Java consult the Xtend documentation.

Active Annotations

Hint
The complete documentation can be found here.

Active annotations allow developers to participate in the translation process of Xtend source code to Java code via library code. 

tapir uses this feature a lot as it facilitates the user to focus on his domain without struggling with boilerplate and glue code. Most of the annotations provided by tapir are Active Annotations. tapir uses Xtend to guide the test developer. You could say that tapir provides an internal DSL (Domain Specific Language) for Xtend.

Example

tapir Testcases are organized in steps which are executed sequentially. Unfortunately the order of methods is not included in Java’s bytecode. Therefore we need another way to determine the order at runtime. tapir uses the Active Annotation @Step to achieve this. A @DependsOn which refers the name of the predecessor is generated. This information is evaluated at runtime and the methods can be sorted and executed in the desired order.

MyTest.xtend

@TestClass
class MyTest {
    @Step
    def void step1() {
    }
 
    @Step
    def void step2() {
    }
}

 

MyTest.java

@TestClass
public class MyTest {
    @Step
    public void step1() {
    }
 
    @Step
    @DependsOn("step1")
    public void step2() {
    }
}

Consult the javadoc of the concrete annotation in order to understand how it is processed.

Extension Methods

Hint
The complete documentation can be found here.

Extension methods allow to add new methods to existing types without modifying them. This feature is actually where Xtend got its name from. 

Extension methods enrich tapir’s API when writing test cases. On every @TestClass annotated class TapirAssertions is registered as extension. Therefore you can use methods like assertThat or containsString. By using @UseExtension it is possible to add custom extensions like BrowserInteractionService which provides openURL and getTitle.

GoogleTest.xtend

@TestClass
@UseExtension(BrowserInteractionService)
class GoogleTest {

    @Step
    def void openWebsite() {
        openURL("http://google.com/?hl=en")
    }

    @Step
    def void assertTitle() {
        assertThat[title].contains("Google")
    }
}

Generally, extension methods facilitate the Composition over Inheritence principle. Most of the tapir classes choose composition over inheritence for the known reasons.

Syntactic Sugar

Xtend offers a lot of syntactic sugar like

  • Getter access - You can access getters by the property name

    Xtend

     println(googlePage.queryField.text)
    

    Generated Java

    InputOutput.<String>println(this.googlePage.getQueryField().getText());
    
  • Setter access - Calling setters can be done with assignments

    Xtend

    googlePage.queryField.text = "tapir" 
    

    Generated Java

    this.googlePage.getQueryField().setText("tapir");
    
  • it keyword - e.g. in lamdba expression you do not have to name the parameter explictly

This is just a small insight to Xtend. You can use any Xtend feature in conjunction with tapir. We highly recommend to take a look at Xtend as it’s a very powerful JVM-based language. You can find more information at their website.