Java Unit Test (using JUnit)

Source: Internet
Author: User

JUnit is a regression testing framework (regression testing framework) written by Erich Gamma and Kent Beck for Java developers to write unit tests.

1. Overview
JUnit testing is a programmer's test, the so-called white-box test, because the programmer knows how the software being tested (how) accomplishes the function and what it does.
JUnit is essentially a framework in which developers develop a set of rules that follow this requirement to write test code, such as inheriting a class and implementing an interface that can be automatically tested with JUnit.
Since JUnit is relatively independent of the code being written, it is possible to test code writing before implementing code, and the implementation of the test first design that is respected in XP has a ready-made approach: writing test code with JUnit, writing implementation code, running tests, testing failures, modifying implementation code, Run the test again until the test succeeds. Subsequent modifications and optimizations to the code are successful when the test is run successfully.
Team development under Java, with the CVS (version control) + ANT (Project management) + JUnit (integration testing) mode, can be easily implemented by using ant's configuration for automated testing.

For subjects of different properties, such as CLASS,JSP,SERVLET,EJB, JUnit has different techniques for using, and then slowly Apple told. The following is an example of a class test, unless otherwise specified.

2. Download and install


Go to the JUnit home page to download the latest version of 3.8.1 package Junit-3.8.1.zip

Unzip the Junit-3.8.1.zip to a directory named $junithome with WinZip or unzip

Add Junit.jar and $junithome/junit to Classpath, adding the latter only because the test routines are in that directory.

Be careful not to place Junit.jar under the extension directory of the JDK.

Run the command, as shown in the image on the right.
Java Junit.swingui.TestRunner junit.samples.AllTests

3. JUnit Architecture
The following is an example of the money class.

public class Money {
private int famount;//Balance
Private String fcurrency;//currency type

public money (int amount, String currency) {
famount= amount;
fcurrency= currency;
}

public int amount () {
return famount;
}

Public String currency () {
return fcurrency;
}

Public funds Add (money m) {//Plus
return new Money (Amount () +m.amount (), currency ());
}

public boolean equals (Object anobject) {//Determine if money is equal
if (AnObject instanceof money) {
Money amoney= (money) AnObject;
Return amoney.currency (). Equals (currency ())
&& amount () = = Amoney.amount ();
}
return false;
}
}


JUnit itself is designed around two design patterns: Command mode and Integrated mode.

Command mode
Using TestCase to define a subclass, generate a test object in this subclass, write code to detect whether a method is called after the state of the object is consistent with the expected state, and then assert that the program code has no bug.
When this subclass is testing the implementation code for more than one method, it is possible to set up a test base to run the tests on the same basis, to reduce the initialization of each test, and to test the connections between the different methods.
For example, we want to test the money's Add method, which can be as follows:
public class Moneytest extends TestCase {//testcase Subclass
public void Testadd () {//Put the test code in Testadd
Money m12chf= New Money ("CHF"); The bank and the next line do some initialization
Money m14chf= New Money ("CHF");
Money expected= New Money ("CHF");//Expected results
Money result= M12chf.add (M14CHF); Run the method being tested
Assert.asserttrue (expected.equals (result)); Determine if the running result is the same as expected
}
}

If you test the Equals method, use a similar code, as follows:
public class Moneytest extends TestCase {//testcase Subclass
public void Testequals () {//Put the test code in Testequals
Money m12chf= New Money ("CHF"); The bank and the next line do some initialization
Money m14chf= New Money ("CHF");

Assert.asserttrue (!m12chf.equals (null));//test for different situations
Assert.assertequals (M12CHF, M12CHF);
Assert.assertequals (M12CHF, New Money ("CHF")); (1)
Assert.asserttrue (!m12chf.equals (M14CHF));
}
}


When you want to test both the add and the Equals methods, you can combine their own initialization work together to form a test base, initialize with Setup, and clear with teardown. As follows:
public class Moneytest extends TestCase {//testcase Subclass
Private money f12chf;//fetching common objects
Private Money F14CHF;

protected void SetUp () {//Initialize common objects
f12chf= New Money ("CHF");
f14chf= New Money ("CHF");
}
public void Testequals () {//test correctness of the Equals method
Assert.asserttrue (!f12chf.equals (null));
Assert.assertequals (F12CHF, F12CHF);
Assert.assertequals (F12CHF, New Money ("CHF"));
Assert.asserttrue (!f12chf.equals (F14CHF));
}

public void Testsimpleadd () {//test the correctness of the Add method
Money expected= New Money ("CHF");
Money result= F12chf.add (F14CHF);
Assert.asserttrue (expected.equals (result));
}
}


Save any of the above three TestCase subclass code in a file named Moneytest.java, and add the first line of the file
Import junit.framework.*;
, all of them can be run. The problem with JUnit running is interesting, as described separately below.
The above explains the concept of "test Foundation (fixture)", introducing two Tests of two methods. The essential difference between command mode and integrated mode is that the former runs only one Test at a time.

Integrated mode
With Testsuite, you can include all the test*** () methods in a TestCase subclass and also include the Testsuite subclasses, which makes it a hierarchical relationship. Testsuite can be regarded as a container, you can put the testcase in the test*** () method, it can also nest. This architecture, very similar to the reality of the process of step-by-step development of the integration of the current situation.
For the above example, the code is as follows:
public class Moneytest extends TestCase {//testcase Subclass
....
public static test suite () {//Static test
TestSuite suite= new TestSuite ();//Generate a TestSuite
Suite.addtest (New Moneytest ("Testequals")); Adding Test methods
Suite.addtest (New Moneytest ("Testsimpleadd"));
return suite;
}
}

