Test Automation: Enhancing Game Engine Programming with Unit Tests

Welcome back to the world of C++ game engine infrastructure! Today, we will be exploring the fascinating realm of test automation in the context of game programming and game engine development.

In the previous video, we set up our namespace and file system, incorporating the IOC (Inversion of Control) infrastructure we built in previous videos. However, there is a key difference in this video: we will separate Singletons from the container and delve into the interface by writing unit tests.

Tests are not only a means of testing code; they also serve as valuable documentation. Open source projects often lack comprehensive documentation, but by examining the tests, you can gain insights into how different parts of the code are used. So, let’s dive into test automation!

Test Automation: Enhancing Game Engine Programming with Unit Tests
Test Automation: Enhancing Game Engine Programming with Unit Tests

Setting Up Unit Tests

To begin, let’s add a new project for our unit tests. We have several options, and while Google Test is a popular choice, we will use the Microsoft test framework to minimize friction. We can ignore the pre-compiled headers for now and focus on what matters.

Next, we need to add a reference to the core project, as it is the project we are testing. This ensures that the required dependencies are included, allowing for successful builds.

Running the Tests

To run the tests efficiently, we’ll use the test runner provided by the test framework. By navigating to the Test Explorer window, we can easily run and organize our tests. Running the tests from here will aggregate the results and allow us to track their status.

Further reading:  Designing a Custom Bathroom Sink: A Step-by-Step Guide

Writing Unit Tests

Now comes the exciting part—writing unit tests! In this video, we’ll demonstrate how to use the IOC container in our tests. We’ll create a fresh IOC container before each test runs to ensure independence and avoid interfering with the test data. We’ll also explore the use of assertions to check if the tests meet our expectations.

TEST_METHOD_INITIALIZE(Setup) {
    p_ioc = std::make_unique<IOCContainer>();
}

TEST_METHOD_CLEANUP(TearDown) {
    p_ioc.reset();
}

TEST_METHOD(SimpleResolveSuccess) {
    const auto expected = 69.0;
    const auto actual = p_ioc->Resolve();
    Assert::AreEqual(expected, actual);
}

TEST_METHOD(SimpleResolveFailure) {
    Assert::ExpectException<std::runtime_error>([] {
        p_ioc->ResolveBase();
    });
}

These are just a couple of examples of the tests we can write using the IOC container. Writing unit tests for our code can be initially time-consuming, but it pays off in terms of bug detection and future code refactoring.

Enhancing Test Development

To streamline our test development process, we can create a wrapper header file that disables specific warnings. By including this header file before the test framework header, we can maintain static analysis checks for our code while avoiding warnings from the test framework.

#pragma warning(push)
#pragma warning(disable : 26433)
#include "CppUnitTest.h"
#pragma warning(pop)

This allows us to focus on the warnings that matter for our code while ignoring warnings from external sources.

Conclusion

In this video, we explored the fundamentals of test automation and unit testing within the context of game engine programming. We learned how to set up unit tests, run them efficiently, and write tests for our IOC container.

Writing unit tests is an essential part of the software development process. It helps us catch bugs early, document our code, and ensure that changes to the codebase do not introduce unexpected issues. While writing unit tests may add some overhead, the benefits far outweigh the costs.

Further reading:  Beginner's Guide to Structures in C++

If you found this video helpful, please like and share it. Stay tuned for more exciting content on C++ game engine infrastructure.

YouTube video
Test Automation: Enhancing Game Engine Programming with Unit Tests