loading...

The seven rules for continuous UnitTest

koduki profile image koduki ・3 min read

Introduction

Do you write UnitTest on your project? Are UnitTests ran every time?

I completely thought it's same thing to write UnitTest and write "continuous" UnitTest.
But it is difference.

Almost engineer know UnitTest is important. So they write UnitTest.
But I saw such a UnitTest is abolish again and again.
Why? Because they are very slow, they are difficult to maintenance, and they are broken.

Continuous UnitTest needs to meet some requirements.
You can satisify this requireents by the following rules.

  • Run always
  • Keep portability
  • Keep repeatability
  • Avoid slow tests like a RDB, emulation, and so on
  • Don't use your eyes
  • One UnitTest, One point of view for a test
  • Use readable name

In this article, I explain about these rules.
I explain based on Java, Maven, JUnit. But You can apply to other languages.

The seven rules

Run always

This rule is the most important.
You should run UnitTest every time, when you build your code.

Don't use -Dmaven.test.skip=true!! Please...

If you can always run all unit tests, they are Continuous UnitTest code.
But if you can't do it, you need modify it.

Keep portability

Portability is important.
Unit Test isn't only ran on you PC, but also is ran on other environment.
Other environment is coworker's PC, CI environment and future your PC.

For portability, you need to only use under your project directory.
You shouldn't use /var/foobar and D:\foobar as test data directory and so on.
Please use under target directory or src/test/resources/.

Keep repeatability

Portability is important for run always.
Your code should be ran without any manual operations like a removing test data and so on.

In generally, such a initialize or cleanup code should be ran on setUp or tearDown.

Avoid slow tests like a RDB, emulation, and so on

You should avoid slow test like a RDB test and using emulator.
Such a test is very useful. You should do it. However it's integration test.

JUnit also support integration test.
You can use real DB by DBUnit. You can use arquillian. Today, you can use even Docker.

I love it. But these test is slow.
If tests are slow, you will not run all UnitTest every time.

So, you should separate such a test as Slow Test.
I recommend make a slow-test profile or use maven's integration-test phase.
And you can ran it when build on CI environment or before commit.

Don't use your eyes

Don't use your eyes for UnitTest!

UnitTest should check assertion automatically.
You shouldn't use your eyes to check logs, standard out, file output and so on.
Please use assertThat, assertEquals and so on. It's JUnit's role.

Maybe following article helps you.
How do you write "Production Code" for UnitTest?

One UnitTest, One UnitTest, One point of view for a test

Each test should be check only one point of view.
If there are many points of view for a test case, it's difficult to check which test is failed.

This is not manual tests. You don't need to decrease test operation cost.
You can make a test case for only one point of view.

Please avoid only one test case per method.

Use readable name

Please use readable name.
You should avoid like a test001, test002, test003...
Because anyone can't understand a expectation of its method.

Naming is important as well as production code.

Maybe BDD style helps you a lot.
You should use method name, condition and expectation as test name.

Summary

I think almost rule is not difficult.
Maybe many people think almost rules are very natural.
You may even think it is unnecessary as it is common sense.

But it's important to be clearly rules.

Especially, many people don't separate UnitTest and IntegrationTest.
JUnit tests are managed as just JUnit tests. It's not good.

I believe simple rules support smooth communication!

Happy hacking!

Discussion

markdown guide