What is JUnit?

JUnit is a unit testing framework for the Java programming language for writing and running repeatable automated tests.

Ii. JUnit features:
  • JUnit is an open resource framework for writing and running tests.
  • Provide annotations to identify test methods.
  • Provide assertions to test the expected results.
  • JUnit tests allow you to write code faster and improve quality.
  • JUnit is elegant and simple. It’s not that complicated, it takes less time.
  • JUnit tests can be run automatically and check their results and provide immediate feedback. So there is no need to comb through the report of test results manually.
  • JUnit tests can be organized as test suites, containing test cases, and even other test suites.
  • JUnit displays progress in a bar. Green if it works well; If the run fails, it turns red.
3. JUnit notes
annotations describe
@Test Test annotations that mark a method as a test case.
@Before The Before annotation indicates that the method must be executed Before each test in the class in order to perform some necessary prerequisites.
@BeforeClass BeforeClass annotations indicate that this is attached to static methods that must be executed once and before all tests of the class, which is typically used to test computations, shared configuration methods (such as database connections).
@After The After annotation indicates that this method is executed After each test (such as resetting some variables After each test, deleting temporary variables, and so on).
@AfterClass AlterClass annotations can be used to clean up some resources (such as database connections) when all tests need to be executed after the JUnit test case class. Note: methods must be static.
@Ignore You can use this annotation when you want to temporarily disable specific test execution, and every method annotated as @ignore will no longer be executed
@Runwith @runwith is used before the name of the test class to determine how the class will work. You can leave it out and use the default runner.
@Parameters Use the parameterization function.
@SuiteClasses For suite testing
JUnit’s assertion
assertions describe
void assertEquals([String message],expected value,actual value) Asserts that two values are equal. The value types may be int, short, long, byte, char, Object, and the first argument is an optional string message
void assertTrue([String message],boolean condition) Asserts that a condition is true
void assertFalse([String message],boolean condition) Asserts that a condition is false
void assertNotNull([String message],java.lang.Object object) Asserting that an object is not null
void assertNull([String message],java.lang.Object object) Declare an object null
void assertSame([String message],java.lang.Object expected,java.lang.Object actual) Asserts that two objects refer to the same object
void assertNotSame([String message],java.lang.Object unexpected,java.lang.Object actual) Asserts that two objects do not refer to the same object
void assertArrayEquals([String message],expectedArray,resultArray) Asserts that the expected array and the result array are equal. The array types may be int, short, Long, byte, CHAR, or Object

Let’s look at an example of using assertions. AssertionTest.java

public class AssertionTest {

    @Test
    public void test() {
        String obj1 = "junit";
        String obj2 = "junit";
        String obj3 = "test";
        String obj4 = "test"; String obj5 = null; int var1 = 1; int var2 = 2; int[] array1 = {1, 2, 3}; int[] array2 = {1, 2, 3}; Assert.assertEquals(obj1, obj2); Assert.assertSame(obj3, obj4); Assert.assertNotSame(obj2, obj4); Assert.assertNotNull(obj1); Assert.assertNull(obj5); Assert.assertTrue(var1 < var2); Assert.assertFalse(var1 > var2); Assert.assertArrayEquals(array1, array2); }}Copy the code

As you can see from the above class, these assertion methods work.

  • AssertEquals () This method returns normally if the two objects being compared are equal; Otherwise the failure to show up in JUnit’s window test will abort.
  • The assertSame() and assertNotSame() methods test that two object references point to exactly the same object.
  • AssertNull () and assertNotNull() methods test whether a variable is null or not (null).
  • The assertTrue() and assertFalse() methods test whether the if condition or variable is true or false.
  • AssertArrayEquals () compares two arrays, and if they are equal, the method continues without raising an error. Otherwise the failure will show up in the JUnit window and abort the test.
5. JUnit execution process

JuntiTest.java

public class JunitTest {

    @BeforeClass
    public static void beforeClass() {
        System.out.println("in before class");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("in after class");
    }

    @Before
    public void before() {
        System.out.println("in before");
    }

    @After
    public void after() {
        System.out.println("in after");
    }

    @Test
    public void testCase1() {
        System.out.println("in test case 1");
    }

    @Test
    public void testCase2() {
        System.out.println("in test case 2"); }}Copy the code

After executing the entire test class through IDEA, the results are as follows:

in before class
in before
in test case 1
in after
in before
in test case 2
in after
in after class
Copy the code
6. Ignore tests
  • A test method with the @ignore annotation will not be executed
  • If a test class has the @ignore annotation, its test methods will not be executed

We marked the testCase2() method in our test class as @ignore,

    @Ignore
    @Test
    public void testCase2() {
        System.out.println("in test case 2");
    }
Copy the code

This method is then ignored when executing the test class, resulting in:

in before class
in before
in test case 1
in after

Test ignored.
in after class
Copy the code
7. Time test

JUnit provides a convenient pause option. If a Test case takes more time than the specified number of milliseconds, JUnit will automatically mark it as a failure. The timeout parameter is used with the @test annotation, such as @test (timeout=1000). Continuing with the example, now extend the execution time of testCase1 to 5000 ms, add the time parameter, set the timeout to 1000 ms, and then execute the test class

    @Test(timeout = 1000)
    public void testCase1() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5000);
        System.out.println("in test case 1");
    }
Copy the code

TestCase1 is marked as a failure and an exception is thrown.

