I remember my generation and how we were having trouble with understanding Test Driven Development (Design). First it came like TFD (Test First Development) which you were writing your tests before going into any code. But then this doesn’t fit into practical world. And TDD came into our world. Right now in turns into TED (Test Enhanced Design). Hehe.. Anyway, I just want to share my experience with all these. If you’re just starting this technique, you might find it a little bit hard to identify what/how many and when you should use this technique. And maybe more interesting, what is all about? what is unit test, what is integration test, what is functional test, what is acceptance test, etc.
In this first post, I wanna more focus on Unit Tests.
What is Unit Test
You might try looking wikipedia, however I’d like to define it myself. A unit test is your unit (source code) validator. Ideally you’d have at least one unit test for each unit which covers each of your unit’s functionality.
Do You Know WHAT and HOW MANY Unit Tests to Write
In an ideal Test Driven Development scenario, developers generally tend to target 100% test coverage. However, in real world this number is pretty much impossible to reach. Because we have a lot of factors that interferes the TDD process. Most of the time developers end up with 50-80% of test coverage.
First of all we should remember that we’re creating Unit tests to validate and assert that public and protected methods (we pass private methods since they’re most likely to be refactored code segments, then again every refactored code snippet should be tested too) of a class meet the expectations based on varying input. This includes good/bad data testing, exception handling, edge or fragile values, and of course outcome satisfaction. For more information on this, please refer to Pragmatic Unit Testing.
Example
It’s very hard for me to give a very big code here. So I’ll pick a simple test story. However, most of the time developers get confused after these basic approaches. Because there are much more technical details (what to test/when/where) above these basic line. Anyway, if you have any questions, please feel free to drop a comment.
In our example we’ll have a Number Divider and we’ll create a test for that. First step into application will be understanding all the requirements.
A Number Divider will do: - Divide two given numbers - Cannot divide by 0 - If any number has a sign, it should be taken into account
Let’s assume, these are our business requirements. You can create hell more, I don’t care. For this example, I’m gonna create only these requirements. And please guys, don’t do the common mistake by getting lost in test cases! That’s why this initial step is so important.
Okay, let’s test if our ND can divide two given numbers:
NumberDivider numberDivider;
@Before
public void initialize() {
numberDivider = NumberDivider.getInstance();
}
@Test
public testDivisionOfGoodInput() {
assertEquals(3d, numberDivider.divide(12, 4));
assertEquals(5d, numberDivider.divide(15, 3));
assertEquals(0.5d, numberDivider.divide(2, 4));
}
}
So now we know that we need these outcome from our Number Divider. Let’s try to code our super duper Number Divider:
private static NumberDivider instance;
private NumberDivider() { }
public static NumberDivider getInstance() {
if (instance == null) {
instance = new NumberDivider();
}
return instance;
}
public double divide(int number1, int number2) {
return (double) number1 / number2;
}
}
Now if you run the test case, you’ll see that all assertions are true. So we’re done right? Of course not. We didn’t finish the requirements. We need to check division by 0 and signs. So we need more test cases for them:
NumberDivider numberDivider;
@Before
public void initialize() {
numberDivider = NumberDivider.getInstance();
}
@Test
public testDivisionOfGoodInput() {
assertEquals(3d, numberDivider.divide(12, 4));
assertEquals(5d, numberDivider.divide(15, 3));
assertEquals(0.5d, numberDivider.divide(2, 4));
}
@Test(expected=ArithmeticException.class)
public testDivisionByZero() {
numberDivider.divide(2, 0);
}
@Test
public testDivisionOfNegativeValues() {
assertEquals(-2d, numberDivider.divide(4, -2));
assertEquals(-5d, numberDivider.divide(-15, 3));
assertEquals(3d, numberDivider.divide(-9, -3));
}
}
And if you run the test case now, you’ll get an error for division by zero test since we didn’t throw any exception if there is a division by zero. Let’s add that part too:
private static NumberDivider instance;
private NumberDivider() { }
public static NumberDivider getInstance() {
if (instance == null) {
instance = new NumberDivider();
}
return instance;
}
public double divide(int number1, int number2) throws AritmeticException {
if (number2 == 0) {
throw new AritmeticException("Division by zero error!");
}
return (double) number1 / number2;
}
}
Now if you run the test again, you’ll pass everything. So we’re done? Actually no. But since we’re gonna keep this simple now, we’re gonna finish it here. I just wanna summarize couple more things here about WHAT/HOW MANY/WHEN to test part. You might argue with these, but these are my experiences so far:
- Dependencies – e.g. Database Schema, Datasets, Web Services, I/O etc. Please don’t confuse things with Integration tests. Here we’re mocking everything and just testing the unit. Not the SYSTEM!
- Fragile Code – e.g. Regular Expressions, data conversions, etc
- When errors can be difficult to spot – e.g. Rounding, arithmetic, calculations, etc
- Performance – e.g. Slow forms, Time critical applications
When not to test:
- For Private methods if it is just refactoring or maintance
- When unit tests start to test integrational units, please don’t do this, don’t get lost in tests!
- When unit tests become bigger than the original function, actually I’m planning to cover refactoring as a different article. Because this is most likely goes under that topic too
- When code has been generated from Code Generators
I hope this would be helpful. Anyway, I’ll try to continue this article sometime soon. I’ll try to cover 10 important tips about unit tests. This was the first tip. When/What/How many questions before starting unit tests. Okaaay.. Ciao for now :)









