Software Testing Social Network

Free Software Testing Tutorial and Quality Assurance Portal

Home Featured Articles Software Testing Software Testing Tools Unit Testing with JUnit

Unit Testing with JUnit

This article contains the following information:

  • Introduction

  • Conventional approach

  • Unit testing with JUnit

  • More on JUnit

What Is Unit Testing?

Definition

  • Testing is the process of showing that a program works for certain inputs.

  • A unit is a module or a small set of modules.

  1. In Java, a unit is a class or interface, or a set of them, e.g.,

  2. An interface and 3 classes that implement it, or

  3. A public class along with its helper classes.

  • Unit testing is testing of a unit.

How to Do Unit Testing

1.    Build systems in layers
a.    Starts with classes that donÙt depend on others.
b.    Continue testing building on already tested classes.
2.    Benefits
a.    Avoid having to write (test) stubs.
b.    When testing a module, ones it depends on are reliable.

Program to Test

public final class IMath {

   /**
    * Returns an integer approximation to the square root of x.
    */
   public static int isqrt(int x) {
       int guess = 1;
       while (guess * guess < x) {
            guess++;
       }
       return guess;
   }
}
Conventional Testing

 /** A class to test the class IMath. */
public class IMathTestNoJUnit {
   /** Runs the tests. */
   public static void main(String[] args) {
       printTestResult(0);
       printTestResult(1);
       printTestResult(2);
       printTestResult(3);
       printTestResult(4);
       printTestResult(7);
       printTestResult(9);
       printTestResult(100);
  }
 private static void printTestResult(int arg) {
       System.out.print(“isqrt(“ + arg + “) ==>  “);
       System.out.println(IMath.isqrt(arg));
  }
}
  Conventional Test Output

Isqrt(0) ==> 1
Isqrt(1) ==> 1
Isqrt(2) ==> 2
Isqrt(3) ==> 2
Isqrt(4) ==> 2
Isqrt(7) ==> 3
Isqrt(9) ==> 3
Isqrt(100) ==> 10

What does this say about the code? Is it right?
WhatÙs the problem with this kind of test output?

Solution?

1.    Automatic verification by testing program
a.    Can write such a test program by yourself, or
b.    Use a testing tool such as JUnit.
2.    JUnit
a.    A simple, flexible, easy-to-use, open-source, and practical unit testing framework for Java.
b.    Can deal with a large and extensive set of test cases.
c.    Refer to www.junit.org.
 
Testing with JUnit

import junit.framework.*;

/** A JUnit test class to test the class IMath. */
public class IMathTest extends TestCase {

  /** Tests isqrt. */
  public void testIsqrt() {
    assertEquals(0, IMath.isqrt(0)); // line 23
    assertEquals(1, IMath.isqrt(1));
    assertEquals(1, IMath.isqrt(2));
    assertEquals(1, IMath.isqrt(3));
    assertEquals(2, IMath.isqrt(4));
    assertEquals(2, IMath.isqrt(7));
    assertEquals(3, IMath.isqrt(9));
    assertEquals(10, IMath.isqrt(100));
  }
   /** Returns the test suite for this test class. */
  public static Test suite() {
    return new TestSuite(IMathTest.class);
  }

  /** Run the tests. */
  public static void main(String[] args) {
    junit.textui.TestRunner.run(suite());
    // junit.swingui.TestRunner.run(suite());
  }
}

Compilation and Output 

