Skip to main content
Engineering LibreTexts

6.7: Write Tests to Understand

  • Page ID
    32728
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Intent Record your understanding of a piece of code in the form of executable tests, thus setting the stage for future changes.

     

    Problem

    How do you develop an understanding of a part of a legacy system which contains neither tests nor accurate and precise documentation?

    This problem is difficult because:

    • Code is always difficult to understand.

    • You would like to make hypotheses about what the code is really doing and validate them.

    • You would like to specify as precisely as possible the behavior of the system.

    • You would like to record your understanding to communicate it but you do not want to waste your time in writing documents that will be obsolete as soon as you start changing the code.

    Yet, solving this problem is feasible because:

    • The piece of code is relatively small and has clearly defined boundaries.

    • You have the possibility to specify tests and validate them.

     

    Solution

    Encode your hypotheses and conclusions as executable tests.

     

    Tradeoffs

    Pros
    • Tests help you to validate your understanding.

    • Tests can provide a precise specification of certain aspects of the system. Tests cannot be fuzzy.

    • Tests can be applied to gain different levels of understanding. For example, black-box tests can help you to refine your understanding of roles and collaborations, whereas white-box tests can help you to gain understanding of the implementation of complex logic.

    • The tests that you develop will help to enable future reengineering effort.

    • Tests will force you to be precise about the creation and the use of the objects under test.

    Cons
    • Writing tests is time consuming.

    Difficulties
    • Obtaining a well defined context in which you can test the objects is difficult especially if the objects to be tested do not represent specific abstractions. Looking for the places where objects you want to understand are created can help.

    • Concurrent systems are known to be difficult to test, so test scan miss important aspects (such as handling of race conditions).

     

    Rationale

    By writing automated tests, you exercise parts of the system you want to understand, while recording your understanding and setting the stage for future reengineering effort.

     

    Related Patterns

    Before writing any tests, you might want to Refactor to Understand. As you write your tests, be sure to Tie Code and Questions.


    This page titled 6.7: Write Tests to Understand is shared under a CC BY-SA license and was authored, remixed, and/or curated by Serge Demeyer, Stéphane Ducasse, Oscar Nierstrasz.

    • Was this article helpful?