Skip to content

Implemented a C++ function, learned how to use CMake and Google Test framework for unit testing. Used a custom cpp devcontainer.

License

Notifications You must be signed in to change notification settings

jotavare/unit-testing

Repository files navigation

ABOUT

This project involves creating and testing a function called hasPair() using modern C++ practices. It required learning CMake, and using GoogleTest for unit testing. The project setup utilizes a devcontainer for C++, and Node.js for chapter exercises from The Art of Unit Testing (aout3-samples/).

PROJECT CHECKLIST

  • Introduction to unit testing.
  • Implement the function hasPair().
  • Use Google Test, for unit testing the code.
  • Remember to comment on the code where necessary.
  • Publish the code on GitHub and send the link.
  • Bonus: Set up the project with CMake.

PROJECT STRUCTURE

The current folder structure of the project and explanation of each folder and file:

├── .devcontainer/
│   ├── cpp/
│   │   ├── devcontainer.json   # devcontainer configuration file
│   │   ├── Dockerfile          # Dockerfile for setting up devcontainer
│   │   ├── post-create.sh      # script to run after creating the devcontainer
│   │   └── reinstall-cmake.sh  # script to reinstall cmake
│   ├── node/
│   │   └── devcontainer.json   # devcontainer configuration file for aout3-samples
├── aout3-samples/              # sample exercises from "The Art of Unit Testing" book
├── cmake-tutorial/             # small tutorial i did to learn cmake
├── exercise/
│   ├── cmake/                  # includes a cmake update submodules file
│   ├── example/                # cmake example i did to learn cmake and a makefile example
│   ├── googletest/             # source code of googletest
│   ├── hasPair/                # the main exercise, hasPair function and tests
│   └── CMakeLists.txt          # main cmake configuration file
├── .gitignore
├── .gitmodules
├── LICENSE
└── README.md

COMMANDS

List of commands that I learned while doing this project:

# generate build system files in the 'build' directory
# use --trace to show the commands being executed
cmake -S . -B build
cmake -S . -B build --trace

# build the project using the generated build system files
# use [n] (threads) to build or $(nproc --all) to use all threads
# use --verbose to show the commands being executed
cmake --build build -j [n]
cmake --build build -j [n] --verbose
cmake --build build -j $(nproc --all)

# run the tests with coloured output and show output on failure
GTEST_COLOR=1 ctest --test-dir build --output-on-failure

# measure the time
time ccmake -S . -B build

# measure the time
time cmake --build build

# display the directory structure up to [n] levels deep
tree -L [n]

# list all installed vs Code extensions
code --list-extensions | xargs -L 1 echo code --install-extension

# update the submodules
git submodule update --init

FUTURE IDEAS

These are some ideas or improvements that I would make in the future:

  • Design a flow diagram of the project and the unit tests.
  • Create a CI/CD pipeline to automate the build and testing process, when code is pushed to the repository.
  • Create a srand vector, to test the code with a custom range, size and number of times.
  • Use a variable directly while building the project. cmake -S . -B build -D vector="1,2,3,4,5"
  • Instead of symlink the latest version of Google Test, use a release version or fetch the latest version with cmake.
  • Currently, I have to build again with cmake --build build so the tests can be disabled/enabled. Find if this is the intended behaviour.

REFERENCES

Some references that I used or will in the future, to learn and complete this project. Some are based on the book The Art of Unit Testing.

Book Author
Working Effectively with Legacy Code (Pearson, 2004) Michael Feathers
The Complete Guide to Software Testing (Wiley, 1988) Bill Hetzel
XUnit Test Patterns (Addison-Wesley Professional, 2007) Gerard Meszaros
Unit Testing Principles, Practices, and Patterns Vladimir Khorikov
Test-Driven Development: By Example (Addison-Wesley Professional, 2002) Kent Beck
Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Professional, 2009) Steve Freeman and Nat Pryce
Clean Code (Pearson, 2008) Robert C. Martin
Websites Source
Command Query Separation Website
XUnit Test Patterns Website
Node.js’s assert module Website
GoogleTest Primer Website
GoogleTest Assertions Reference Website
CPP Devcontainer GitHub
GNU Smalltalk User's Guide: SUnit - Kent Beck Website
Videos
CMake - the essential package
Do you even test? (your code with CMake)
GoogleTest Introduction with CMake LINUX - C++ - GMOCK

UNIT TEST CHECKLIST

This section includes some checklists and questions from the book The Art of Unit Testing, which I found useful to remember when writing unit tests.

UNIT TEST PROPERTIES

A good unit test should exhibit the following properties:

  • It should be easy to understand the intent of the test author.
  • It should be easy to read and write.
  • It should be automated.
  • It should be consistent in its results (it should always return the same result if you don’t change anything between runs).
  • It should be useful and provide actionable results.
  • Anyone should be able to run it with the push of a button.
  • When it fails, it should be easy to detect what was expected and determine how to pinpoint the problem.

UNIT TEST QUESTIONS

Ask yourself the following questions about the tests you’ve written and executed up to now:

  • Can I run and get results from a test I wrote two weeks, months or years ago?
  • Can any member of my team run and get results from tests I wrote two months ago?
  • Can I run all the tests I’ve written in no more than a few minutes?
  • Can I run all the tests I’ve written at the push of a button?
  • Can I write a basic test in no more than a few minutes?
  • Do my tests pass when there are bugs in another team’s code?
  • Do my tests show the same results when run on different machines or environments?
  • Do my tests stop working if there’s no database, network, or deployment?
  • If I delete, move, or change one test, do other tests remain unaffected?

UNIT TEST QUALITIES

A good unit test has these qualities:

  • It should run quickly.
  • It should have full control of the code under test.
  • It should be fully isolated (it should run independently of other tests).
  • It should run in memory without requiring filesystem files, networks, or databases.
  • It should be as synchronous and linear as possible (no parallel threads).

About

Implemented a C++ function, learned how to use CMake and Google Test framework for unit testing. Used a custom cpp devcontainer.

Topics

Resources

License

Stars

Watchers

Forks