How to Write Good Tests?

The banner image shows a picture of a bridge called 南桥 (Nan Qiao, literally means the South Bridge.) This bridge is located at Dujiangyan, which is a small city 50km away from Chengdu, Sichuan, China. Since I had my high-school in Dujiangyan, I have a lot of precious memories there. I miss the people, inexpensive but delicious food, the way of living, and the memory when I rode a bike to travel between Chengdu and Dujiangyan with my best friends (around 100 km in total.)

Recently I am reading a book called The Art of Readable Code by Dustin Boswell. This is a textbook for a code-review class that I am taking. I think it is a good idea to share about some contents with you so that 1) I can deepen my understanding, 2) You can learn something from here!

Chapter 14: Testing and Readability

KEY IDEA: Test code should be readable so that other coders are comfortable changing or adding tests.

  1. Test should be more readable

    • When writing a test, we should hide less important details.
  2. Minimize the test statement

    • We should make the input/ expectation of a test clear so that it is very easy to add more tests.
  3. Helper function

    • By extract some unimportant logics into a separate function, we can focus on the main implementation of the test itself.
  4. Make error message readable

    • Utilize better assert in the language assertEqual in python, for example.
  • Create custom error message like:
1
2
3
4
CheckScoresBeforeAfter() failed,
Input: "-5, 1, 4, -99998.7, 3"
Expected Output: "4, 3, 1"
Actual Output: "1, 3, 4"
  1. Choose good input

In general, you should pick the simplest set of inputs that completely exercise the code.

  1. Simplifying the Input Values

    • The simple test that achieves the purpose is the best!
  2. Multiple tests

    • multiple tests for multiple purposes with clear input/expectation
  3. Naming

    • Name the test as the description.
    • Test__<FunctionName>_<Situation>()
1
2
3
void Test_SortAndFilterDocs_BasicSorting() {
...
}
  • For helper function, we can name it differently as “test-unware”.

If you write your code knowing you’ll be writing a test for it later, a funny thing happens: you start designing your code so that it’s easy to test! Fortunately, coding this way also means that you create better code in general. Test-friendly designs often lead naturally to wellorganized code, with separate parts to do separate things.

​ I hope this helps, but I strongly recommend you to read this book because it contains a lot of examples of good/bad practices. It is concise and very helpful for me and you who want to be a professional programmer!

2022/1/21

Some add-on

Programs have to be written with two goals in mind:

  • Communicating with computer
  • Communicating with people

Three themes:

  1. Safe from bugs:
  • Correctness
  • Defensiveness: correctness in future
  1. Easy to understand:
    • communicate with future programmers
    • good design helps future you/maintainers
  2. Ready to change

Software Engineering is not Hacking

Engineers are pessimists, so:

  1. write a little bit at a time, testing as you go.
  2. document the assumptions that code depends on
  3. defend code against carelessness.

Git Commit Message

image-20220121170914865

We can use a concise and helpful commit message format such as :

1
2
<type>: <Message>
feat: blablabla

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!