The Benefits of Test Driven Development and its Best Practices


Jul 6th 2020

By Robert Kirchner JR


Test Driven Development, What is It?

Test driven development(TDD) is a software engineering practice in which we write test against new features before we actually write the code for them. This gives us a red light green light dev cycle that also provides living documentation, and allows us to release with confidence that our application works.


test-driven-development

Unit Testing

This is the foundation of TDD, and it takes many forms.


Unit of Work

A unit of work can be thought of as the smallest amount of work any given lines of code are doing.

This could be a method/function, or it could be as small a line of conditional logic.

Unit Tests

Unit testing, and its frameworks allow you to run tests on your code as you develop, without having to build the entire application and debug with print lines.

A typical unit test might might assert against the case logic in a method, very that another function was called with the right parameters, or maybe assert that an artifact was rendered properly.

Testing Frameworks

No matter what language you are coding in, there is most likely a framework that provides the means to run unit tests. In Java we might use JUnit, as well as Jest in Javascript.

Mocking

Mocking is the practice of replacing objects your code is dependent on with test purpose specific fakes.

This not only simplifies and makes units of work smaller, but also decouples your code from dependencies you may not own or control.

This allows us maybe to verify that a method calls another with the right arguments, but also gives us the means to control what an external dependency returns. This allows us to test all the edge cases our logic might encounter.

It is best TDD practice, to wrap services and dependencies(especially ones that you don't control) in another object or interface that can be easily mocked.


Integration Testing

Functional Tests

With integration tests, we make assertions on the entire running application.

If we were engineering a web service, an integration test might verify that endpoints return the appropriate responses when being called with requests.

These types of tests usually verify that all dependencies are wired up working together right.



Enter Test Driven Development

traffic light

Red Light, Green Light

The idea behind TDD is very simple, test first, code last.

The that is, you engineer features with failing tests. First, you write a test that asserts that the functionality you are about to add works correctly. This gives us a failing test(red light), but we must be careful that the test fails for the right reason.

Now we add the code, and make the test pass(green light).

Living Documentation

When we develop applications with TDD, our software now has living documentation without ugly and unsightly comments.

Every faucet of code has a test, that with good naming conventions, tells us what the code does.

This is one of the most valuable aspects of good test driven development practices. We could handle our entire codebase of to an entirely new team, and assume with some confidence that they can get up to speed in a reasonable amount of time.

Refactoring

Refactoring is the act of changing, or reorganizing our code, while retaining the same behavior.

Code that has been well covered with tests, can be refactored with confidence. That is if we add functionality that breaks another part of our application, some test will fail and let us know.

Deploy Often

The practice of test driven development allows us to deploy as often as the users can stand, with confidence that our code is always in a working state

Code that has been well covered with tests, can be refactored with confidence. That is if we add functionality that breaks another part of our application, some test will fail and let us know.

We now have a test driven development life-cycle that we can relate to a traffic light:

  • Red: Write the failing test
  • Green: Write the code(Make the test pass)
  • Blue: Refactor the code

Deploy Often

The practice of test driven development allows us to deploy as often as the users can stand, with confidence that our code is always in a working state.

Quality test coverage, coupled with good CI/CD practices empowers us with a smooth development life-cycle.


Conclusion

Unit and integration testing allow us a sustainable way to test small units of work withing our application.

Test driven development is a practice in which we write failing tests for features before we write the actual code to implement them. This gives our code living documentation and allows us to make iterative refactoring passes on our code with confidence.

With TDD we can deploy as often as users can tolerate, and know our code always works.


Comments




Navagation