Skip to content

Testing and Unit Testing ​

Learning Outcomes ​

After completing this lecture and the related lab, students will be able to:

  • Explain: Articulate the purpose of testing, differences between unit testing and other testing types, and why tests improve developer productivity.
  • Design Tests: Design effective unit tests including normal cases, edge cases, and failure cases.
  • Write Tests: Write unit tests using Doctest and use common test macros/assertions.
  • Interpret Results: Run tests, read test output, and diagnose failing tests to locate defects.
  • Automate: Integrate tests into a simple automated workflow using Makefiles.
  • Use Test-First Practices: Apply basic test-driven development to guide incremental implementation.
  • Debug & Prevent Regressions: Create regression tests for fixed bugs and use tests to prevent regressions.

Ethics Essay on the Importance of Testing ​

Review the instructions for the ethics essay today!

Test Your Code ​

Testing will make you more productive.
Meaning, you will spend less time working on problems because you will...

  • increase your chances of getting it right the first time AND

  • rarely make the same mistake twice.

Warning ​

  • A computer program cannot sufficiently generate test cases for your code.

  • The Halting Problem: Alan Turing proved that it is impossible for a computer to determine if any program halts (finishes).
    Watch this explanation video.

    • Optionally, check out this related video: Math's Fundamental Flaw. This video is optional to watch, but fascinating.
  • If we don’t know if it halts, how can we test?

  • This is your job, and an advantage you have over computation.

Unit Test ​

  • For this course, unit testing is sufficient.

  • There are many other forms of testing, but this course focuses on (relatively) small units of code.

  • There are numerous unit-testing tools, but no de facto standard for C++.

    • Unlike Java’s JUnit
  • Popular testing frameworks for C++ include GoogleTest, Boost.Test, CppUnit, CxxTest, and Catch2.

Doctest – Unit Testing for C++ ​

  • We will use Doctest for this course.

    • Doctest is simple, yet has a rich feature set.
  • You only need to place the one file, doctest.h, in your test repository.

  • I have provided a full template in class-code.
    Take a look in the git repository.

Regression Testing ​

Regression testing focuses on preventing previously fixed bugs from reappearing by adding automated tests that reproduce the bug. With Doctest, write a focused TEST_CASE that encodes the failing scenario (use CHECK/REQUIRE to assert expected behavior), commit the test alongside the fix, and include it in your test suite so CI or the auto-grader will catch regressions.

Example:

cpp
// Regression test: previously failed on empty input
TEST_CASE("handle empty input") {
  CHECK_EQ(handle(""), expectedValue);
}

Keep regression tests small, deterministic, and fast so they reliably prevent regressions without slowing development.

Lab 5 ​

Auto-Grader ​

  • An auto-grader will provide a grade for most of the labs (starting in Lab 5).

    • It will not say what test cases you failed.

    • It may not mention if there is a timeout.

    • It may not say if there are compilation errors.

    • It may tell you which part of the lab you got right or wrong.

  • Test cases from the auto-grader will NOT be disclose. You must learn how to write your own test cases!

  • The grade from the auto-grader should be pushed to your repository shortly after you push your solution.

Lab 5: A Review of C++ Arrays ​

Let’s talk about Lab 5.