Unit testing with JUNIT4 in eclipse

Source: Internet
Author: User
Tags assert

When we write large programs, we need to write thousands of methods or functions that may be powerful, but we only use a small subset of the functions of the function in our program, and by debugging we can determine that a small subset of the functionality is correct. However, we should also make sure that each function is completely correct, because if we extend the program in the future and use the other functions of a function, which is a bug, it is definitely a very depressing thing. So, after each function is written, all aspects of the function should be tested, which we call unit tests. Traditional programming, unit testing is a very troublesome thing, you have to re-write another program, in the program to call the method you need to test, and carefully observe the results of the operation to see if there are errors. Because of this trouble, programmers are not very enthusiastic about writing unit tests. So there was a cow who launched the unit test package, which greatly simplifies the work of unit testing, which is JUNIT4. This article briefly describes the method of unit testing using JUNIT4 in Eclipse3.2.

First, let's take a stupid crash tutorial and don't ask why, follow Me, let's experience the thrill of unit testing!

First create a new project called Junit_test, we write a calculator class, this is a simple implementation of the subtraction, square, the root of the calculator class, and then to unit test these functions. This class is not perfect, and we deliberately keep some bugs for demonstration, which are described in the comments. This type of code is as follows:

Package Andycpp;public class Calculator {    private static int result;//static variable for storing run result public    void Add (int n) {
   
    result = result + N;    }    public void substract (int n) {        result = result-1;  Bug: Correct should be result =result-n    } public    void multiply (int n) {    }         //This method has not yet been written well public    void divide (int N) {        result = result/n;    }    public void Square (int n) {        result = n * n;    }    public void SquareRoot (int n) {for        (;;);            Bug: Dead Loop    } public    void Clear () <span style= "font-family: Song Body;" > </span>{     //Results Clear 0 Result        = 0;    }    public int GetResult () {        return result;    }}
   
The second step is to introduce the JUNIT4 Unit test package into this project: Right-click on the item, click "Properties",

In the pop-up Properties window, first select "Java Build Path" on the left, then the "Libraries" tab on the right, then on the far right, click on the "Add Library ..." button as shown:

Then select JUnit4 in the new pop-up dialog and click OK, as shown in the JUNIT4 software package is included in our project.

The third step is to generate the JUnit test framework: In Eclipse's Package Explorer, right-click on the pop-up menu and select "Newàjunit test Case". As shown in the following:

In the popup dialog box, make the appropriate selections as shown in:

After clicking "Next", the system will automatically list the methods contained in your class and choose the method you want to test. In this example, we only test the "add, subtract, multiply, divide" four methods. As shown in the following:


The system then automatically generates a new class Calculatortest, which contains some empty test cases. You only need to make these test cases slightly modified to use. The complete calculatortest code is as follows:

package andycpp; import static Org.junit.assert.*;import Org.junit.before;import Org.junit.ignore;import org.junit.Test; public class calculatortest ...       {private static Calculator Calculator = new Calculator ();    @Before public void SetUp () throws Exception {calculator.clear ();        } @Test public void Testadd () {calculator.add (2);        Calculator.add (3);    Assertequals (5, Calculator.getresult ());        } @Test public void Testsubstract () {calculator.add (10);        Calculator.substract (2);    Assertequals (8, Calculator.getresult ()); } @Ignore ("Multiply () yet implemented") @Test public void Testmultiply () {} @Test public void tes        Tdivide () {Calculator.add (8);        Calculator.divide (2);    Assertequals (4, Calculator.getresult ()); }}
Fourth step, run the test code: After modifying the code as described above, we right-click on the Calculatortest class and select "Run Asàjunit Test" to run our test as shown in:


The results of the operation are as follows:

The progress bar is red color indicates found error, the specific test results on the progress bar indicates "a total of 4 tests, of which 1 tests were ignored, a test failed"

At this point, we have fully experienced the methods of using JUnit in Eclipse. In the next article, I'll explain in detail every detail in the test code!

