TDD, GoogleTest, GitHub, Travis CI and Conan; the easy way!

Test-Driven Development (TDD) is a popular approach in developing code bases and there is a good reason for that. There are many books that explain the way and the advantages of adopting an approach like that. In today’s post, I’m not going to explain that again.  An amazing book that I can suggest is the “Modern C++ Programming with Test-Driven Development” by Jeff Langr.  My intention is to share a template of a way to do it in your everyday life.

So let’s imagine the situation. I developing a library. I use TDD via GoogleTest. What will make my life easier is to enable Continuous Integration (CI) in GitHub via Travis. All fine up to this point. But how I install GoogleTest in my image up to the cloud? Is there any easy way? Of course, it is and it is called Conan. Do you want to see the way?

In GitHub, an easy way to enable Travis CI is to add a file called “.travis.yml” in the root of your codebase. What to include on that? Let’s see:

language: cpp
dist: bionic
compiler: gcc
os: linux

script:
  - sudo apt-get update
  - sudo apt-get install python3-setuptools
  - sudo apt-get install python3-pip
  - pip3 install conan
  - mkdir -p build
  - conan profile new default --detect
  - conan profile update settings.compiler.libcxx=libstdc++11 default
  - conan install . -s build_type=Debug --install-folder=build --build=missing
  - chmod +x build.sh
  - ./build.sh

What are we doing here? First, we install Conan, create a default profile, enable modern C++ and install the GoogleTest library. For the latter we need the usual “conanfile.txt”, which looks like:

[requires]
gtest/1.10.0

[generators]
cmake

Easy, eh? What is next? There is a script that helps us to proceed with the building and testing. No rocket science there. The “build.sh” looks like:

#!/bin/bash

set -euo pipefail

cd build

# Configure
cmake -DCMAKE_BUILD_TYPE=Debug ..
# Build (for Make on Unix equivalent to `make -j $(nproc)`)
cmake --build . --target all --config Debug -- -j $(nproc)
cmake --build . --target soundex_test -- -j $(nproc)

All right, but now I think that the last piece of the puzzle is the CMakeLists.txt, how it looks like? How it engages Conan? How introduces testing? Let me show you:

cmake_minimum_required(VERSION 3.12)
project(Soundex)

set(CMAKE_CXX_STANDARD 14)

if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
    include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
    conan_basic_setup()
else()
    message(WARNING "The file conanbuildinfo.cmake doesn't exist, you have to run conan install first")
endif()

include_directories(include)

add_library(Soundex src/Soundex.cpp include/Soundex.h)

add_executable(soundex_test tests/Test.cpp)
target_link_libraries(soundex_test Soundex ${CONAN_LIBS})
add_test(soundex_test soundex_test)

Is it the only way to do something like that? Of course not. There are more advanced and sophisticated approaches. However, this is an easy to understand step by step development that helps you to understand the nitty-gritty. A complete repository (under development) that shows the big picture can be found here.

Enjoy it!