start

Nowadays, large companies pay more and more attention to the unit test of the project, and even explicitly require the unit test coverage of the project can not be lower than a certain value, so the importance of unit test can be seen.

Imagine if there were no unit tests, how would you make sure your code worked?

What testers do is business integration testing, that is, black box testing, and there is no way to test a single method. Moreover, the range of bugs tested will be very wide, and it is impossible to determine the scope of the bug and have to spend time to determine where the bug is.

Also, one of the most common questions: Is writing a single test a waste of time? Have you ever calculated how long it takes you to fix a bug (location + fix)? If you do, you’ll find that you’re wasting even more time.

advice

Here are a few tips for writing good unit tests:

1. Test data externalization

Test data can be roughly divided into two types: variable and unchanged. For unchanged test data, we can either write it in the unit test case code or externalize the data.

However, when the test data is changing all the time and the amount of test data is relatively large, test data externalization can be used to put the data outside the test case for unified management.

What is data externalization? For example, we can unify the test data from a unit test case into a CSV file.

We can specify the CSV file with the @parameterizedTest annotation as a parameter test in junit5 and the @Csvfilesource annotation that introduces the CVS file and specifies the resources attribute in it. The numLinesToSkip = n property specifies to start at line n+1. This allows unified management of data in a single unit test case through a CSV file.

All we need to manage the data in our test cases is a single CSV file.

Here’s an example :(see the junit5 blog series parameterized testing for details)

@ParameterizedTest
@CsvFileSource(resources = "/two-column.csv", numLinesToSkip = 1)
void testWithCsvFileSource(String first, int second) {
    assertNotNull(first);
    assertNotEquals(0, second);
}
Copy the code

In the command, two-column. CSV contains the content of the file

Country, reference
Sweden, 1
Poland, 2
"United States of America", 3
Copy the code
2. Build tests with specific results
  • If the results are random, such methods are almost impossible to test, so there is no way to test them.
  • We can only test methods that produce specific results based on unique data.
3. Comprehensive testing, each aspect of the design must have a test case:
  • Positive all scenarios
  • Negative all scenarios
  • The critical value
  • Special values
4. Keep test cases simple and brief

Keep your code as clean as possible to test it, not only to make it look better, but also to maintain and understand it. Which would you rather see, a bunch of code or a few lines of code?

5. Test cases as quickly as possible

For unit test cases, almost every time we develop a method or modify a method, we will run the test case to make sure that it does not affect the normal operation of other modules, so we try to make your test method “fast!” To remove code that is not related to unit tests. Of course, the premise is to ensure the integrity and correctness of the test.

6. Every time you run a unit test, make sure it’s 100% successful!

This is relatively simple, but it can be difficult to do because your test cases can fail for a variety of reasons, such as data expiration, changes in method internal logic, and so on.

These may take some time to correct, and you may not want to, but if you do something, do it well

But if you don’t pay attention to these small mistakes, it can lead to a big process failure. You should know that when we run a process, a small mistake can lead to a process failure!

7. Design your tests

This includes a wide range of aspects, the following aspects I think we should pay attention to:

  • The code described above is as simple as possible while maintaining quality
  • Code abstraction is also possible in unit testing, and some reusable code can be abstracted to improve code reuse and reduce code duplication.
  • Give your test class test method a good name. A Test class is usually a suffix of class name +Test, which can indicate which class is tested. Test methods are similarly “Test method name +Test suffix” or “Test method name +Test part effect +Test suffix” for partial tests of a method.
  • Each test method should not have too many functional assertions for the method being tested. If a method needs more than one assertion to be tested, we can roughly classify it into less than two test methods, so that the test can be fine grained.
8. Pay attention to test code coverage

A well-designed unit test also has high code test coverage. 100% test code coverage is not required, but code with high coverage is less likely to contain undetected errors because more of its source code is executed during testing.

Note: High code coverage does not guarantee perfect tests, so be careful!

9. There are some other points to pay attention to, such as
  • Do not use print statements to print test results manually to determine whether they are correct, use assertions
  • Some tests that are not easy to understand had better be annotated above the method for later understanding and maintenance
  • Use frameworks for unit testing, such as Junit5 or ASsertJ to enrich assertions if the assertion support doesn’t meet your needs, Mockito to Mock data, etc

Ok, so that’s some advice on how to write good unit tests. If not, please point it out in the comments section. Thank you!

Next, I will write about how to set up unit tests, the new syntax of junit5, and unit tests based on graph databases

The official website of blogs