Test-Driven Development
“Programming is like exploring a dark house. You go from room to room to room. Writing the test is like turning on the light. Then you can avoid the furniture and save your shins (the clean design resulting from refactoring). Then you’re ready to explore the next room” - Kent Beck
It is true that sometimes programming is like exploring a dark house, especially when we just directly type our code without defining first the goal and acceptance criteria for the code that we are going to write. We cannot be sure whether we have created the correct code or not since we have not tested it yet. Test-Driven Development can assist us in programming, to test whether we have the correct code that meets the acceptance criteria, and to guide us on what to code.
How TDD Works
Image Source: http://www.agilenutshell.com/test_driven_development
TDD has three basic rules.
- Test First: Don’t write a line of new code unless you first have a failing test.
- Create a function to pass the test.
- Eliminate duplication.
Those three basic rules are implemented in TDD Cycle. TDD Cycle consists of (at minimum) three steps or phases.
- Red
In this phase, we make a working test case before coding the actual implementation of the program. In this phase, we define a working test case that can be used to test our program based on the defined acceptance criteria. In this phase, we execute the test case to get the first failing test in order to continue to the next phase
2. Green
We created a code that can pass the test case. In this phase, the coding process is continued if the code is not accepted yet by the test. In this phase, we have to make sure that our code's primary goal is to do things that are defined in the acceptance criteria.
3. Refactor
After writing a code that can pass the test, we might need to refactor our code due to some issues, for example, Code Smells, inefficient algorithms, etc.
The benefits of implementing TDD
TDD is very beneficial for software developers to prevent bugs early in the development process and to guide programmers on what to code.
The drawbacks of implementing TDD
Implementing TDD can take a lot of time since the programmer has to create the test at the very beginning of the process and this can be a problem for a project with tight deadlines.
How my team implemented TDD
We strictly followed TDD and the above picture is an example of how we implement it in our project. When naming a commit, we give specific "tag"/"prefix" on the commit name, such as [RED], [GREEN], [REFACTOR], and [CHORES]. Every member of the development team has to make a test case first before making the actual implementation of the code.
FIRST Principle
F.I.R.S.T. Principle stands for
Fast
The developer should not hesitate to run the test case since the test case should be fast and not redundant so that it does not take much time to execute all the test cases.
Isolated
The test must be isolated so that each component can be tested accurately without any interference from external factors, for example, Database, Objects, Data, etc.
Repeatable
The test should be accessible at any time. The test cases can be executed at any time without any limitation. The test should be deterministic, to ensure the quality of the code.
Self-validating
The test cases should be able to automatically check flaws in the code by using assertions. The test should be automatic and must not require any manual actions.
Thorough
The test should be able to cover the acceptance criteria of the code and edge cases, such as invalid inputs and other possible scenarios.
Implementation of the FIRST Principle in my team
All the tests that exist in the repository are isolated from external factors such as databases, objects, and data. It is performed by using a different database setup (isolated database) for the testing phase and initializing new objects during the setUp of tests.
The tests cover both negative and positive tests for both desired and undesired situations. The test runs automatically and all tests use assertion to check the code.
Example Test Cases
Initializations of Objects during setUp
During the setUp, test cases must create all the required objects since the database is isolated and different from the database used in the production.
Positive Test
Negative Test
References
https://medium.com/@tasdikrahman/f-i-r-s-t-principles-of-testing-1a497acda8d6