unit Testing with JUNIT4 in Eclipse (intermediate)

We continue to analyze the examples in the primary article. In the introductory chapter we use Eclipse to automatically generate a test framework, in this article, we will carefully analyze the test framework of each of the details, know it more to know why, in order to become more proficient in the application of JUNIT4.

A. Contains the necessary package

The JUNIT4 framework is used in the test class, and the package is naturally included in the corresponding package. One of the most important package is org.junit.*. After it is included, most of the features are there. There is also a word that is very important "import static org.junit.assert.*;", we use a series of assertequals methods when testing from this package. Note that this is a static inclusion (static), which is a new feature added in JDK5. In other words, Assertequals is a series of static methods in an Assert class, and is generally used in an assert manner. Assertequals (), but with static inclusion, the preceding class name can be omitted and used more conveniently.

II. Declaration of the Test class

It is noted that our test class is a separate class, without any parent class. The name of the test class can also be arbitrarily named, without any limitations. So we cannot tell by the declaration of a class that it is not a test class, but that it differs from the ordinary class in its declaration of methods inside it, which we will then talk about.

Third, create an object to be tested.

Which class you want to test, you'll first create an object of that class. As the code in the previous article:

private static Calculator Calculator = new Calculator ();

In order to test the calculator class, we must create a calculator object.

Iv. Declaration of test methods

In a test class, not every method is used for testing, and you must use "callout" to clearly indicate which is the test method. "Labeling" is also a new feature of JDK5, which is very appropriate here. As we can see, there are @before, @Test, @Ignore and so on before some methods, and these are the annotations, which begin with an "@". These annotations are JUNIT4 customized and it is important to master the meaning of these annotations.

Five, write a simple test method.

First, you will use the @test callout in front of the method to indicate that this is a test method. The declaration of a method has the following requirements: The name can be arbitrarily taken without any restrictions, but the return value must be void and cannot have any arguments. If these rules are violated, an exception is thrown at run time. As for what to write in the method, it depends on what you need to test. Like what:

    @Test public    void Testadd () {          calculator.add (2);           Calculator.add (3);           Assertequals (5, Calculator.getresult ());    }

We want to test the "addition" function when the correct, in the test method called several times the Add function, the initial value of 0, plus 2, plus 3, we expect the result should be 5. If the final actual result is also 5, then the Add method is correct, and the reverse means it is wrong. Assertequals (5, Calculator.getresult ()); Is to determine whether the expected results and actual results are equal, the first parameter fills in the expected result, the second parameter fills in the actual result, that is, the results obtained by the calculation. When this is done, JUnit automatically tests and feeds the test results back to the user.

VI. Ignore testing some of the unfinished methods.

If you do a good job planning before you write the program, then what is the function should be fixed. Therefore, even if the method is not yet complete, his specific functionality is deterministic, which means that you can write test cases for him. However, if you have finished writing the test case for the method, but the method is not yet complete, then the test must be "failed". This failure is different from real failure, so JUnit provides a way to differentiate them by adding a @ignore callout to the test function, meaning that "some methods have not been completed and are not currently participating in the test." In this case, the test results will prompt you to have several tests ignored, not failures. Once you have completed the corresponding function, just delete the @ignore annotation and you can perform the normal test.

Vii. Fixture (translated as "fixed code snippet")

The meaning of fixture is "code that must be called at certain stages". For example, the above test, because only a calculator object is declared, his initial value is 0, but after testing the addition operation, his value is not 0, and then test the subtraction operation, it is necessary to consider the results of the last addition operation. This is definitely a very bad design! We very much hope that each test is independent and that there is no coupling between each other. Therefore, it is necessary for us to perform a "undo" operation on the Calculator object before executing each test to eliminate the impact of other tests. Therefore, "code that must be executed before any test execution" is a fixture, and we use @before to label it as shown in the previous example:

      @Before public      void SetUp () throws Exception {           calculator.clear ();      }

