diskusi.tech (beta) Community

loading...

TDD: The Art of Planning Implementation by Writing Test

andhikayusup profile image andhikayusup Updated on ・2 min read

"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.

  1. You may not write production code until you have a failing test.
  2. You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
  3. 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)
...
Enter fullscreen mode Exit fullscreen mode
  • [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
...
Enter fullscreen mode Exit fullscreen mode
  • [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
...
Enter fullscreen mode Exit fullscreen mode
  • [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
...
Enter fullscreen mode Exit fullscreen mode

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

pic
Editor guide