Topic: [tests] test code C++
why test your code (not to put the same errors from the past into the git log, you will be warned by the tests)
doc Working Effectively. with Legacy Code
https://github.com/ontiyonke/book-1/blo … ode%5D.pdf
Code without tests is bad code. It doesn’t matter how well written it is; it doesn’t matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change
the behavior of our code quickly and verifiably. Without them, we really don’t know
if our code is getting better or worse.
1. Identify change points.
2. Find test points.
3. Break dependencies.
4. Write tests.
5. Make changes and refactor
Identify Change Points
The places where you need to make your changes depend sensitively on your
architecture. If you don’t know your design well enough to feel that you are
making changes in the right place, take a look at Chapter 16, I Don’t Understand the Code Well Enough to Change It,
and Chapter 17, My Application Has No Structure.
Find Test Points
In some cases, finding places to write tests is easy, but in legacy code it can often
be hard. Take a look at Chapter 11, I Need to Make a Change. What Methods
Should I Test?, and Chapter 12, I Need to Make Many Changes in One Area.
Do I Have to Break Dependencies for All the Classes Involved? These chapters
offer techniques that you can use to determine where you need to write your
tests for particular changes.
Dependencies are often the most obvious impediment to testing. The two ways
this problem manifests itself are difficulty instantiating objects in test harnesses
and difficulty running methods in test harnesses. Often in legacy code, you have
to break dependencies to get tests in place. Ideally, we would have tests that tell
us whether the things we do to break dependencies themselves caused problems, but often we don’t. Take a look at Chapter 23, How Do I Know That I’m
Not Breaking Anything?, to see some practices that can be used to make the
first incisions in a system safer as you start to bring it under test. When you
have done this, take a look at Chapter 9, I Can’t Get This Class into a Test Harness, and Chapter 10, I Can’t Run This Method in a Test Harness, for scenarios
that show how to get past common dependency problems. These sections
heavily reference the dependency breaking techniques catalog at the back of the
book, but they don’t cover all of the techniques. Take some time to look
through the catalog for more ideas on how to break dependencies.
Dependencies also show up when we have an idea for a test but we can’t
write it easily. If you find that you can’t write tests because of dependencies in
large methods, see Chapter 22, I Need to Change a Monster Method and I
Can’t Write Tests for It. If you find that you can break dependencies, but it
takes too long to build your tests, take a look at Chapter 7, It Takes Forever to
Make a Change. That chapter describes additional dependency-breaking work
that you can do to make your average build time faster.
I find that the tests I write in legacy code are somewhat different from the tests I
write for new code. Take a look at Chapter 13, I Need to Make a Change but I
Don’t Know What Tests to Write, to learn more about the role of tests in legacy
Make Changes and Refactor
I advocate using test-driven development (TDD) to add features in legacy code.
There is a description of TDD and some other feature addition techniques in
Chapter 8, How Do I Add a Feature? After making changes in legacy code, we
often are better versed with its problems, and the tests we’ve written to add features often give us some cover to do some refactoring. Chapter 20, This Class Is
Too Big and I Don’t Want It to Get Any Bigger; Chapter 22, I Need to Change
a Monster Method and I Can’t Write Tests for It; and Chapter 21, I’m Changing the Same Code All Over the Place cover many of the techniques you can use
to start to move your legacy code toward better structure. Remember that the
things I describe in these chapters are “baby steps.” They don’t show you how
to make your design ideal, clean, or pattern-enriched. Plenty of books show
how to do those things, and when you have the opportunity to use those techniques, I encourage you to do so. These chapters show you how to make design
better, where “better” is context dependent and often simply a few steps more
maintainable than the design was before. But don’t discount this work. Often
the simplest things, such as breaking down a large class just to make it easier to
work with, can make a significant difference in applications, despite being