This is the final post of my Things a developer should know to practice TDD seriese
TDD does not promise to good design. TDD is not a replacement for user acceptance testing, automated, load, concurrency, or anything else that you might put under the category of “smoke” or “stress” testing. TDD is not about testing only, it’s about development. Moreover, TDD is not magic you need to look for code smells and refactor for better designs
Few Code smells are easy to identify.
- Duplicated code
- Conditional Complexity
- Large Class
- Long Methods
- Long Parameter List: if more than 3
- Middle Man
- Parallel Inheritance Hierarchies
- Shotgun Surgery: Change in one class requires cascading changes in several related classes
Test smells help identifying bad design as well.
- Long arrange to test a single unit
- Difficult to write test
- Code changes break unrelated tests
A test code base should be well designed. Otherwise, maintaining test base will be cumbersome. Unit tests should be refactored to better design
- A test has many dependencies
- One change to production code requires changes on many tests
- More than one assertions in many tests
- Changes in production code lead break unrelated tests
Listen to your test suits it may tell you the story about your production code. Read more about tests
The following few principles are really handy. All these help to build loosely coupled, high cohesive, maintainable and agile system.
- Separation of concerns
- Hollywood Principle – Don’t Call Us, We’ll Call You!
But I want to mention three principles that always assist me to take the design decision more often than others, not only for production code also for tests. And they are Single Responsibility Principle, Dependency Inversion Principle and Don’t Repeat Yourself (DRY)
TDD using a set of design principles helps to achieve higher quality code. A StackExchange thread mentions an idea about how to chose a design pattern.
Any pattern that causes side effects or persists state is going to be difficult to test
I guess the Repository and Unit of work are the two most popular patterns. Other than these two, few patterns that I come across most often are
- Factory Patterns
- Rules Engine
Discussing design patterns for better design is out of the scope of this post. You use it or not You must know about design patterns. Then you may use it properly and correctly. I tend to write Idempotent and side effects free functions. Try not to violate Law of Demeter.
Design Patterns to help writing Unit Test
Nobody wants to spend more time maintaining the test base. It should be clean, readable and properly separated. To be successful on TDD you need to know how to write better unit tests. Some design patterns I found really handy to write unit tests are
I want to mention TDD does not lead you to good code design unless you apply design patterns and principles very carefully.
Refactoring in very small steps towards better design
No need to apply design patterns in the first place, apply them eventually. Listen to your test and code smells, what patterns are required will be clear eventually.
To pass a failing test write dumb code. And when there are tests developers don’t scare to change. But you must refactor your codes in very small steps. And it is really important. Do jump to a big refactoring of your code
If you are not familiar with refactoring, a few resources I could recommend for a jump start
- Refactoring catalog
- Code kata
- Steve Smith’s Pluralsight courseses
This whole series will be incomplete if I do not mention about code kata. To practice TDD or to become efficient with TDD code kata is here to help us.
For a beginner two katas are really helpful
This will help you to understand how to do code kata as well as TDD process. I have also tried katas to learn TDD. Do code kata’s at least for half an hour every day, this will show you the power of TDD
I have tried to add a few references about things you need to know to practice TDD. This is the last post. But this is not all. There are many more. A whole lot of things you need to know to become specialist over TDD to be a Software Craftsman. So please do not stop here, this is just the beginning.
I have really enjoyed writing this series of posts. I have learned more about TDD while researching to write these posts. I have tried to share my understanding of TDD with you. Please correct me if I am wrong. You can email me at firstname.lastname@example.org or follow me on twitter