in before class
in before
in after

org.junit.runners.model.TestTimedOutException: testtimed out after 1000 milliseconds at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at  java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at com.lxs.JUnit.JunitTest.testCase1(JunitTest.java:35) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethodThe $1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
	at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.lang.Thread.run(Thread.java:748)

in before
in test case 2
in after
in after class
Copy the code
Eight, abnormal test

Junit provides an option to track exceptions with code handling. You can test the code to see if it throws the desired exception. The Expected parameter is used with the @test annotation. Now let’s look at @test (Expected). Create a new test method testCase3().

    @Test(expected = ArithmeticException.class)
    public void testCase3() {
        System.out.println("in test case 3");
        int a = 0;
        int b = 1 / a;
    }
Copy the code

The testCase3() method is executed alone, and the test passes because it gets an expected exception, with the result

in before class
in before
in test case 3
in after
in after class
Copy the code

If no expected exception is obtained:

in before class
in before
in test case 3
in after

java.lang.AssertionError: Expected exception: java.lang.ArithmeticException

in after class
Copy the code
Nine, parameterized test

Junit 4 introduces a new functional parameterization test. Parameterized testing allows developers to run the same test repeatedly with different values. You will follow 5 steps to create parameterized tests:

– to use parametric test that runs the test class named special org. Junit. Runners. The Parameterized.

  • Declare several variables for the test class to hold the expected value and the data used for the test.
  • Declare a public constructor with parameters for the test class and assign values to the variables declared in the second part.
  • To test the class declaration a use annotations org. Junit. Runners. The Parameterized. The Parameters modification, the return value for Java. The util. Public static method of Collection, and in this method initialize all the Parameters on the need to test.
  • Write test methods that use defined variables as parameters to test.
What is the @ RunWith?

The first step is to distinguish a few concepts: test method, test class, test set, test runner.

  • The Test methods are functions annotated with @test.
  • A Test class is a ** test.java file that contains one or more Test methods,
  • A test set is a suite that may contain multiple test classes.
  • The test runner determines the preference for running these test sets/classes/methods.

The @Runwith is placed before the name of the test class to determine how the class works. You can leave it out and use the default runner. Common runners are:

  • The @runwith (Parameterized. Class) parameterization runner uses JUnit’s parameterization function with @parameters
  • @ RunWith (Suite. Class) @ SuiteClasses ({ATest. Class, BTest. Class, CTest class}) test set runner with function of test set
  • @runwith (junit4.class), the default JUnit4 runner
  • RunWith(JUnit38ClassRunner. Class) for junit3.8-compatible runners
  • Some other running devices have more functionality. Such as @ RunWith (SpringJUnit4ClassRunner. Class) integrates the function of some of the spring

PrimeNumberCheckerTest.java

/** * Step 1: */ @runwith (Parameterized. Class) public class PrimeNumberCheckerTest {/** * Declare variable */ private Integer inputNumber; private Boolean expectedResult; private PrimeNumberChecker primeNumberChecker; /** * Step 3: Declare a public constructor with parameters for the test class, Assign values to variables */ public PrimeNumberCheckerTest(Integer inputNumber, Boolean expectedResult) {this.inputNumber = inputNumber; this.expectedResult = expectedResult; } /** * Step 4: To test the class declaration a use annotations org. Junit. Runners. The Parameterized. The Parameters modification, the return value to * Java. Util. Public static method of Collection, 1) The method must be modified by the Parameters annotation 2) the method must be public static 3) the method must return Collection type 4) The method name is not required 5) the method has no arguments */ @Parameterized.Parameters public static CollectionprimeNumbers() {
        return Arrays.asList(new Object[][]{
                {2, true},
                {6, false},
                {19, true},
                {22, false},
                {23, true}}); } @Before public voidinitialize() { primeNumberChecker = new PrimeNumberChecker(); } /** * Step 5: Write a Test method, use a custom variable to Test */ @test public voidtestPrimeNumberChecker() {
        System.out.println("Parameterized Number is : "+ inputNumber); Assert.assertEquals(expectedResult, primeNumberChecker.validate(inputNumber)); }}Copy the code

PrimeNumberChecker.java

public class PrimeNumberChecker {

    public Boolean validate(final Integer parimeNumber) {
        for (int i = 2; i < (parimeNumber / 2); i++) {
            if (parimeNumber % i == 0) {
                return false; }}return true; }}Copy the code

JUnit will execute the command multiple times according to the specified parameters. The result is as follows:

Parameterized Number is : 2
Parameterized Number is : 6
Parameterized Number is : 19
Parameterized Number is : 22
Parameterized Number is : 23
Copy the code
X. Suite testing

“Suite testing” means bundling several unit test cases together and running them. In JUnit, the @runwith and @suite annotations are used to run Suite tests. Let’s start by creating some test classes

public class JunitTest1 {

    @Test
    public void printMessage(){
        System.out.println("in JunitTest1"); }}Copy the code
public class JunitTest2 {

    @Test
    public void printMessage(){
        System.out.println("in JunitTest2"); }}Copy the code
@runwith (suite.class) @suite.suiteclasses ({** ** where the order of the class will affect the order of execution */ junittest1.class, JunitTest2.class }) public class JunitSuite { }Copy the code

Execute the JunitSuite test class and the result is:

in JunitTest1
in JunitTest2
Copy the code