$ javac IMath.java IMathTest.java
$ java IMathTest
.F
Time: 0.02
There was 1 failure:
testIsqrt(IMathTest)junit.framework.AssertionFailedError: expected:<0> but was:<1>
      at IMathTest.testIsqrt(IMathTest.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMeth...
    at sun.reflect.Delegating...
    at IMathTest.main(IMathTest.java:17)

FAILURES!!!
Tests run: 1,  Failures: 1,  Errors: 0

Exercise
Write a JUnit test class for testing
public class ForYou {
   /** Return the minimum of x and y. */
    public static int min(int x, int y) { ... }
}

By filling in the following:

public class ForYou {
   /** Return the minimum of x and y. */
    public static int min(int x, int y) { ... }
}

import junit.framework.*;
/** Test ForYou. */
public class ForYouTest extends TestCase {
  /** Test min. */
  public void testMin() {

  }
  // the rest as before …
}
 

 Some Terminology
1.    Definition
a.    A test data (or case) for a method M is a pair of (o, args), where
i.    o is not null and M can be sent to o,
ii.    args is a tuple of arguments that can be passed to M.
b.    A test data, (o, args), for M succeeds iff o.M(args) behaves as expected.
c.    A test data, (o, args), for M fails iff it does not behave as expected.
2.    Question
a.    Why should o not be null?
b.    If M has a bug that is revealed by a test data, does that test data for M succeeds or fails?

Parts of Test Code 

1.    Definition
a.    The test fixture is the set of variables used in testing.
b.    The test driver is the class that runs the tests.
c.    The test oracle for a test data is the code that decides success or failure for that test data.
2.    Question
a.    What in the code we saw so far was the test driver, and the oracle?
b.    What difference is there between JUnit testing and non-JUnit testing in what we saw before?

Basic Usage of JUnit 

To test a type T:
1. Write a class like:

import junit.framework.*;

/** A JUnit test class for the class T. */
public class TTest extends TestCase {
  /** Runs the tests. */
  public static void main(String[] args) {
    junit.textui.TestRunner.run(suite());
  }

  /** Returns the test suite for this test class. */
  public static Test suite() {
    return new TestSuite(TTest.class);
  }

  <test methods go here>
}

2. Compile T.java and TTest.java
    $ javac T.java TTest.java

3. Run the JUnit graphical user interface on TTest
    $ java junit.swingui.TestRunner TTest

    or

    Run the text interface (good from makefiles)
    $ java TTest

4. Look at the failures and errors

Naming Convention 

Test methods start with “test”
    e.g., testIsqrt, testMin
Test classes end with “Test”
    e.g., IMathTest, ForYouTest

Assertion Methods 

 

- Static methods defined in junit.framework.Assert
- Variations taking string error messages

More on JUnit -- Test Fixture 

Sharing test data among test methods 

public class TTest extends TestCase {


  // other methods here …

  protected void setUp() throws Exception {
     // initialize test fixture variables.
  }

  protected void tearDown() throws Exception {
     // uninitialize test fixture variables.
  }

  // test fixture variables,  i.e., fields shared by several test methods.
}

Example 

public class PointTest extends TestCase {
  private Point p;  // test fixture variable

  protected void setUp() { // initializes text fixture variables
     p = new Point(10, 10);
  }

  protected void tearDown() { } // clean up text fixture variables

  public void testSetX() { // tests SetX
     p.setX(20);
     assertEquals(20, p.getX());
  }

  public void testSetY() { // tests SetY
     p.setY(30);
     assertEquals(30, p.getY());
  }

 // template and other test methods here…
}
 

More on JUnit -- Test Suite

1.    Definition
a.    A test suite is a set of test methods and other test suites.
2.    Test Suite
a.    Organize tests into a larger test set.
b.    Help with automation of testing.

Example 

public class AllTestSuite extends TestCase {

  /** Returns the test suite for this test class. */
  public static Test suite() {
    TestSuite suite = new TestSuite() {
          public String toString() {
             return "Test suite for Project T";
          }
       };
    suite.addTestSuite(T1Test.class);
    suite.addTestSuite(T2Test.class);
    …
    suite.addTestSuite(TnTest.class);
    return suite;
  }
 
  // the rest of methods as before …
}

More on JUnit?
¡Refer to www.junit.org


Comments (0)Add Comment

Write comment
You must be logged in to post a comment. Please register if you do not have an account yet.

busy