Testing logging to log files

Recommended reading before you read this article: Mockito basics

How do we test logging to logs?

We should not do that in general. The solution might be to test if notifications are being sent to support or diagnostic teams though. The implementation of those notifications might go to logs. For example:

A sample implementation of SupportTeam interface might look like this:

The examples above hide logging behind a SupportTeam interface. This seems to be a good modelling example of the real world scenarios. Who looks at the production logs in the real world? Support team in most cases. Then we should notify support team when exception occurs instead of logging to logs. The implementation of SupportTeam interface can log to logs though. Modelling the real world scenarios is in my opinion one of the key OO principles that people often forget about.

Please comment!

[Removing duplication in tests] (Part 1) Move wiring of objects to class attributes

Recommended reading before you read this article: Mockito basics

Hot to get rid of duplicated code in tests

When we have multiple tests and all of them have similar givens we are tempted to extract those common givens to setup method or the field declarations. This might be a good idea when those givens are just wiring of dependencies. In most other cases it might be not a good idea.
Below I include an example for correct removing duplication of “givens” for multiple tests. Moving wiring of objects in field declarations. This way we do not test the wiring in the test, just the business functionality. The wiring should be tested in acceptance or end to end tests, not on unit level.

The example below also replaces string constants with variable names. For example in the tests we don’t care that the username is “john”. We only care that the username passed around is the same object. So we can move the definition of username out of the test to increase readability.

Please note that all fields are marked as final. This ensures that all wiring was done before we start testing the user object.

Before refactor

After refactor

I have not found any other scenarios for removing duplication in tests by moving common code into set up methods or class attributes. All other scenarios where duplication occurs pointed to problems in production code and design issues. Please take a look at all other parts for further details (coming soon).

Please comment! 🙂

Testing time dependant functionalities

Recommended reading before you read this article: Mockito basics, Fest assertions.

How do we test time dependent operations?

Let us assume we have a report and it may me marked as complete. When it is marked as complete the “completed on” date should be set. The easiest approach would be to do a “new Date()” and assign it to “completed on” attribute.

But how do we test it? We have to take an other approach.
The solution is to introduce a Clock object that can be asked for the current time and which we will be able to mock in tests:

Recommended further reading: How NOT to test drive time dependant functionalities

The ultimate test template

Recommended reading before you read this article: Mockito basics, Fest assertions.

When doing OOP we create objects. While doing TDD we should focus on relationships between those objects. That being said, one of the main principles that we should focus on is “Tell Don’t Ask”. We tell object “do this thing” and expect a certain result. This leads us to the “ultimate test template”, a test should have 3 parts: inputs for the tested object, call on the object and then asserting for the expected results, for example:

This is a very basic example just to illustrate the 3 parts of the test. The input is that the User object was supplied with an observer. The output is that if user changed password is that the observer was notified. (This example uses Mockito mocks to create a mock object and then verify if a method was called on it).

You might notice the comments //given //when // then. At the beginning I added them each time I was staring a new test, but after a while I realised that this just adds noise. When you know that each test will have those 3 parts I would skip the comments.

Sometimes the first or third parts may be skipped of course. For example we may skip the first part (the givens are in the same line as the call for readibility):

Or we can skip the first and last part. The third part is moved to the annotation parameters:

InteliJ IDEA users

You might add a live template to your IDE. Go to File->Settings->Live Templates.
Add the listing below to “plain” category. The abbreviation should be “test”.
Do not forget to check “Context -> Java Code”.

Now when you type “test” and pres TAB in a java file the test template will appear.

Starting test names with “itShould” or “should”

Recommended reading before you read this article: Mockito basics, Fest assertions.

Sometimes you might find some people applying a convention of starting test names with a prefix such as “itShould” or “should”, for example:

I used to do it, but now I find it useless. It is unnecessary noise for me. The test name listed below still reads like a sentence (is readable) and has no unnecessary additions.

What do you think?

Pros and cons of TDD

Why do TDD?

  • if you are starting your journey with software development it might be a good path to follow
  • TDD is an effective way of discovering relationships between objects while doing OOP
  • tests document the code
  • it is easier to spot errors and code smells in production code when we have good tests, one just has to seek for simple patterns in the tests
  • there is an increasing need for TDD skills in IT market
  • do it for fun, experience new approach to software development
  • any other ideas? 🙂

