Appendix C: A development environment for unit testing

Note: the following instructions assume that you are connected to the Internet and that you are using GCC on a POSIX compatible operating system. All unix shell commands are assumed to be running from your home directory ($HOME). Finally, any command that begins with sudo assumes that you have administrative rights on your machine. If you do not — please ask your system administrator about installing the software you need.

Vim

Vim is a screen based text editor powerful enough to serve as a lightweight C++ IDE.

A .vimrc file placed in the user’s home directory contains configuration information used by vim when it starts. The “rc” at the end stands for “run command” (see RUNCOM). If you want to begin learning about vimrc files, Vimrc Configuration Guide - How to Customize Your Vim Code Editor with Mappings, Vimscript, Status Line, and More is a good place to start.

The following file is a reduced version of a vimrc file that will work well with this book:

" VIM Configuration File
" Description: created for C/C++ development, but useful for Python too
" Author: Bhaskar Tallamraju
" Original version: https://tbhaskar78.github.io/vimrc/
" Last modified by Jeff Elkner 13 Sept 2024 to remove things we don't use

" I like the desert theme the best
color desert
" turn syntax highlighting on
set t_Co=256
syntax on
" set the hightlight for search, with background black and red font
set hlsearch
hi Search ctermbg=black
hi Search ctermfg=Red

" Set no backup, avoids creating extra files by vim
set nobackup

"folding settings
" zc folds at the current place
" zM folds everything
" zR unfolds everything
" za toggle folding
set foldmethod=indent   "fold based on indent
set foldnestmax=10      "deepest fold is 10 levels
set nofoldenable        "dont fold by default
set foldlevel=2         "this is just what i use

" set UTF-8 encoding
set enc=utf-8
set fenc=utf-8
set termencoding=utf-8

" disable vi compatibility (emulation of old bugs)
set nocompatible
"enable filetype
filetype plugin on
" use indentation of previous line
set autoindent
" use intelligent indentation for C
set smartindent
" configure tabwidth and insert spaces instead of tabs
set tabstop=4        " tab width is 4 spaces
set shiftwidth=4     " indent also with 4 spaces
set expandtab        " expand tabs to spaces
" wrap lines at 80 chars.
set textwidth=80
" turn line numbers on
" set number
" highlight matching braces
set showmatch
" intelligent comments
set comments=sl:/*,mb:\ *,elx:\ */
" c++ indent
set cindent
set cinoptions=g0
retab
"enable python syntax
let python_highlight_all = 1

" Enhanced keyboard mappings
" switch between header/source with F4
map <F4> :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>

" Build gcc, g++ or python code from here <Shift F8>
autocmd FileType c nnoremap <buffer> <S-F8> :update<bar>!gcc -Werror % && ./a.out<CR>
autocmd FileType c nnoremap <buffer> <S-F9> :update<bar>!gcc -g -Werror % && gdb ./a.out<CR>
autocmd FileType cpp nnoremap <buffer> <S-F8> :update<bar>!g++ -Werror -std=c++17 % && ./a.out<CR>
autocmd FileType cpp nnoremap <buffer> <S-F9> :update<bar>!g++ -g -Werror % && gdb ./a.out<CR>
autocmd FileType python nnoremap <buffer> <S-F8> :update<bar>!python3 %<CR>

" Auto build using make with <F5>
map <F5> :make<CR>
" Auto build using make with <S-F7>
map <S-F9> :make clean all<CR>

Doctest

doctest is a C++ testing framework that is light on resources and easy to use, making it an ideal tool for beginners learning C++. It is introduced in Chapter 10 Exercise Set 2: Introducing DOCTEST and TDD and used in the exercises of each following chapter.

Configuring CPATH for Local Libraries

CPATH is an environment variable that specifies the search path that the preprocessor uses to look for somelibrary.h in a:

#include <somelibrary.h>

directive.

To set our CPATH, we need to:

  1. create a directory where C/C++ libraries will be stored.

  2. set the CPATH environment variable to the path to that directory.

On a Debian GNU/Linux system this can be accomplished by:

  1. running: $ mkdir -p ~/.local/lib/gcc/include

  2. adding the line:

    export CPATH=$HOME/.local/lib/gcc/include/
    

    to your .bashrc file

    Note

    MacOS users will have to add this to .zshrc instead.

After copying doctest.h to ~/.local/lib/gcc/include, you will now be able to simply add:

#include <doctest.h>

to any program in which you want to use doctest.

To test your configuration, add the following to a file named test_doctest.cpp:

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest.h>

TEST_CASE("testing doctest") {
    CHECK(2 == 1);
}

Then compile it and run it. Success will mean getting output like this:

test_doctest.cpp:4:
TEST CASE:  testing doctest

test_doctest.cpp:5: ERROR: CHECK( 2 == 1 ) is NOT correct!
  values: CHECK( 2 == 1 )

===============================================================================
[doctest] test cases: 1 | 0 passed | 1 failed | 0 skipped
[doctest] assertions: 1 | 0 passed | 1 failed |
[doctest] Status: FAILURE!

Note

doctest.h uses C++ language features from the C++11 standard. If your compiler is set to default to another C++ standard (as are the school issued MacBooks where I teach), you have to add --std=c++11 to the end of your compiler instruction to use doctest.