Starting with Junit2.0, there are simple ways to do this:
public class Moneytest extends TestCase {//testcase Subclass
....
public static test suite () {Static test
return new TestSuite (Moneytest.class); Take class as Parameter
}
}

Testsuite See nested examples, in the case of a later application.
  

4, the test code run
First, the most common integration patterns.
After the test code is written, you can write the main method in the corresponding class, run it directly with the Java command, or do not write the main method and run it with the JUnit-supplied runner. JUnit provides three types of Textui,awtui and Swingui actuators.
As an example of the alltests run in the previous 2nd step, there are four types:

Java Junit.textui.TestRunner junit.samples.AllTests
Java Junit.awtui.TestRunner junit.samples.AllTests
Java Junit.swingui.TestRunner junit.samples.AllTests
Java junit.samples.AllTests

In the main method, it is common to simply call Suite () with runner, and when there is no main, Testrunner generates a testsuite for the arguments that are running on the class.
  
There are two ways to run a command pattern.

Static methods

TestCase test= New Moneytest ("simple Add") {
public void Runtest () {
Testsimpleadd ();
}
};


Dynamic methods

TestCase test= New Moneytest ("Testsimpleadd");

I tried, as if there was a problem, which friend succeeded, please give me a hint. I can do that.

Import junit.framework.*;

public class Moneytest extends TestCase {//testcase Subclass
Private money f12chf;//fetching common objects
Private Money F14CHF;
Public moneytest (String name) {
Super (name);
}
protected void SetUp () {//Initialize common objects
f12chf= New Money ("CHF");
f14chf= New Money ("CHF");
}
public void Testequals () {//test correctness of the Equals method
Assert.asserttrue (!f12chf.equals (null));
Assert.assertequals (F12CHF, F12CHF);
Assert.assertequals (F12CHF, New Money ("CHF"));
Assert.asserttrue (!f12chf.equals (F14CHF));
}

public void Testadd () {//test the correctness of the Add method
Money expected= New Money ("CHF");
Money result= F12chf.add (F14CHF);
Assert.asserttrue (expected.equals (result));
}
public static void Main (string[] args) {
TestCase test=new moneytest ("simple Add") {
public void Runtest () {
Testadd ();
// }
// };
Junit.textui.TestRunner.run (test);
// }
public static void Main (string[] args) {
TestCase test=new moneytest ("Testadd");
Junit.textui.TestRunner.run (test);
}
}


Give an example of a static method with integration testing:
public static Test Suite () {
TestSuite suite= new TestSuite ();
Suite.addtest (
New Testcar ("Getwheels") {
protected void Runtest () {testgetwheels ();}
}
);

Suite.addtest (
New Testcar ("Getseats") {
protected void Runtest () {testgetseats ();}
}
);
return suite;
}


5. Application Cases


The Junit primer routines run as follows:
Java com.hedong.JunitLearning.Primer.ShoppingCartTest


Ant+junit+mailto enables automatic compilation, debugging, and sending of results build.xml

JUnit has been implemented, well written, and deeply understood. The routines run as follows:
Java com.hedong.JunitLearning.car.testCarNoJunit
Java Junit.swingui.TestRunner Com.hedong.JunitLearning.car.testCar


JUnit combined with log4j, the course of a dish runs:
CD Acai
Ant JUnit











6, some problems
Some people have summed up some very valuable use skills on the basis of practice, I did not pass one by one "test", tentatively listed here.

Do not initialize the fixture with the TestCase constructor, but with the setup () and teardown () methods.

Do not rely on or assume the order of test runs, because JUnit uses vectors to save test methods. So different platforms will remove the test method from the vector in different order. I do not know whether the 3.8 is still the case, but it provides examples of one is specified with Vectorsuite, if not specified?

Avoid writing testcase that have side effects. For example, if the subsequent test relies on certain transaction data, do not submit the transaction data. A simple rollback is all that is possible.

When inheriting a test class, remember to call the Setup () and teardown () methods of the parent class.

Put the test code and the work code together, while compiling and updating synchronously. (Use ant with a task that supports JUnit.)

Test classes and test methods should have a consistent naming scheme. If you precede the work class name with test to form the testing class name.

Make sure the test is time-independent, and do not rely on testing with outdated data. This makes it difficult to reproduce the test during the subsequent maintenance process.

If you are writing software for international markets, consider internationalization factors when writing tests. Do not test only in your native language locale.

Using the JUnit-provided Assert/fail method and exception handling methods as much as possible can make the code more concise.

The test should be as small as possible and execute faster.

Set up the test program in the same package as the subject being measured

In your original code directory to avoid the test code appears, you can put the test code in a source image directory

Include a testsuite test class in your own application package





7. Download Related Resources
The following jar packages, I just do the packaging, compiling and debugging work, for download learning, the relevant rights belong to the original author.

can run routines. jar

Build.xml

A routine of a vegetable

Junit API Translation (PDF)


8. Unfinished tasks


HttpUnit

Cactus

Test JUnit with a link pool

Java Unit Test (using JUnit)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.