When it might not be the best idea?

  • prototyping
  • example: project runs for 3 months and then goes to production only for one month, we might then test only the critical paths through the system
  • sometimes there is no business value in TDD, for example you do a project on you own and you are a very experienced developer, then you might test only the critical paths of the application
  • very little time to release the product, but willing to pay the technical debt and intrest for the technical debt in the future
  • any other ideas? 🙂

Don’t write tests for production code, write production code for tests

Always start with a test

Focus on what you want to your production code to do and then express it by a test scenario. When the test case fails add or change some production code. When the test case gets green do some refactoring if you think there is a need. Then choose the next scenario you want to implement and start the process again.

In the beginning commit to this rule blindly. It will pay in the future.

There might be several exceptions to this rule such as prototyping for example. Remember that prototype should not become production code in most cases. If you prototype you should delete the code as soon as the prototype is ready unless you feel that you are willing to commit to pay the technical debt and the interest for the technical debt along the way.
For me prototyping is most often getting to know how third party APIs work. But in that case I also often just write tests for the third party API and then I am sure I know how it works.
But, since you are new to TDD this was just an example for you when TDD might not be the best way. You, keep doing TDD! 🙂

Any comments? Please comment! 🙂

Recommended idea for today:

http://coderetreat.com/how-it-works.html

Recommended book for today:

Clean Code: A Handbook of Agile Software Craftsmanship

TDD best practices, tips and many more. New blog started!

Practice, practice, practice: from now on always start with test

Admit it. You don’t do TDD because you don’t know how.

This blog is about TDD for a developer who wants to start doing TDD. I assume that you are a developer with experience. I assume you have the basic knowledge of what TDD might be. I assume you are thinking of trying out TDD. That was my situation about 2 years ago. I was looking for a set of TDD best practices but found none. That is why I decided to write something that might get you faster to the point that I am in right now so that we can continue this journey together.

I am a Java developer. I have been one for over 4 years now. I work on fairly large applications. I am still on my journey of discovering the best practices I should follow.  Fortunately I met many good souls on the way and I am now confident that I can start calling myself a TDD developer. Now I know that TDD is not only about good code quality. It is a style of work, influences the whole process and at the end you are enjoying your work a lot more then you used to. Less frustration, less problems, less hassle.  There are many cases where TDD might not be a good idea, but in most cases it is fortunately.

I know some developers that don’t do TDD because they have been doing development for more then 10 or 20 years. They are very skilled and mostly work on their own, not in teams. This is one of the cases when this blog might not be that much useful.

Most of the code examples presented here will be in Java. The topics are not ordered in any way, I write what comes to my mind.

Can you help me?

My purpose in starting this blog is also self-education. I consider myself as a mid-level developer thus I seek feedback on my ideas all the time. I hope to enjoy discussions with you about the subjects that I will work on.

TDD is a skill one has to learn

I will not try to make you a TDD developer. But I will always advise just to try. Think of the new technologies you use sometimes. Once upon a time I tried using Ruby On Rails since it was said to be a fast way of getting an idea into production. It worked. Then I tried TDD, I wanted to enjoy my work even more. It worked. Now I work in a XP team, do TDD and pair programming on daily basis and enjoy the work and the salary 😉 It might be the same for you! Give it a try and see what happens.

TDD in legacy code

I would advise trying TDD on a new project. Doing TDD on legacy code that was not driven by tests from the beginning might lead to frustration when one lacks the knowledge of the common patterns that can be applied. On the other hand I did it with help of my fiends and it worked so I guess the decision is up to you.

Practice, practice, practice

Commit to practice each day. It worked for me. I had to deal with many obstacles along the way (legacy code not driven by tests, large team not willing to try TDD, …) but it was worth it.
Also, couple of the coolest things I learned came up during my own experiments at home with self-assigned programming exercises. Try to think of a problem and find a solution doing TDD!

Recommended video for today:

http://www.youtube.com/watch?v=XcT4yYu_TTs

Recommended book for today: (may be a bit out of date, but still a classic):

Test Driven Development: By Example