Mittwoch, 2. Dezember 2009

Example JUnit Test With Test Steps

Some times in a tests we want to have separate test steps that means to ensure the run of more then one statement e.g. assert statements.

Here a simple JUnit test, this tests show how such tests steps can look in a JUnit 4.X tests:

public class StackTest {

 Stack stack;

 @Before public void createStack() {
  stack = new Stack();
 }

 @Test public void push() {
  new Steps() {
   
   @Step public void setupPushElementsInStack() {
    stack.push("Element One");
    stack.push("Element Three");
    stack.push("Element X");
   }
   
   @Step public void verifyStackSizeIsThree() {
    assertEquals(2, stack.size());
   }
   
   @Step public void verifyStackElementOne() {
    assertElementIs(0, "Element One");
   }
   
   @Step public void verifyStackElementTwo() {
    assertElementIs(1, "XY");
   }
   
  };
 }

 private void assertElementIs(int position, String expected) {
  String element = stack.get(position);
  assertEquals(expected, element);
 }
}

And here the test result:


And here the code of the Steps class:

public class Steps {

 private List testStepFailures = new ArrayList();
 
 {
  run();
 }
 
 public final void run() {
  Method[] methods = getClass().getMethods();
  for (Method method : methods) {
   try 
   {
    Step step = method.getAnnotation(Step.class);
    if(step != null){
     method.invoke(this);
    }
   } 
   catch (Exception e) 
   {
    TestFailure failure = new TestFailure();
    failure.method = method;
    failure.exception = e;
    testStepFailures.add(failure);
   } 
  }
  if(testStepFailures.size() > 0){
   throw new TestStepsFailureException(testStepFailures);
  }
 }

}

Kommentare:

  1. Looks nice, BUT : Java dosn't guarantee the method order! Therefore this can work, but must not.

    Also in most cases you would need "fields" to pass values from one Step to the next. Eg. a execute() produces a result, which you want to verify.

    AntwortenLöschen