Refactoring 011 - Replace Comments with Tests

Maxi Contieri - Apr 23 '23 - - Dev Community

Comments are dead. Tests are alive

TL;DR: Take your comment, compact it, and name your functions. Now test it and remove the comments.

Problems Addressed

  • Maintainability

  • Readability

Related Code Smells

Steps

  1. Take the comment of the method explaining what the function does.

  2. Rename the method with the comment description (the what).

  3. Create tests to verify the comments.

  4. Omit irrelevant implementation details.

Sample Code

Before

def multiply(a, b):
    # This function multiplies two numbers and returns the result
    # if one of the numbers is zero, the result will be zero
    # if the number are both positive, the result will be positive
    # if the number are both negative, the result will be positive
    # the multiplication is done by invoking a primitive
    return a * b

# This code has a comment that explains what the function does.
# Instead of relying on this comment to understand the behavior of the code,
# we can write some unit tests that verify the behavior of the function.
Enter fullscreen mode Exit fullscreen mode

After

def multiply(first_multiplier, second_multiplier):
    return first_multiplier * second_multiplier

class TestMultiply(unittest.TestCase):
    def test_multiply_both_possitive_outcome_is_possitive(self):
        result = multiply(2, 3)
        self.assertEqual(result, 6)
    def test_multiply_both_negative_outcome_is_positive(self):
        result = multiply(-2, -4)
        self.assertEqual(result, 8)
    def test_multiply_first_is_zero_outcome_is_zero(self):
        result = multiply(0, -4)
        self.assertEqual(result, 0)
    def test_multiply_second_is_zero_outcome_is_zero(self):
        result = multiply(3, 0)
        self.assertEqual(result, 0)
    def test_multiply_both_are_zero_outcome_is_zero(self):
        result = multiply(0, 0)
        self.assertEqual(result, 0)           

# We define a test function called test_multiply,
# which calls the multiply function with different arguments 
# and verifies that the result is correct using the assertEqual method.

# 1. Take the comment of the method explaining what the function does.
# 2. Rename the method with the comment description (the what).
# 3. Create tests to verify the comments. 
# 4. Omit irrelevant implementation details
Enter fullscreen mode Exit fullscreen mode

Type

[X] Semi-Automatic

We can rewrite the comment and compact it, but it is not always in an algorithmic way.

Safety

This is not a safe refactor but it increases coverage.

Why code is better?

Comments lie. The code doesn't.

Limitations

We cannot test private methods.

In the unlikely event that we need to replace a comment on a private method, we should test it indirectly or extract it into another object.

We can leave comments reflecting important design decisions.

Tags

  • Comments

Related Refactorings

Credits

Image by philm1310 on Pixabay


This article is part of the Refactoring Series.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .