Google Test and Google Benchmark Libraries

Learn about the Google Test and Benchmark libraries.

Learning instruments

In this course, we will be using the Google Test and Benchmark libraries as our learning instruments. Let’s go through them in detail.

Google Test library

Google Test is a C++ unit testing framework that allows developers to write and run automated tests for their C++ code. It provides a simple and flexible syntax for defining test cases and test suites, as well as a wide range of assertions for verifying the correctness of test results.

Using Google Test can help developers catch bugs early in the development process, improve code quality, and increase confidence in the codebase. By writing tests covering different scenarios and edge cases, developers can ensure that their code behaves correctly under various conditions.

In this course, Google Test plays a crucial role. It allows us to validate our code in real time, ensuring it behaves as expected in various scenarios. This proactive approach helps us minimize potential errors, promoting efficient and high-quality code development. By learning to use Google Test, you’ll gain exposure to a widely-used industry framework, preparing you for real-world software development.

We can add the library in the code like this #include <gtest/gtest.h>.

  1. Defining test cases: Developers define test cases by writing test code that exercises the functionality of the code under test. Test cases are organized into test suites, which are collections of related test cases.

  2. Writing assertions: Developers use Google test’s assertion macros to write test code that checks the expected behavior of the code under test. The assertion macros compare expected results with actual results and report any failures.

  3. Running tests: Developers use the Google test framework to run the defined test cases. The framework reports the results of the tests, including any failures, and provides statistics on test coverage.

Let’s see an example below:

Press + to interact
#include <gtest/gtest.h>
bool IsEven(int num) {
return num % 2 == 0;
}
TEST(TestingCode, IsEvenTest) {
ASSERT_TRUE(IsEven(4)); // Assertion succeeds since 4 is even
ASSERT_FALSE(IsEven(7)); // Assertion succeeds since 7 is not even
ASSERT_TRUE(IsEven(5)); // Assertion fails since 5 is not even
}
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Explanation

Line 1: Including the necessary header file gtest.h, which contains the Google test framework’s functionality.

Lines 3–5: The function, IsEven, takes an integer num as a parameter and checks if it is even. It returns true if the number is even and false otherwise.

Lines 7–10: This block defines a test case named IsEvenTest inside the TestingCode test suite. It contains three assertions using the ASSERT_TRUE and ASSERT_FALSE macros provided by Google Test.

  • The first assertion checks if IsEven(4) returns true. Since 4 is even, the assertion succeeds.
  • The second assertion checks if IsEven(7) returns false. Since 7 is not even, the assertion succeeds.
  • The third assertion checks if IsEven(5) returns true. Since 5 is not even, the assertion fails.

Google Benchmark library

Google Benchmark, on the other hand, is a C++ micro benchmarking framework that allows developers to measure the performance of their code. It provides a simple, easy-to-use API for defining and running benchmarks in a controlled environment.

Using Google Benchmark can help developers identify performance bottlenecks in their code and optimize it for speed and efficiency. By measuring the performance of different implementations and comparing the results, developers can make informed decisions about which approach to use for a given task.

It provides us the ability to quantify the performance of our code, a critical aspect of high-performance programming. As we tackle performance-critical topics, you’ll be using Google Benchmark to measure and understand the implications of your design and implementation choices. Learning to identify bottlenecks and optimize your code will arm you with the skills necessary to write high-performance C++ applications.

We can add the library in the code like this #include <benchmark/benchmark.h>.

  1. Defining benchmarks: Developers define benchmarks by writing benchmark code that measures the performance of a specific function or piece of code. The benchmark code is run multiple times to obtain statistical data on its performance.

  2. Configuring benchmarks: Developers can configure the benchmark environment to control factors such as input size, number of iterations, and statistical analysis options.

  3. Running benchmarks: Developers use the Google Benchmark framework to run the defined benchmarks. The framework measures the performance of the benchmark code and provides statistical data on its performance, including mean, median, and standard deviation.

Press + to interact
#include <benchmark/benchmark.h>
// The function to be benchmarked
int Fibonacci(int n) {
if (n <= 1)
return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
// The benchmark function
static void BM_Fibonacci(benchmark::State& state) {
// Perform setup here
int n = state.range(0);
for (auto _ : state) {
// This code gets timed
int result = Fibonacci(n);
benchmark::DoNotOptimize(result);
}
}
// Register the benchmark
BENCHMARK(BM_Fibonacci)->Arg(10)->Arg(20)->Arg(30);
// Run the benchmark
BENCHMARK_MAIN();

Explanation

Line 1: Including the header file for using the Google benchmark library.

Lines 4–8: Implementation of Fibonacci function

Lines 11–20: The function BM_Fibonacci is the benchmark function. It takes a benchmark::State object as a parameter, which provides information about the benchmark’s state. Inside the function, it extracts the input value n from the benchmark state using state.range(0). Then, it enters a loop controlled by the state object.

Each loop iteration calls the Fibonacci function with the input n and stores the result in the result variable. The benchmark::DoNotOptimize(result) call is used to prevent the compiler from optimizing away the computation of result, ensuring that the benchmark accurately measures the performance.

Line 23: This line registers the BM_Fibonacci benchmark function with the Google Benchmark framework. It specifies three different argument values for n: 10, 20, and 30. These values represent the input sizes for benchmarking the Fibonacci function’s performance.

Line 26: BENCHMARK_MAIN() defines the entry point for the benchmarking program. It initializes the benchmarking framework and runs all the registered benchmarks.

Note: The course utilizes these libraries to execute the code on the platform, and you will see it in pretty much all the lessons as the course progress, but the purpose of the course is to get them hands-on with the modern C++ syntax and concepts and not testing the codes.