jun it faqs

Upload: nipun-sharma

Post on 05-Apr-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Jun It Faqs

    1/8

    1. How do I write and run a simple test?

    Create a class:

    package junitfaq;

    import org.junit.*;

    import static org.junit.Assert.*;

    import java.util.*;

    public class SimpleTest {

    Write a test method (annotated with @Test) that asserts expected results on the object under test:

    @Test

    public void testEmptyCollection() {

    Collection collection = new ArrayList();

    assertTrue(collection.isEmpty());

    }

    If you are running your JUnit 4 tests with a JUnit 3.x runner, write a suite() method that uses the

    JUnit4TestAdapter class to create a suite containing all of your test methods:

    public static junit.framework.Test suite() {

    return new junit.framework.JUnit4TestAdapter(SimpleTest.class);}

    Although writing a main() method to run the test is much less important with the advent of IDE runners,

    it's still possible:

    public static void main(String args[]) {

    org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");

    }

    }

    1. Run the test: To run the test from the console, type:

    java org.junit.runner.JUnitCore junitfaq.SimpleTest

    To run the test with the test runner used in main(), type:

    java junitfaq.SimpleTest

    2. The passing test results in the following textual output:3.

    4. .

    5. Time: 06.

    7. OK (1 tests)

    8.

    2. How do I use a test fixture?

    A test fixture is useful if you have two or more tests for a common set of objects. Using a test fixture avoids

    duplicating the code necessary to initialize (and cleanup) the common objects.

    Tests can use the objects (variables) in a test fixture, with each test invoking different methods on objects in

    fixture and asserting different expected results. Each test runs in its own test fixture to isolate tests from the c

  • 7/31/2019 Jun It Faqs

    2/8

    made by other tests. That is, tests don't share the state of objects in the test fixture. Because the tests are isola

    they can be run in any order.

    To create a test fixture, declare instance variables for the common objects. Initialize these objects in a publi

    method annotated with @Before. The JUnit framework automatically invokes any @Before methods before

    test is run.

    The following example shows a test fixture with a common Collection object.

    package junitfaq;

    import org.junit.*;

    import static org.junit.Assert.*;

    import java.util.*;

    public class SimpleTest {

    private Collection collection;

    @Before

    public void setUp() {

    collection = new ArrayList();

    }

    @Test

    public void testEmptyCollection() {

    assertTrue(collection.isEmpty());

    }

    @Test

    public void testOneItemCollection() {

    collection.add("itemA");

    assertEquals(1, collection.size());

    }

    }

    Given this test, the methods might execute in the following order:setUp()

    testEmptyCollection()

    setUp()

    testOneItemCollection()

    The ordering of test-method invocations is not guaranteed, so testOneItemCollection() might be execute

    before testEmptyCollection(). But it doesn't matter, because each method gets its own instance of the

    collection.

    Although JUnit provides a new instance of the fixture objects for each test method, if you allocate any extern

    resources in a @Before method, you should release them after the test runs by annotating a method with @Af

    The JUnit framework automatically invokes any @After methods after each test is run. For example:

    package junitfaq;

    import org.junit.*;

    import static org.junit.Assert.*;

    import java.io.*;

    public class OutputTest {

    private File output;

    @Before

    public void createOutputFile() {

  • 7/31/2019 Jun It Faqs

    3/8

    output = new File(...);

    }

    @After

    public void deleteOutputFile() {

    output.delete();

    }

    @Test

    public void testSomethingWithFile() {

    ...

    }}

    With this test, the methods will execute in the following order:

    createOutputFile()

    testSomethingWithFile()

    deleteOutputFile()

    3. How do I test a method that doesn't return anything?

    Often if a method doesn't return a value, it will have some side effect. Actually, if it doesn't return a value ANdoesn't have a side effect, it isn't doing anything.

    There may be a way to verify that the side effect actually occurred as expected. For example, consider the ad

    method in the Collection classes. There are ways of verifying that the side effect happened (i.e. the object waadded). You can check the size and assert that it is what is expected:

    @Test

    public void testCollectionAdd() {

    Collection collection = new ArrayList();

    assertEquals(0, collection.size());

    collection.add("itemA");

    assertEquals(1, collection.size());collection.add("itemB");

    assertEquals(2, collection.size());

    }

    Another approach is to make use ofMockObjects.

    A related issue is to design for testing. For example, if you have a method that is meant to output to a file, doin a filename, or even a FileWriter. Instead, pass in a Writer. That way you can pass in a StringWriter

    capture the output for testing purposes. Then you can add a method (e.g. writeToFileNamed(String file

    to encapsulate the FileWriter creation.

    4. Under what conditions should I test get() and set() methods?

    Unit tests are intended to alleviate fear that something might break. If you think a get() orset() method co

    reasonably break, or has in fact contributed to a defect, then by all means write a test.

    In short, test until you're confident. What you choose to test is subjective, based on your experiences and con

    level. Remember to be practical and maximize your testing investment.

    Refer also to "How simple is 'too simple to break'?".

    5. Under what conditions should I not test get() and set() methods?

    http://www.mockobjects.com/http://junit.sourceforge.net/doc/faq/faq.htm#best_3%23best_3http://junit.sourceforge.net/doc/faq/faq.htm#best_3%23best_3http://www.mockobjects.com/
  • 7/31/2019 Jun It Faqs

    4/8

    Most of the time, get/set methods just can't break, and if they can't break, then why test them? While it is usu

    better to test more, there is a definite curve of diminishing returns on test effort versus "code coverage". Rem

    the maxim: "Test until fear turns to boredom."

    Assume that the getX() method only does "return x;" and that the setX() method only does "this.x = x;". If

    write this test:

    @Test

    public void testGetSetX() {

    setX(23);

    assertEquals(23, getX());}

    then you are testing the equivalent of the following:

    @Test

    public void testGetSetX() {

    x = 23;

    assertEquals(23, x);

    }

    or, if you prefer,

    @Test

    public void testGetSetX() {

    assertEquals(23, 23);

    }

    At this point, you are testing the Java compiler, or possibly the interpreter, and not your component or applic

    There is generally no need for you to do Java's testing for them.

    If you are concerned about whether a property has already been set at the point you wish to call getX(), then

    want to test the constructor, and not the getX() method. This kind of test is especially useful if you have mu

    constructors:

    @Test

    public void testCreate() {

    assertEquals(23, new MyClass(23).getX());

    }

    6. How do I write a test that passes when an expected exception is thrown?

    Add the optional expected attribute to the @Test annotation. The following is an example test that passes w

    expected IndexOutOfBoundsException is raised:

    @Test(expected=IndexOutOfBoundsException.class)

    public void testIndexOutOfBoundsException() {

    ArrayList emptyList = new ArrayList();

    Object o = emptyList.get(0);

    }

    7. How do I write a test that fails when an unexpected exception is thrown?

  • 7/31/2019 Jun It Faqs

    5/8

    Declare the exception in the throws clause of the test method and don't catch the exception within the test m

    Uncaught exceptions will cause the test to fail with an error.

    The following is an example test that fails when the IndexOutOfBoundsException is raised:

    @Test

    public void testIndexOutOfBoundsExceptionNotRaised()

    throws IndexOutOfBoundsException {

    ArrayList emptyList = new ArrayList();

    Object o = emptyList.get(0);

    }

    8. How do I test protected methods?

    Place your tests in the same package as the classes under test.

    9. How do I test private methods?

    Testing private methods may be an indication that those methods should be moved into another class to promreusability.

    But if you must...

    If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the a

    the PrivilegedAccessor. For details on how to use it, read this article.

    10. Why does JUnit only report the first failure in a single test?

    Reporting multiple failures in a single test is generally a sign that the test does too much, compared to what a

    test ought to do. Usually this means either that the test is really a functional/acceptance/customer test or, if it unit test, then it is too big a unit test.

    JUnit is designed to work best with a number of small tests. It executes each test within a separate instance o

    test class. It reports failure on each test. Shared setup code is most natural when sharing between tests. This idesign decision that permeates JUnit, and when you decide to report multiple failures per test, you begin to f

    against JUnit. This is not recommended.

    Long tests are a design smell and indicate the likelihood of a design problem. Kent Beck is fond of saying in

    case that "there is an opportunity to learn something about your design." We would like to see a pattern langudevelop around these problems, but it has not yet been written down.

    Finally, note that a single test with multiple assertions is isomorphic to a test case with multiple tests:

    One test method, three assertions:

    public class MyTestCase {

    @Test

    public void testSomething() {

    // Set up for the test, manipulating local variables

    assertTrue(condition1);

    assertTrue(condition2);

    assertTrue(condition3);

    http://sourceforge.net/projects/privaccessor/http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.htmlhttp://sourceforge.net/projects/privaccessor/http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.html
  • 7/31/2019 Jun It Faqs

    6/8

    }

    }

    Three test methods, one assertion each:

    public class MyTestCase {

    // Local variables become instance variables

    @Before

    public void setUp() {// Set up for the test, manipulating instance variables

    }

    @Test

    public void testCondition1() {

    assertTrue(condition1);

    }

    @Test

    public void testCondition2() {

    assertTrue(condition2);

    }

    @Test

    public void testCondition3() {

    assertTrue(condition3);

    }

    }

    The resulting tests use JUnit's natural execution and reporting mechanism and, failure in one test does not aff

    execution of the other tests. You generally want exactly one test to fail for any given bug, if you can manage

    11. In Java 1.4, assert is a keyword. Won't this conflict with JUnit's assert() method?

    JUnit 3.7 deprecated assert() and replaced it with assertTrue(), which works exactly the same way.

    JUnit 4 is compatible with the assert keyword. If you run with the -ea JVM switch, assertions that fail wil

    reported by JUnit.

    12. How do I test things that must be run in a J2EE container (e.g. servlets, EJBs)?

    Refactoring J2EE components to delegate functionality to other objects that don't have to be run in a J2EE co

    will improve the design and testability of the software.

    Cactus is an open source JUnit extension that can be used to test J2EE components in their natural environm

    13. Do I need to write a test class for every class I need to test?

    No. It is a convention to start with one test class per class under test, but it is not necessary.

    Test classes only provide a way to organize tests, nothing more. Generally you will start with one test class p

    under test, but then you may find that a small group of tests belong together with their own common test fixt

    In this case, you may move those tests to a new test class. This is a simple object-oriented refactoring: separaresponsibilities of an object that does too much.

    http://jakarta.apache.org/cactus/index.htmlhttp://jakarta.apache.org/cactus/index.html
  • 7/31/2019 Jun It Faqs

    7/8

    Another point to consider is that the TestSuite is the smallest execution unit in JUnit: you cannot execute a

    smaller than a TestSuite at one time without changing source code. In this case, you probably do not want to

    tests in the same test class unless they somehow "belong together". If you have two groups of tests that you tyou'd like to execute separately from one another, it is wise to place them in separate test classes.

    [1] A test fixture is a common set of test data and collaborating objects shared by many tests. Generally they

    implemented as instance variables in the test class.

    14. Is there a basic template I can use to create a test?

    The following templates are a good starting point. Copy/paste and edit these templates to suit your coding sty

    SampleTest is a basic test template:

    import org.junit.*;

    import static org.junit.Assert.*;

    public class SampleTest {

    private java.util.List emptyList;

    /*** Sets up the test fixture.

    * (Called before every test case method.)

    */

    @Before

    public void setUp() {

    emptyList = new java.util.ArrayList();

    }

    /**

    * Tears down the test fixture.

    * (Called after every test case method.)

    */

    @Afterpublic void tearDown() {

    emptyList = null;

    }

    @Test

    public void testSomeBehavior() {

    assertEquals("Empty list should have 0 elements", 0, emptyList.size());

    }

    @Test(expected=IndexOutOfBoundsException.class)

    public void testForException() {

    Object o = emptyList.get(0);

    }

    }

    15. How do I write a test for an abstract class?

    An Abstract TestCaseis a TestCasefor an AbstractClassthat ensures that concrete implementations of the ab

    class behave as expected.

    The Abstract TestCase will have abstract methods to enable it to obtain concrete subclasses of the Abstract cla

    under test, to obtain appropriate arguments for tests and expected results.

    http://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?AbstractClasshttp://c2.com/cgi/wiki?AbstractClasshttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?TestCasehttp://c2.com/cgi/wiki?AbstractClasshttp://c2.com/cgi/wiki?TestCase
  • 7/31/2019 Jun It Faqs

    8/8

    16. When are tests garbage collected?

    By design, the tree of Test instances is built in one pass, then the tests are executed in a second pass. The test

    holds strong references to all Test instances for the duration of the test execution. This means that for a very test run with many Test instances, none of the tests may be garbage collected until the end of the entire test ru

    Therefore, if you allocate external or limited resources in a test, you are responsible for freeing those resourc

    Explicitly setting an object to null in the tearDown() method, for example, allows it to be garbage collecte

    before the end of the entire test run.