Docstoc

Software Engineering Requirements Engineering

Document Sample
Software Engineering Requirements Engineering Powered By Docstoc
					Unit Testing with JUnit

CS 3331
Fall 2009

Kent Beck and Eric Gamma. Test Infected: Programmers Love
Writing Tests, Java Report, 3(7):37-50, 1998.
Available from: http://junit.sourceforge.net/doc/testinfected/testing.htm



                                                                            1
Unit Testing

   Introduction
   Conventional approach
   Unit testing with JUnit
   More on JUnit




                              2
Testing in General
   Testing
       A way of showing the correctness of software
   Phases
       Unit testing
           To test each module (unit, or component)
            independently
           Mostly done by developers of the modules
       Integration and system testing
           To test the system as a whole
           Often done by separate testing or QA team
       Acceptance testing
           To validate system functions for (and by)
            customers or user


                                                        3
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.
          In Java, a unit is a class or interface, or a set of
           them, e.g.,
          An interface and 3 classes that implement it, or

          A public class along with its helper classes.

       Unit testing is testing of a unit.



                                                                  4
Question
   Do you get more confidence by running
    more test data?




                                            5
Why Unit Testing?
   Code isn’t right if it’s not tested.
   Practical
       Most programmers rely on testing, e.g.,
        Microsoft has 1 tester per developer.
       You could get work as a tester.
   Divide-and-conquer approach
       Split system into units.
       Debug unit individually.
       Narrow down places where bugs can be.
       Don’t want to chase down bugs in other units.




                                                        6
Why Unit Testing? (Cont.)
   Support regression testing
       So can make changes to lots of code and
        know if you broke something.
       Can make big changes with confidence.




                                                  7
How to Do Unit Testing
   Build systems in layers
       Starts with classes that don’t depend on
        others.
       Continue testing building on already tested
        classes.
   Benefits
       Avoid having to write (test) stubs.
       When testing a module, ones it depends on
        are reliable.



                                                      8
Question
   How does low coupling help testing?
   How does high coupling hurt it?




                                          9
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;
    }
}



                                                                   10
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));
  }
}


                                                     11
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?



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




                                                             13
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));
 }




                                                     14
Testing with JUnit (Cont.)
    /** 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());
    }
}




                                                         15
Compilation and Output
$ javac IMath.java IMathTest.java
$ java IMathTest
.F
Time: 0.02
There was 1 failure:
1) 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

Question: Is this better? Why?

                                                                           16
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) { ... }
    }




                                                     17
Exercise (Cont.)
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 …
}
                                                                              18
Some Terminology
   Definition
       A test data (or case) for a method M is a pair of (o,
        args), where
          o is not null and M can be sent to o,
          args is a tuple of arguments that can be passed to M.
       A test data, (o, args), for M succeeds iff o.M(args)
        behaves as expected.
       A test data, (o, args), for M fails iff it does not behave
        as expected.
   Question
       Why should o not be null?
       If M has a bug that is revealed by a test data, does
        that test data for M succeeds or fails?



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



                                                               20
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>
  }

                                                           21
Basic Usage of JUnit (Cont.)
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



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




                                     23
Assertion Methods
 Method                   Description
 assertEquals(a,b)        Test if a is equal to b
 assertFalse(a)           Test if a is false
 assertNotSame(a, b)      Test if a and b do not refer to the
                          identical object
 assertNull(a)            Test if a is null
 assertSame(a,b)          Test if a and b refer to the identical
                          object
 assertTrue(a)            Test if a is true


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




                                                                   24
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.
    }


                                                                                  25
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…
}
                                                                       26
More on JUnit -- Test Suite
   Definition
       A test suite is a set of test methods and other
        test suites.
   Test Suite
       Organize tests into a larger test set.
       Help with automation of testing.




                                                     27
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 …
}
                                                         28
More on JUnit?
   Refer to www.junit.org
   JUnit APIs available from the course Web
    page




                                          29

				
DOCUMENT INFO