h1. Test Guidelines Tests are an important part of the development work to ensure the functionality of the code. This wiki page covers the guideline regarding unit tests and states difficulties to define integration tests for new devices. h2. Unit Tests Unit tests are used to test the correct behavior of functions. The Open eCard project uses for test creation the "TestNG":http://testng.org/doc/index.html Framework which is inspired by JUnit and NUnit but provides new functionalities and is easier to use. Test files have to be placed into the separate source tree @src/test@ relative to the root directory of the project or module. The Java files should be placed into @src/test/java@ while supporting files like images, XML files or whatever the test requires has to be located in @src/test/resources@. Most Java IDEs have integrated support for this structure and create it automatically but if you just use a editor without project support you should know this. In the @java@ directory the same package structure as in the source tree should be applied. There is no strict rule which methods have to be tested. Here we give a brief overview of thing which should be tested and which not. * Do not test private methods. * Do not test getters or setters except they contain a lot of logic for input validation or something similar. * At least one unit test per non trivial public method. * Methods with parameters should be tested with correct and incorrect input data to ensure a well defined error handling. * Do not specify tests which require a specific infrastructure e.g. a working network connection or a special kind of smart cards attached to the test executing machine. * The unit test should be as small as possible. * The name of the test file should be as descriptive as possible, e.g. if you test a specific method than chose something like WrongInputInFooBarTest.java or if you test all method of an object use something like ObjectNameTest.java * Every unit test should be documented so that everyone is able to understand whats the expected result. * Every unit test should contain an Assert.assert... call but also the annotation with @@Test(expectedExceptions=...)@ is legit in case of a test with wrong data. h2. Usage of TestNG Here we provide a short introduction into the creation of unit tests with TestNG. For detailed information visit the "TestNG Documntation":http://testng.org/doc/index.html. Specifying a test works the following way:

package de.foo.bar

import org.testng.annotations.Test;

public class foo {

    @Test
    public void foobarTest() {

    }
}

So all you have to do is to annotate a public method with the @@Test@ annotation which instructs the TestNG Framework to interpret the function as test. But currently the test is always evaluated to @passed@ because no real rest method is called. So lets add some more detail to the test.

package de.foo.bar

import org.testng.annotations.Test;
import org.testng.Assert;

public class foo {

    @Test
    public void foobarTest() {
        BarObject bar = new BarObject();
        bar.open(true);
        Assert.assertNotNull(bar);
        Assert.assertTrue(bar.isOpen());
    }
}

The test creates now a @BarObject@ and sets the bar to open. Now the @assertNotNull()@ method checks that the bar is not @NULL@ that's obviously true. Furthermore a check is performed which test whether the bar is open and the bar is so the conditions is also true and the test is passed. If a condition in an Assert statement is not fulfilled the test is evaluated to failed. Another feature of TestNG is to evaluate methods which throw exception in certain cases.

package de.foo.bar

import org.testng.annotations.Test;

public class foo {

    public static class Beer {

        public boolean open(int power) throws BottleBrokenExcepion {

            if (power > 75) {
                throw new BottleBrokenException();
            } else if (power < 25) {
                return false;
            } else {
                return true;
            }
        } 

    }

    @Test(expectedExceptions = BottleBrokenException.class)
    public void beerTest() {
        Beer beer = new Beer();
        bee.open(80);
    }
}

In some case it might be necessary to create an object with a lot of methods if we would do that in the test method the method body would grow and grow. TestNG provides an annotation for methods to do such things before the test is launched.

package de.foo.bar

import org.testng.annotations.Test;
import org.testng.Assert;

public class foo {

    private Cocktail cocktail;

    @BeforeClass
    public void init() {
        cocktail.add(new Limejuice());
        cocktail.add(new Vodka());
        cocktail.add(new Beer());
        cocktail.add(new Wine());
        cocktail.shake();
    }

    @Test
    public void cocktailTest() {
        Assert.assertFalse(cocktail.tastsGood());
    }
}

*Note:* There are several other @@Before*@ annotations available see the TestNG documentation for the exact meaning.