What is Test-Driven Development?
Test-driven development, or TDD, is a programming language-agnostic methodology where tests are written before the code. It forces the software engineer to "plan before doing" instead of just "doing" by using an easy-to-remember mantra: Red-Green-Refactor.
Red-Green-Refactor Explained
Let's visualize Red-Green-Refactor as a traffic light.
When driving, we must stop at the red light. Running the red light can have dire consequences. We could get an expensive traffic ticket, cause an accident, or even worse - kill someone. We have all been tempted to run red lights, especially when we are in a hurry to get to our destinations, but we do not run them because we know what could happen. It is not a risk worth taking. Typically we will not kill someone by failing to follow Red-Green-Refactor in software development, but skipping the process can have consequences for the application and for the business we are working with.
A green light tells us that we can proceed through the intersection, but if we do not know what direction we should be going to get to our destination, what good is that green light? We could be going around in circles, never getting where we want to. The same can be said about software development. Stakeholders give us the green light to start developing the software, but if we do not understand the target we will 100% miss it.
Refactoring is much like the yellow light. It tells us to proceed with caution. In the case of refactoring code, we can rely on the tests written in the Red-Green steps to let us know if we have introduced bugs or unintentional functionality. We must be cautious to ensure we have followed the proper steps and continuously run the tests when refactoring.
First Things First - Get the Requirements in Order
Stakeholders have a vision, budget, and often a timeline in mind for launch. Whether we follow agile, waterfall, DevOps, or any other delivery methodology, it is at times difficult to get stakeholders to understand that proper processes must be followed to have a solid application that customers can trust. Requirements are the most important part of test-driven development and often the step that stakeholders have the most issues with because of the time it takes upfront to do them properly. The test cases are written directly from requirements from the stakeholders and the features are written from the tests. If the requirements are not clear, our test cases will not be clear and our feature will have holes. Holes will not be caught and lead to bugs and/or unexpected behavior for the end users. It is important that we do not proceed until you have clear requirements.
Let's look at an example of a simple requirement for a login screen:
As a user, when I am presented with the login screen, then I can enter my username and password and gain access to the application.
Pretty simple and standard login behavior. Do you see anything missing from this requirement? Let's think through this a bit.
As a user...
What kind of user is this? Is this a registered user or a new user who does not yet have an account. First hole found! Let's make this requirement for a registered user. There needs to be a different requirement for a new user, but we will focus on the registered user for now.
As a registered user with an existing account, when I am presented with the login screen, then I can enter my username and password to gain access to the application.
This requirement has more clarity. What else is missing?
when I am presented with the login screen...
This is straightforward. The registered user is presented with some style of login screen.
then I can enter my username and password to gain access to the application...
Also straightforward. The registered user enters their username and password to authenticate into the application.
Wait, can the username be anything or is it an email address? What happens if they enter the wrong password? Or they forgot their username and/or password? Or their access to the application has been revoked? Or there is an error with the authentication API? More holes!
The original requirement is happy path - meaning what happens is the ideal scenario. It also lacks details. It does not account for error handling and other non-happy path (edge cases, errors, etc) behavior and other details that are needed to develop the feature.
Do we need to know these non-happy paths and details to write code for login? Yes, yes we do. Otherwise our code will not be well rounded enough to account for all of these common scenarios and we will have to go back and fix it later. Time and money wasted - all things developers and stakeholders detest, so better to get this right up front.
Let's fix this requirement by adding some non-happy path scenarios in addition to the original requirement.
As a registered user with an existing account, when I am presented with the login screen, then I can enter my email address and password to gain access to the application.
As a registered user with an existing account, when I enter the wrong email address or password, then I am prompted with an error message.
As a registered user with an existing account, when I have forgotten my username, then I am presented with an option to retrieve it.
As a registered user with an existing account, when I have forgotten my password, then I am presented with an option to reset my password.
As a registered user with an existing account, when I login to the application and my access has been revoked, then I do not see information in the site.
As a registered user , when I login to the application and there is an issue with the authentication feature, then I see an error message.
Wow! One simple requirement has now turned into six, and #3 and #4 needed to be broken down further. Stakeholders must be part of this process to clarify and breakdown requirements. It is time consuming, but the cost up front is well worth it. This is now a robust feature set that is ready to start testing and developing.
Red - Write a Test and Make it Fail
Now that we have clear requirements, we can start writing tests. Remember, we must write the test before the code! The test we write initially should be for the smallest part of the requirement. Let's write a test that checks that the username field only takes a properly formed email address and nothing else.
Run the test and watch it fail because the function doesn't exist yet. Failure is success!
Green - Write Enough Code to Make Your Test Pass
Now is the time to start the feature implementation. We make tests pass by writing just enough code for the properly formed email address value. If our test fails, we work on the code until it passes.
Refactor - Make the Feature and Test Better
This is the step where we refactor code to make it well structured, and continuously run the tests to ensure that we did not unintentionally introduce a breaking change.
For each additional functionality of the feature, we repeat the steps in order. In this instance, the next feature for the username field would be to write a test that displays an error for values not properly formatted as an email. We write the test, update the function to validate the field until the test passes and then refactor the code.
Red-Green-Refactor brings organization to our product development process. It makes us stop and think about what we are writing, verify against the requirements and work out bugs early in the process before any code is shipped to users. It can take some time up front to change our ways of thinking to start working this way, but Red-Green-Refactor in test-driven development is well worth it.
The World Best Exam Dumps Webiste is Dumpsedu. One of the top site for AZ-900 Exam Dumps. AD0-E127 Exam Questions
AD0-E329 Exam Questions
CTP Exam Questions
CGFM Exam Questions
RHIA Exam Questions
AHM-510 Exam Questions
AHM-520 Exam Questions
AHM-250 Exam Questions