avatarJoão Almeida

Summary

The article discusses table-driven testing, a more idiomatic way of writing tests for functions in Go, Python, and PHP.

Abstract

The article titled "Patterns: table-driven testing" showcases a better way to structure tests for improved readability and easier extension. The author uses the example of a function that anonymizes emails in a given text and compares the classical way of testing it with the table-driven way. The classical way involves having a test function for each case, which can lead to duplicated test code and make it harder to read. The table-driven way, on the other hand, involves defining a table with input data and expected outcomes for each case, and then executing the function being tested and asserting its outcome. The author provides examples of how to implement table-driven testing in Go, Python, and PHP.

Opinions

  • The author believes that table-driven testing is a more idiomatic way of writing tests for functions in Go, Python, and PHP.
  • The author thinks that the classical way of testing can lead to duplicated test code and make it harder to read.
  • The author suggests that one test function should be used per function being tested.
  • The author recommends using pytest's parametrize feature for Python testing.
  • The author advises using data providers for PHP testing.
  • The author emphasizes that tests should be easy to read and reason about, not only by the author but also by the people who will review or refactor them in the future.
  • The author encourages readers to provide feedback or ask questions about the article on Twitter.

Patterns: table-driven testing

The Go, Python and PHP way

Photo by Émile Perron on Unsplash

In this article I’m going to showcase a way to better structure your tests that allows for better readability and easier extension.

Consider the following signature for a function that anonymizes all emails in a given text by replacing them with “*****” and returning the result:

func (Anonymizer) AnonymizeEmails(text string) string

The Classical Way

The common way to go about testing this would be to have a test function for each of the cases you want evaluated:

However, as you can see, even though the function being tested is fairly simple, it’s not that trivial to read its test file. It has quite a bit of duplicated test code and will only get worse as you add new cases or your implementation becomes more complex.

The Table-driven Way

A more idiomatic way of writing these tests is to have a single test function that starts by defining a table with all the input data needed to setup the test and the expected outcomes for each case you want to evaluate. Then, for each entry in the table, it executes the function being tested and asserts its outcome.

Rule of thumb: one test function per function being tested

In practice

Go

Python

If you’re using pytest, check out parametrize.

PHP

More on data providers.

Conclusion

Your tests should be easy to read and reason about, not only by you but, above all, by the people that will review or refactor them in the future. This approach is quite simple but can make a world of difference.

References

If you have any question or feedback about this article, feel free to comment or DM me on twitter @ https://twitter.com/jmdalmeida1.

Testing
Go
Python
PHP
Unit Testing
Recommended from ReadMedium
avatarArpan Basak
Mocking with Mockery in Golang

6 min read