"Writing test is just planning an implementation"
For those who are currently practicing Software Engineering maybe familiar with bugs and errors. Sometimes, fixing one of those bugs will create more bugs! Therefore, Test Driven Development (TDD) comes in handy. But, what is TDD?
Brief Summary of TDD
Test-Driven Development (TDD) is a form of workflow in software development process. Kent Beck, the creator of Extreme Programming, is credited as the person who is "rediscovered" this the technique. Contrary to the general workflow of software development, the main idea of this workflow is to create testcase first and then the implementation later. This technique let developers "planning the implementation" by adding testcase which defining its supposed pair of input and output in advance.
Three Laws of TDD
According to Robert C. Martin's book, Clean Code, There are three laws of TDD.
- You may not write production code until you have a failing test.
- You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
- You may not write more production code than is sufficient to pass the currently failing test.
TDD also introduced popular git tag RED-GREEN-REFACTOR-CHORES to be a label in git commit message:
- [RED] is when the testing code committed and the production code fails. Usually this is the commit tag if you wanted to commit unittests.
For example:
[RED] Add test_retrieve_internship_application_success_return_200
...
def test_retrieve_internship_application_success_return_200(self):
view = InternshipApplicationList.as_view()
request = self.factory.get(URL_INTERNSHIP_LIST)
force_authenticate(request, user=self.admin)
response = view(request)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
...
- [GREEN] is when the implementation pass the currently failing test. Usually this should be the implementation that your unittest stated before.
For Example:
[GREEN] Implement endpoint for listing internship submission
...
class InternshipApplicationList(generics.ListAPIView):
permission_classes = [IsAdmin | IsSuperadmin]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_class = InternshipApplicationFilter
search_fields = ["student__profile__npm"]
queryset = InternshipSubmission.objects.all()
serializer_class = InternshipSubmissionDetailSerializer
...
- [REFACTOR] is when cleaning the implementation code. This tag is common if you wanted to reduce duplication and refactor your production code.
For Example:
[REACFTOR] Change IntershipSubmission into global var
...
internship_submission_all = InternshipSubmission.objects.all()
...
class InternshipApplicationList(generics.ListAPIView):
permission_classes = [IsAdmin | IsSuperadmin]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_class = InternshipApplicationFilter
search_fields = ["student__profile__npm"]
queryset = internship_submission_all
serializer_class = InternshipSubmissionDetailSerializer
...
- [CHORES] is when commiting something that not changing production code behavior such as color, codestyle, and other.
For Example:
[CHORES] Reformat quotes codestyle
...
internship_submission_all = InternshipSubmission.objects.all()
...
class InternshipApplicationList(generics.ListAPIView):
permission_classes = [IsAdmin | IsSuperadmin]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_class = InternshipApplicationFilter
search_fields = ['student__profile__npm']
queryset = internship_submission_all
serializer_class = InternshipSubmissionDetailSerializer
...
F.I.R.S.T
Readability counts. Not only production code have to be clean and readable, but also testing code. Robert C. Martin said that a clean test should follow F.I.R.S.T rules:
F irst
Testing code should be fast. If certain test is slow, it should not be run not too often.I ndependent
The test should not dependent to other test.R eapeatable
The test should be repeatable in many environment.S elf-validation
The test should return boolen: True/False, Fail/Pass.T imely
Test first, implementation later.
Discussion