Saturday, June 28, 2008

Junit 5

Do You Have To Write a Test for Everything?

No, just test everything that could reasonably break.

Be practical and maximize your testing investment. Remember that investments in testing are equal investments in design. If defects aren't being reported and your design responds well to change, then you're probably testing enough. If you're spending a lot of time fixing defects and your design is difficult to grow, you should write more tests.

If something is difficult to test, it's usually an opportunity for a design improvement. Look to improve the design so that it's easier to test, and by doing so a better design will usually emerge.

How Often Should You Run Your JUnit Tests?

Run all your unit tests as often as possible, ideally every time the code is changed. Make sure all your unit tests always run at 100%. Frequent testing gives you confidence that your changes didn't break anything and generally lowers the stress of programming in the dark.

For larger systems, you may just run specific test suites that are relevant to the code you're working on.

Run all your acceptance, integration, stress, and unit tests at least once per day (or night).

If you're using Eclipse, be sure to check out David Saff's continuous testing plug-in.

What Do You Do When a Defect Is Reported?

Test-driven development generally lowers the defect density of software. But we're all fallible, so sometimes a defect will slip through. When this happens, write a failing test that exposes the defect. When the test passes, you know the defect is fixed!

Don't forget to use this as a learning opportunity. Perhaps the defect could have been prevented by being more aggressive about testing everything that could reasonably break.

Or perhaps there are other places in the application that have the similar code that might break too.

How simple is 'too simple to break'?

The general philosophy is this: if it can't break on its own, it's too simple to break.

First example is the getX() method. Suppose the getX() method only answers the value of an instance variable. In that case, getX() cannot break unless either the compiler or the interpreter is also broken. For that reason, don't test getX(); there is no benefit. The same is true of the setX() method, although if your setX() method does any parameter validation or has any side effects, you likely need to test it.

Next example: suppose you have written a method that does nothing but forward parameters into a method called on another object. That method is too simple to break.

    public void myMethod(final int a, final String b) {
myCollaborator.anotherMethod(a, b);
}

myMethod cannot possibly break because it does nothing: it forwards its input to another object and that's all.

The only precondition for this method is "myCollaborator != null", but that is generally the responsibility of the constructor, and not of myMethod. If you are concerned, add a test to verify that myCollaborator is always set to something non-null by every constructor.

The only way myMethod could break would be if myCollaborator.anotherMethod() were broken. In that case, test myCollaborator, and not the current class.

It is true that adding tests for even these simple methods guards against the possibility that someone refactors and makes the methods "not-so-simple" anymore. In that case, though, the refactorer needs to be aware that the method is now complex enough to break, and should write tests for it -- and preferably before the refactoring.

Another example: suppose you have a JSP and, like a good programmer, you have removed all business logic from it. All it does is provide a layout for a number of JavaBeans and never does anything that could change the value of any object. That JSP is too simple to break, and since JSPs are notoriously annoying to test, you should strive to make all your JSPs too simple to break.

Here's the way testing goes:

    becomeTimidAndTestEverything
while writingTheSameThingOverAndOverAgain
becomeMoreAggressive
writeFewerTests
writeTestsForMoreInterestingCases
if getBurnedByStupidDefect
feelStupid
becomeTimidAndTestEverything
end
end

The loop, as you can see, never terminates.


How To Verify the JUnit Plugin in Eclipse?

If you download and install the standard package of Eclipse 3.1.2, it comes with the JUnit plugin: org.junit_3.8.1. To verify this, you should find this directory under inside the plugins directory with these items:

Directory of C:\eclipse\plugins\org.junit_3.8.1 12/30/2007 03:24 PM . 12/30/2007 03:24 PM .. 01/18/2006 04:28 PM 2,520 about.html 01/18/2006 04:28 PM 121,070 junit.jar 01/18/2006 04:28 PM META-INF 01/18/2006 04:28 PM 592 plugin.properties 01/18/2006 04:28 PM 84 plugin.xml 4 File(s) 124,266 bytes


How To Create Test Class in Eclipse?

There are five ways to create a JUnit test case class in Eclipse with JUnit plugin: org.junit_3.8.1. First, select the directory (usually unittests/) that you wish to create the test case class in.

1. Select File > New > JUnit Test Case.

2. Select the arrow of the button in the upper left of the toolbar. Select JUnit Test Case.

3. Right click on a package in the Package Explorer view in the Java Perspective, and select JUnitTestCase.

4. Click on the arrow of the icon in the toolbar. Select JUnit Test Case.

