From the course: Programming Foundations: Test-Driven Development

What is test-driven development (TDD)? - Java Tutorial

From the course: Programming Foundations: Test-Driven Development

Start my 1-month free trial

What is test-driven development (TDD)?

- This week has been crazy. - Yeah, I know. I can't wait for the weekend. - Hey, why don't you come over to my place this weekend? - That would be awesome. Now where do you live? - Uh, 123 Main Street, Magical Town. - Hm, okay, I don't think I know where that is. Uh, how do you get there? - Well from here, you're going to drive straight for three miles, make a left on Popular Avenue, a right over the bridge, and it's the third row house on your left. - Maybe you could show me on a map? - Yeah, sure. - Okay. - All right, so, you're here, and my house is right here. - Oh, okay, I think I got it, thanks. - How does Thai food sound? - That sounds wonderful. - Okay, I'm going to pick up take-out. - All right (laughing). - To go from point A to point B, you could take turn-by-turn directions, or you could use a high-level map to guide where you want to go. These are the two options. Which option you pick depends on how well you know how to get to point B. Using turn-by-turn directions is the small-step incremental approach, or the bottom-up approach, and using a map is the big picture, top-down approach. This analogy can be used to think about when we are creating something. When we know how to make something, we start with a plan, and then follow the plan as we make it. But, if we do not know the details of how to make something, it's hard to come up with a plan. So, we take small steps while figuring out how to make what we want to make. In the software world, conventionally the planned approach has been to start with the requirements, come up with a design, write code to implement that design, and then write test cases to test that code. This is the test last development approach. In a test-driven approach, given some requirements, you come up with test cases that will drive the rest of the development. The design emerges from the test cases. This is the pure TDD approach. Note that the testing in TDD is only unit testing. That is, testing your code at the smallest unit level. Other types of testing, such as system testing, integration testing, or functional testing, test your application at a higher level and therefore not part of TDD's scope. But, to be able to write unit test cases, there are often high-level ambiguities, especially in large and complex projects, that need to be ironed out before you can think about unit test cases. In those cases, you may come up with some parts of design to help you craft your test cases. So you do have some design drawn out before you write unit test cases. So this is not truly test-driven. But some call it as a test-first approach. Now, there is some overlap in the usage of two terms, test-driven, or test-first, but the key idea is that you first write your test case, and then write the code to pass that test case. The most fundamental aspect of the approach is the test-code-refactor cycle. Before you write any code, you first write your failing test case, then you write the code that passes that test case. As the test cases, and code, continue to grow, you keep an eye for duplicate or bad code. Every now and then, you fix such code by what is called as refactoring. Refactoring is improving the internal structure of your code without changing its external behavior. So, let us take an example to see the difference between the two approaches. First, we will see the test-last approach. - So we've got that customer coming in this morning. Kind of talk about his needs for the new game. - Okay. - Okay? - Hey, how's it going? - Oh, hey, how are ya'? - I'm doing fantastic, how are you both doing? - Really good, really good. - Well, so, for the project that we're on, I'm looking for an app that has word games. It has hangman, crosswords, and anagrams. Is that something we can make happen? - Definitely, definitely, okay. So, we can look at each game as a big use case, right? And, why don't we first focus on the play hangman use case? - Sounds great. - Okay. So, let's get started here. So why don't we think of there's the player. This is going to be our game, or our app, right? - Right, right. - Okay. Okay, so, first we'll start with the play hangman use case, 'kay. Then we'll move on to the anagrams. - Anagrams, yup. - Okay, great. And finally, what, the? - Crosswords. - Crosswords! - Yeah, crosswords. - (laughing) Great. Okay, what do you think? - That sounds amazing. - It's a good start. - Yeah, definitely, really excited about it. - Us, too, thank you so much. - Thank you so much. - All right. Let's get to it! - All right. - Okay. - Okay, so here's our first cut of class diagram, and it looks like we're ready to start coding. - In this scenario, the team started with understanding the requirements, and then created a detailed design. And now, the team is planning to start coding. Now, that is a big no-no in TDD. So, what should the team have done if it wanted to follow TDD? Let us see. - So these are all word games. They all need words, I'm thinking our first functionality that we can implement would be to fetch a word from somewhere. - Well that seems like a good place to start, but, where are you getting the words from? - Well, maybe we can get the words from a text file. And we can always change the source when we have a better idea of what we want. - Okay, well, let's test the first case, then. See that hangman is able to fetch a word of length X, so-- length X. - Okay, sounds good. - I think we can do it. - Notice the difference? The team briefly talked about a high-level design decision, to get the words from an external source, but did not start drawing detailed class diagrams. They took the first requirement and then decided to write its first test case. The key idea here, is that before you write a single line of code, you first write a test case for it. And that is the golden rule of test-driven development.

Contents