
The term was introduced by @mfeathers, the author of the well-known book:

A thread

Imagine that you want to refactor a piece of legacy code, but the code:
Is too complex to know what it does.
Does not have any form of written documentation.
Has no tests that allow you to refactor safely.
Characterization testing can help you!




When you write characterization tests, the purpose is not to find bugs.
The purpose is to invoke the legacy code to observe what it does and understand its behavior.
Characterization tests characterize the *actual* behavior of the code.
The purpose is to invoke the legacy code to observe what it does and understand its behavior.

The key benefits of characterization testing are:
Helps you gain understanding of the legacy system.
Gives you a test suite almost for free.
Allows you to preserve behavior: you can refactor the code and immediately know if you changed the behavior unintentionally.




When a system goes into production, it becomes its own specification.
Users depend on the actual behavior of the system.
We must know when behavior changes, regardless of whether it's correct or not.
When you are writing characterization tests:
If you suspect that the behavior you observe is a bug, seek clarification and escalate the issue, if necessary.
If you are *absolutely* sure that it is a bug, fix it.


An algorithm for writing characterization tests:
Create a test.
Write a failing assertion.
Execute the test to observe the actual behavior of the system.
Change the test so that it expects the actual behavior.
Repeat until you understand the code well.





If you want to delve more into the topic, you can have a look at @mfeathers's book.
You can also find more detailed information in this great article
https://michaelfeathers.silvrback.com/characterization-testing
You can also find more detailed information in this great article