There is no need for @test labeling here, because this is not a test, but a fixture. Similarly, if the "finishing touches required after any test execution" is also a fixture, use @after to annotate. Because this example is relatively simple, this function is not used.

unit Testing with JUNIT4 in Eclipse (Advanced)

First, advanced fixture

In the previous article we introduced two fixture annotations, namely @before and @after, to see if they are suitable for the following functions: one class is responsible for reading and writing large files (more than 500 megabytes), and each of his methods is manipulating the files. In other words, before invoking each method, we have to open a large file and read the contents of the file, which is definitely a time-consuming operation. If we use @before and @after, then each test will have to read the file once, efficiency and low. What we want here is to read the file at the start of all tests, release the file after all the tests are finished, and not read the file every time. The JUnit authors clearly consider this issue, which gives @beforeclass and @AfterClass two fixture to help us achieve this function. As can be seen from the name, using the functions labeled in these two fixture, only the @beforeclass method is executed when the test case is initialized, and after all the tests have been executed, the @afterclass is performed to finish the work. Note here that only one method per test class can be labeled as @beforeclass or @AfterClass, and that the method must be public and static.

Second, time-limited testing.

Remember the example I gave in my introductory article, the function that squared root has a bug, is a dead loop:

public void SquareRoot (int n) {for        (;;);                 Bug: Dead Loop    }

If you encounter a dead loop during testing, you will never smile on your face. Therefore, for those whose logic is very complex, the loop nesting is relatively deep, there is a possibility of a dead loop, so it is necessary to take some precautions. Time-limited testing is a good solution. We set an execution time for these test functions, more than that, they will be forcibly terminated by the system, and the system will report to you the reason for the end of the function is because of the timeout, so you can find these bugs. To do this, you only need to add a parameter to the @test callout, and the code is as follows:

@Test (timeout = +) public void SquareRoot () {        calculator.squareroot (4);        Assertequals (2, Calculator.getresult ());}

The timeout parameter indicates the time you want to set, in milliseconds, so 1000 represents 1 seconds.

Third, test the exception

Exception handling in Java is also a priority, so you will often write some functions that need to throw exceptions. So, if you think a function should throw an exception, but it's not thrown, does that count as a bug? This is certainly a bug, and JUnit has taken this into account to help us find this bug. For example, we write the Calculator class has the division function, if the divisor is a 0, then must throw "except 0 exception". Therefore, it is necessary for us to test these. The code is as follows:

@Test (expected = arithmeticexception.class) public  void DivideByZero () {calculator.divide (0);   }

As shown in the code above, we need to use the expected property of the @test callout to pass the exception we want to test to him so that the JUnit framework will automatically help us detect if the exception we specified is thrown.

Four, Runner (running device)

Have you ever thought about this question, how does the framework run your code when you submit the test code to the JUnit framework? The answer is--runner. There are many runner in JUnit, they are responsible for invoking your test code, each runner has its own special features, and you need to choose different runner to run your test code as needed. Perhaps you will find it strange that we have written so many tests before, and have not explicitly specified a runner ah? This is because there is a default runner in JUnit, and if you do not specify it, the system automatically uses the default runner to run your code. In other words, the following two paragraphs of code mean exactly the same:

Import Org.junit.internal.runners.testclassrunner;import Org.junit.runner.RunWith; The system default Testclassrunner is used, exactly the same as the following code public class Calculatortest {}  @RunWith (testclassrunner.class) public class Calculatortest {}

As you can see from the above example, to specify a runner, you need to use the @runwith callout and pass the runner you specify as a parameter to it. Another thing to note is that the @RunWith is used to modify the class, not to modify the function. All functions in this class are called by this runner whenever a runner is specified for a class. Finally, do not forget to include the appropriate package, the above example is very clear. Next, I'll show you the unique features of other runner.

Five, parametric test.

