Project

General

Profile

Actions

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.

Unit Tests

Unit tests are used to test the correct behavior of functions. The Open eCard project uses for test creation the TestNG 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.

Usage of TestNG

Here we provide a short introduction into the creation of unit tests with TestNG. For detailed information visit the TestNG Documntation.

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.

Updated by Hans-Martin Haase over 8 years ago · 3 revisions

Also available in: PDF HTML TXT