5. You can create a normal Java class as shown in the Eclipse tutorial, but include junit.framework.TestCase as the super class of the test class you are creating.

How to Run a JUnit Test Case in Eclipse?

There are three ways to run JUnit Test Cases or Test Suites in Eclipse with JUnit plugin: org.junit_3.8.1.

1. You can right click on the test case class or test suite class and select Run As > JUnit Test.

2. You can select a test case or suite and click the arrow on the icon or select Run from the toolbar, and select Run As > JUnit Test.

3. You can select a test case or suite and click the arrow on the icon or select Run from the toolbar, and select Run... From here you will create a new JUnit test configuration, and name it. You can choose to run a single test case, or run all test cases in a project or folder.


Can You Describe Steps of Creating Test Case Classes in Eclipse?

There are detailed steps to create a test case class in Eclipse with JUnit plugin: org.junit_3.8.1.

1. Use the Browse button to search for a different super class. The default super class is junit.framework.TestCase.

2. Check which method stubs you would like to create. You can create a main method, setUp(), tearDown(), or a constructor(), but all of these are optional. A constructor is only run when the test case class is first instantiated, but the setUp() and tearDown() methods are run before and after, respectively, each test case is run.

3. You can browse the application that you are creating for a class that you wish to test, or this could be left blank if you will generate the class while creating while creating the test.

- If you selected a "Class Under Test" you can click the Next button, otherwise click Finish. You will be able to select which methods in the class under test that you want to write test cases for. The method signatures will be created for you. Click Finish. The new test case class will be open in the editor.

- This test class demonstrates the basic functionality of the setUp() and tearDown() methods, and gives example test cases. The testForException() method demonstrates how to test that an exception is properly thrown.

Note: All source methods in the class under test must be public or protected, not private, in order to be tested by JUnit. If the method in the class under test is private, the test class must be in the same package.

How to creating a Test Suite using JUnit in Eclipse?

There are four ways to create a JUnit test suite class in Eclipse with JUnit plugin: org.junit_3.8.1. First, select the directory (usually unittests/) that you wish to create the test suite class in.

1. Select File > New > Other... > Java > JUnit > JUnit Test Suite.

2. Select the arrow of the button in the upper left of the toolbar. Select Other... > Java > JUnit > JUnit Test Suite,

3. Right click on a package in the Package Explorer view in the Java Perspective, and select Other... > Java > JUnit > JUnit Test Suite, or

4. You can create a normal Java class as shown in the Eclipse tutorial, but include junit.framework.TestSuite as the super class of the test class you are creating.

How Do You Use Ant to Create HTML Test Reports?

1. Ensure that Ant's optional.jar file is either in your CLASSPATH or exists in your $ANT_HOME/lib directory.

2. Add an ANT property for the directory containing the HTML reports:

      

3. Define the Ant task for running JUnit and generating reports:



















4. Run the test:

      ant test-html

How Do You Test Classes That Must Be Run in a J2EE Container?

To test classes that must be run in a J2EE container (e.g. servlets, EJBs), you should refactor J2EE components to delegate functionality to other objects that don't have to be run in a J2EE container 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 environment.

How Do You Test Classes That Must Be Run in a J2EE Container?

To test classes that must be run in a J2EE container (e.g. servlets, EJBs), you should refactor J2EE components to delegate functionality to other objects that don't have to be run in a J2EE container 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 environment.

Can You Explain the Exception: "No runnable methods"?

You will get this exception, if you use the JUnit 4.4 core runner to execute a class that has no "@Test" method. You can try this sample class:

public class Hello {
public static void main(String[] arg) {
System.out.print("Hello world!");
}
}

Run this class with the JUnit 4.4 core runner:

java -cp .;junit-4.4.jar org.junit.runner.JUnitCore Hello

JUnit version 4.4
.E
Time: 0
There was 1 failure:
1) initializationError0(Hello)
java.lang.Exception: No runnable methods
at org.junit.internal.runners.MethodValidator.validateInstanceM
at org.junit.internal.runners.MethodValidator.validateMethodsFo
at org.junit.internal.runners.JUnit4ClassRunner.validate(JUnit4
at org.junit.internal.runners.JUnit4ClassRunner.(JUnit4Cl
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Nativ
...
at org.junit.runner.JUnitCore.run(JUnitCore.java:100)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:81)
at org.junit.runner.JUnitCore.main(JUnitCore.java:44)

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

No comments:

Topics