You may have encountered such a function, its parameters have many special values, or his parameters are divided into a number of areas. For example, a function to evaluate test scores, the return value is "good, good, general, pass, fail", so you write the test, at least to write 5 tests, the 5 is included in the situation, this is really a very troublesome thing. We also use our previous example to test the "calculate the square of a number" this function, for the moment divided into three categories: positive, 0, negative. The test code is as follows:

Import Org.junit.afterclass;import org.junit.before;import Org.junit.beforeclass;import Org.junit.Test;import Static org.junit.assert.*; public class Advancedtest {private static Calculator Calculator = new Calculator ();    @Beforepublic void Clearcalculator () {        calculator.clear ();}     @Testpublic void Square1 () {        calculator.square (2);        Assertequals (4, Calculator.getresult ());}     @Test public   void Square2 () {        calculator.square (0);        Assertequals (0, Calculator.getresult ());}    @Test public   void Square3 () {        calculator.square ( -3);        Assertequals (9, Calculator.getresult ());} }

to simplify a similar test, JUNIT4 puts forward the concept of "parametric testing", writing only one test function, passing in several cases as parameters, and testing them once. The code is as follows:
Import static Org.junit.assert.assertequals;import Org.junit.test;import Org.junit.runner.runwith;import Org.junit.runners.parameterized;import Org.junit.runners.parameterized.parameters;import Java.util.Arrays;import Java.util.Collection; @RunWith (parameterized.class) public class squaretest ... {    private static Calculator Calculator = new Calculator ();p rivate int param;private int result;     @Parameters public   static Collection data () {        return arrays.aslist (new object[][]{                {2, 4},                {0, 0},                { -3, 9},        });} constructor, initializes the variable to public squaretest (int param, int result) {        this.param = param;            This.result = result;} @Test public   void Square () {        calculator.square (param);        Assertequals (result, Calculator.getresult ());    } }

Below we analyze the above code. First, you want to create a new class for this kind of test instead of sharing the same class with other tests, in which case we define a squaretest class. Then, you want to specify a runner for this class, but not the default runner, because special functions need to use special runner. @RunWith (Parameterized.class) This statement specifies a parameterizedrunner for this class. The second step is to define a class to be tested and define two variables, one for storing parameters and one for storing the expected results. Next, define a collection of test data, the data () method described above, which can be arbitrarily named, but must be decorated with @parameters annotations. The framework of this method will not explain, you just need to pay attention to the data, is a two-dimensional array, data 221 groups, each group of the two data, one is the parameter, one is the result you expect. For example, our first set of {2, 4},2 is the parameter, and 4 is the expected result. The order of the two data does not matter, who before who can. The constructor is followed by the function of initializing the two parameters previously defined. Here you have to pay attention to the order of the parameters, consistent with the order of the data set above. If the previous order is {parameter, expected result}, then the order of your constructor is also "constructor (parameter, expected result)" and vice versa. The last is to write a simple test example, and the previous introduction of the same wording, not much to say here.

Six, packaging testing.

From the previous introduction we can feel that in a project, it is impossible to write only one Test class, we will write many many test classes. But these test classes have to be executed one by one, and it's a bit of a hassle. With this in mind, JUnit provides us with the ability to package tests, centralize all the test classes that need to be run, and run them all at once, greatly facilitating our testing efforts. The specific code is as follows:

Import Org.junit.runner.runwith;import org.junit.runners.Suite; @RunWith (Suite.class) @Suite. suiteclasses ({calculatortest.class, squaretest.class}) public class Allcalculatortests {}

as you can see, this feature also needs to use a special runner, so we need to pass a parameter suite.class to the @runwith callout. At the same time, we need another callout @suite.suiteclasses to show that this class is a packaged test class. We pass the class that needs to be packaged as a parameter to the callout. With these two annotations, all of the meanings have been fully expressed, so the following classes are irrelevant, with a class name, and the contents are all empty.


Source: http://www.cnblogs.com/eggbucket/archive/2012/02/02/2335697.html

Unit testing with JUNIT4 in eclipse

Related Article

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.