Home CPSC 330

Unit Testing

Introduction

Testing is a huge part of software development. Most software companies employ people specifically to test.

The goal of testing is to find bugs so that they might be fixed. The earlier a bug is found the better.


Types of Testing


Automatic Testing

In order for bugs to be discovered as soon as possible, testing should be done early and often.

Because testing can be difficult and error-prone, it is automated as much as possible.

Automated tests can be run regularly to discover bugs, including regressions.


JUnit

JUnit is a unit testing framework for Java. It allows for creating unit tests and running them automatically.

To be able to use it, we must add it to our $CLASSPATH variable:


export CLASSPATH=$CLASSPATH:/usr/share/java/junit4.jar

(This will look differently on other operating systems).

JUnit let's us add tests into our code. For example, with the following simple class:


// an extremely simple class
public class Adder {
  public static int add(int a, int b) {
    return a + b;
  }
}

We can write a unit test to try to catch errors in this code as follows:


import org.junit.*;

public class AdderTest {
  @Test public void testAdd() {
    // test some cases
    Assert.assertEquals(Adder.add(12, 19), 31);
    Assert.assertEquals(Adder.add(0, -19), -19);
    Assert.assertEquals(Adder.add(190, 0), 190);
    Assert.assertEquals(Adder.add(-10, 20), 10);
  }
}

Then we need to write a program to run the tests:


import org.junit.*;
import org.junit.runner.*;
import org.junit.runner.notification.*;

public class TestRunner {
  public static void main(String[] args) {
    // run the tests
    Result result = JUnitCore.runClasses(AdderTest.class);

    // print any errors we had
    for(Failure failure : result.getFailures()) {
      System.out.println(failure.toString());
    }

    // print whether we suceeded
    System.out.printf("All test cases passed: %b\n", result.wasSuccessful());
  }
}

When we compile and run this code, it will go through each test.


JUnit Asserts

The Assert class that comes with JUnit has several useful methods:


Testing Setup

Each class can have its own unit test that exercies the methods in that unit. The test class can contain several methods, each serving as a different test. Then we can write a program, like the TestRunner above, that runs all tests.

For the following simple stack class, how can we write a unit test that exercises it?


// T is used to refer to the type being stored
class StackNode<T> {
  public StackNode(T data, StackNode<T> underneath) {
    this.data = data;
    this.underneath = underneath;
  }
  public T getData() {
    return data;
  }
  public StackNode<T> getUnderneath() {
    return underneath;
  }
  private StackNode<T> underneath;
  private T data;
}

public class Stack<T> {
  public Stack() {
    top = null;
  }
  public void push(T new_data) {
    StackNode<T> new_node = new StackNode<T>(new_data, top);
    top = new_node;
  }
  public T pop() {
    T top_data = top.getData();
    top = top.getUnderneath();
    return top_data;
  }
  public boolean empty() {
    return top == null;
  }
  private StackNode<T> top;
}

Benefits of Unit Testing

Copyright © 2018 Ian Finlayson | Licensed under a Creative Commons Attribution 4.0 International License.