////
Copyright (c) 2024 The C++ Alliance, Inc. (https://cppalliance.org)

Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Official repository: https://github.com/boostorg/website-v2-docs
////
= Boost.Test Tutorial
:navtitle: Boost.Test Tutorial

This topic is a step-by-step tutorial on how to get going with the boost:test[] library. This is a very substantial library with lots of functions and documentation. It is valuable to understand the concept of adding tests to a simple program, before venturing further.

In this tutorial, we are using Microsoft Visual Studio, on Windows.

One question you may have is "what happens to the `main` function?" When using Boost.Test, the `main` function is  implicitly defined by the library. This is one of the features that Boost.Test offers to simplify the process of writing tests. This is done using the preprocessor directive `#define BOOST_TEST_MODULE`. There is the option for you to use your own custom `main` function, which we will come to in a later tutorial. The automatic generation of the `main` function does allow you to focus on writing the test cases themselves.

Let's get started with a trivial example.

== Trivial Example

Here's a very simple example of a test suite with Boost.Test:

. Use Visual Studio to create a C++ Console application, call it something like "Trivia".

. In the project *Properties* for *C++/General*, locate *Additional Include Directories* and add the path to your Boost libraries. The path will be something like `C:\Users\<your path>\boost_1_81_0`.

. Then, still in *Properties*, but now for *Linker/General* add to the *Additional Library Directories* with the path to your Boost lib folder. This path will be something like `C:\Users\<your path>\lib`.

. In the *Project* menu, select *Add New Item*, and locate *Boost.Test*. Add it to your project.

. Replace the boilerplate code of test.cpp with:

+
[source,cpp]
----
#define BOOST_TEST_MODULE MyTestSuite
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_CASE(MyTestCase)
{
    BOOST_CHECK(1 + 1 == 2);
}
----

. Comment out the `main` function. In this example, the `main` function is automatically generated by `#include <boost/test/included/unit_test.hpp>` when `BOOST_TEST_MODULE` is defined. 

. Run the program. You should get the `pass:[*** No errors detected]` message, as one plus one does equal two!

. Change the code to:

+
[source,cpp]
----
BOOST_AUTO_TEST_CASE(MyTestCase)
{
    BOOST_CHECK(1 + 1 == 3);
}
----

. Run the program. Do you now get a red error message!

This trivial example shows the two kinds of messages we might get. Now let's move onto something with a bit more meat.



== String Reversal Example

. Use Visual Studio to create a C++ Console application, call it something like "StringRev".

. In the project *Properties* for *C++/General*, locate *Additional Include Directories* and add the path to your Boost libraries. The path will be something like `C:\Users\<your path>\boost_1_81_0`.

. Then, still in *Properties*, but now for *Linker/General* add to the *Additional Library Directories* with the path to your Boost lib folder. This path will be something like `C:\Users\<your path>\lib`.

. Replace the boilerplate code in the .cpp file to:

+
[source,cpp]
----
#include <string>
#include <iostream>

std::string revString(std::string str)
{
    int n = (int) str.length();

    for (int i = 0; i < n / 2; i++) {
        std::swap(str[i], str[n - i - 1]);
    }
    return str;
}

int main(int argc, char* argv[])
{
    std::cout << revString("Reverse String Function") + "\n";
    std::cout << revString("Even") + "\n";
    std::cout << revString("Odd") + "\n";
}

----

. Run the program, and ensure you get the three strings reversed appearing in a Console window.

+
image::rev-string-test.png[]

. Good, now let's see how you would add Boost.Test functions to this.

. In the *Project* menu, select *Add New Item*, and locate *Boost.Test*. Add it to your project.

. Comment out your `main` function, as it will be replaced with the Boost.Test `main` function, whilst the tests are running.

. Add the following automatic tests to your .cpp file:

+
[source,cpp]
----

BOOST_AUTO_TEST_CASE(check_revString) {
    BOOST_TEST(revString("abcd") == "dcba");
    BOOST_TEST(revString("12345") == "54321");
    BOOST_TEST(revString("Even") == "nevE");

    // Add a failure case
    BOOST_TEST(revString("Odd") == "DDO");
}
----

. Run the program. Do you get one error: `check revString("Odd") == "DDO" has failed`?

. Correct the error by changing "DDO" to "ddO" in your code.

. Run the program again. Do you now get `pass:[*** No errors detected]`? If so great, the tests have worked.

. Perhaps add test cases to the `BOOST_AUTO_TEST_CASE` function, to check the case of an empty string, and for a single character string:

+
[source,cpp]
----
    BOOST_TEST(revString("a") == "a");
    BOOST_TEST(revString("") == "");
----

. Add and test any other strings that come to mind.

== Next Steps

You can imagine now how you can add unit tests to your existing projects, checking the correct working of many of your functions.

And check out the full functionality of boost:test[].
