The idea behind test driven development is that you let the tests 'drive' your development process. How does this work? Start by writing a test that fails, then develop the code to make that test pass, then refactor. This cycle is called red, green, refactor.
RED: The red phase is the starting point of the cycle, where you define expectations for the piece of code being tested, and let the test fail. Write tests starting at the lowest level, e.g. when the function is passed an empty array, return an empty array. Why let the test fail? So that you know you have written a good test - a test shouldn't be able to pass without any logic.
GREEN: Implement the necessary logic to make your test pass - don't worry about it being the most optimised or efficient at this stage, the goal is to pass the test!
REFACTOR: During the refactor phase, consider how you could optimise your code, without adding any additional functionality.
So, now that you know about the process, what are the benefits of Test-Driven Development?
With TDD you can dictate exactly what you expect your code to do from the ground up. TDD forces you to think about exactly what you expect from scenario to scenario, which makes you more likely to cover all the bases.
By starting tests with the simplest functionality first, you can use them to guide your logic as you build up functionality. This helps you to break a problem down into smaller, more manageable pieces, thus aiding the problem solving process.
Test-coverage refers to the percentage of your code that is tested. A high test coverage means that you can trust your code works because you have a large set of tests, and TDD allows for this because you shouldn't have any code written which doesn't have the associated tests.
As you are specifically writing code to pass the tests in place, and refactoring at the end of each test; you ensure your code is clean and optimised without any extra pieces of code that you won't need.
As you are adding to the functionality of your code as you go along, you ensure that each stage of the code is working as you progress. Much better than writing a large piece of code, and trying to test it afterwards only to find that it fails!
With a high test coverage, you are simply adding to a very tested piece of code. This is great because you know you can rely on the code you already have, and can write additional tests to add functionality bit by bit.
One great benefit of testing in general (and using descriptive test statements!), is the readability this provides for others. Developers, testers and non-technical colleagues working on or around the codebase can identify exactly what the piece of code does without any guesswork - great for when you are working on an older codebase and want to navigate around it easily.