JAVA Unit Test: Why they can “save” our life?

The Unit Test cases raise the quality of your final product and then you will raise the quality of your reputation

Advertisements

In the last weeks I was working on a JAVA legacy system that needs to add some new features. The contract with the client included a clause that said “the new release should raise the Test Coverage until 70% of the code”.
We discussed about this with my team and several members proposed not “lose” development time in this task and test only the “the happy path” and some simple cases to achieve these value.

After 15 year in IT area I still feel a little heart attack when I hear that. So I took a breath and explained them about the importance to create (always) the proper Unit Test for each line of code that we wrote, write and will write.

Now, I share with you some points and ideas from that discussion. I hope they can help you… and save your life too 🙂

Some Advantages:

  • Automates the test process at the build time (for example when you run the mvn install command) for everyone who works in the project instead run isolated manual tests (that can add human errors or subjective test cases)
  • Makes your code and the application behavior predictable
  • If you did undesired changes (or temporary changes and forgot them) a good Unit Test will fail at the build time as a check-point alarm
  • Helps to find bugs or unexpected behaviors early before QC/QA time: this could help us to save time and a lot of money
  • Helps to avoid the “gold plating” (add unnecessary features)

Some Tips for our development process:

  • For each development task add and estimate the Unit Test write process as an extra task
  • Remember that develop Unit Test cases takes about of 50%-80% of the time estimated for the development tasks (if you estimate 8 hours to write a new feature class probably create the proper Unit Test cases for it take you about 5 or 6 hours)
  • Never subestimate the necessary time to write the Unit Tests
  • Explain to client the importance to create a good Unit Test cases
  • Create the Unit Test cases for each code that you made as a “life routine” (independently of the requirements of the client)
  • If you can use TDD techniques everytime and everywhere (for example, when you write “new” code)
  • Test the happy path, of course, but also write Unit Test cases for all your code: expected behaviors, rare business logic cases, error handling, etc.
  • Check not only the line coverage, verify that all the code branches have the proper Unit Test for each expected behavior: if you receive the user name as String parameter you have to test the behavior of these value when it is valid, non valid, numeric, null, empty, blank, etc. Or if you have an if block with a true-false condition, test the true path but also the false path.
  • Remove the unnecessary code or features
  • Everytime run the cobertura plugin in your IDE (like Eclipse or IntelliJ) or the Maven plugin (mvn cobertura:cobertura) and check the line coverage but also the branch coverage
  • Do the Unit Test more effective with Mock frameworks like Mockito, PowerMock or EasyMock
  • All the Unit Test cases should be documented and should include the scenario to test and the expected result (you can add it to the method’s Javadoc)

Here is a little example about how a Unit Test can work as check-point when we did undesired changes like modify a SQL query for develop purpose and forgot undo the changes.
In this case the developer forgot remove the “DEV” suffix from the table name:

@Repository("SecureDAO")
public class ExampleSecureDAOImpl implements ExampleDAO {

	private static final Logger LOGGER = LoggerFactory.getLogger(ExampleSecureDAOImpl.class);
	
	final static String QUERY_FIND_ALL_SECURE = " SELECT ID, NAME, USER, PASSWORD FROM USERS_DEV WHERE USER = ?";
	
	@Autowired
	DataSource dataSource;
...
}

Instead use “anyString” feature for the query, in the Unit Test case we include (and test) the real query statement:

@RunWith(SpringRunner.class)
public class ExampleSecureDAOImplTest {
	
	// include the query because if you change the query accidentally the test case will fail (it's a good checkpoint)
	final static String QUERY_FIND_ALL_SECURE = " SELECT ID, NAME, USER, PASSWORD FROM USERS WHERE USER = ?";
...
}	

So the Unit Test case will fail because the queries are different… and that’s a good check-point:

Results :

Tests in error:
  ExampleSecureDAOImplTest.findUserInfoByUserWithValidArgumentsShouldReturnAListWithUserInfo:84 ▒ NullPointer

Tests run: 15, Failures: 0, Errors: 1, Skipped: 0

Final notes
I think you should write the Unit Test cases not for the client or to achieve a project requirement. The Unit Test cases are for you and your team. Include and document them as part of your development routine is very important to improve the quality of your code (and the quality of your job) and is a good way to reduce the possibility of bugs and undesired behaviors. Also, a good Unit Test plan could help you to save a lot time (and money) in the future.

And the most important thing: if you raise the quality of your final product you will raise the quality of your reputation!

If you know a better solution for one or more cases or you want to share your best practices with us, please, let me know and I will update this post 🙂

You can visit my public GitHub repository:
https://github.com/Gabotto/

Let me know if you have any problem, comment or new ideas:
WordPress: https://gabelopment.wordpress.com/
Email: gabelopment@gmail.com

Also you can find me at Upwork

See you soon with more development notes…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s