mirror of
https://github.com/ttroy50/cmake-examples.git
synced 2025-12-18 20:24:35 +03:00
add unit testing folder
This commit is contained in:
26
05-unit-testing/README.adoc
Normal file
26
05-unit-testing/README.adoc
Normal file
@@ -0,0 +1,26 @@
|
||||
= Unit Testing
|
||||
|
||||
:toc:
|
||||
:toc-placement!:
|
||||
|
||||
toc::[]
|
||||
|
||||
[[intro]]
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Unit testing is a software development process in which the smallest testable parts of an
|
||||
application, called units, are individually and independently scrutinized
|
||||
for proper operation. This can involve taking a class, function, or algorithm
|
||||
and writing test cases that can be run to verify that the unit is working correctly.
|
||||
|
||||
CMake includes a tool called link:https://cmake.org/Wiki/CMake/Testing_With_CTest[CTest]
|
||||
which allows you to enable the `make test` target to run automated tests such as unit tests.
|
||||
|
||||
There are many unit-testing frameworks available which can be used to help automate
|
||||
and ease the development of unit tests. In these examples I show how to use
|
||||
some of these frameworks and call them using the CMake testing utility CTest.
|
||||
|
||||
The examples here include using the following frameworks:
|
||||
|
||||
* http://www.boost.org/doc/libs/1_56_0/libs/test/doc/html/utf/user-guide.html[Boost Unit Test Framework]
|
||||
40
05-unit-testing/boost/CMakeLists.txt
Normal file
40
05-unit-testing/boost/CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# Set the project name
|
||||
project (boost_unit_test)
|
||||
|
||||
|
||||
# find a boost install with the libraries unit_test_framework
|
||||
find_package(Boost 1.49.1 REQUIRED COMPONENTS unit_test_framework)
|
||||
|
||||
set (SOURCES
|
||||
Reverse.cpp
|
||||
Palindrome.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# Add an library for the example classes
|
||||
add_library(example_boost_unit_test ${SOURCES})
|
||||
|
||||
|
||||
#############################################
|
||||
# Unit tests
|
||||
|
||||
# enable CTest testing
|
||||
enable_testing()
|
||||
|
||||
# Add a testing executable
|
||||
add_executable(unit_tests unit_tests.cpp)
|
||||
|
||||
target_link_libraries(unit_tests
|
||||
example_boost_unit_test
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
)
|
||||
|
||||
add_definitions (-DBOOST_TEST_DYN_LINK)
|
||||
|
||||
add_test(test_all unit_tests)
|
||||
11
05-unit-testing/boost/Palindrome.cpp
Normal file
11
05-unit-testing/boost/Palindrome.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "Palindrome.h"
|
||||
|
||||
bool Palindrome::isPalindrome(const std::string& toCheck)
|
||||
{
|
||||
|
||||
if (toCheck == std::string(toCheck.rbegin(), toCheck.rend())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
15
05-unit-testing/boost/Palindrome.h
Normal file
15
05-unit-testing/boost/Palindrome.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __PALINDROME_H__
|
||||
#define __PALINDROME_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Trivial class to check if a string is a palindrome.
|
||||
*/
|
||||
class Palindrome
|
||||
{
|
||||
public:
|
||||
bool isPalindrome(const std::string& toCheck);
|
||||
};
|
||||
|
||||
#endif
|
||||
161
05-unit-testing/boost/README.adoc
Normal file
161
05-unit-testing/boost/README.adoc
Normal file
@@ -0,0 +1,161 @@
|
||||
= Boost Unit Testing Framework
|
||||
:toc:
|
||||
:toc-placement!:
|
||||
|
||||
toc::[]
|
||||
|
||||
|
||||
# Introduction
|
||||
|
||||
Using link:https://cmake.org/Wiki/CMake/Testing_With_CTest[CTest] you can generate
|
||||
a `make test` target to run automated unit-tests. This example shows how to
|
||||
find the link:http://www.boost.org/doc/libs/1_56_0/libs/test/doc/html/utf/user-guide.html[boost unit-test-framework],
|
||||
create tests and run them.
|
||||
|
||||
The files in this tutorial are below:
|
||||
|
||||
```
|
||||
$ tree
|
||||
.
|
||||
├── CMakeLists.txt
|
||||
├── Reverse.h
|
||||
├── Reverse.cpp
|
||||
├── Palindrome.h
|
||||
├── Palindrome.cpp
|
||||
├── unit_tests.cpp
|
||||
```
|
||||
|
||||
* CMakeLists.txt - Contains the CMake commands you wish to run
|
||||
* Reverse.h / .cpp - Class to reverse a string
|
||||
* Palindrome.h / .cpp - Class to test if a string is a palindrome
|
||||
* unit_test.cpp - Unit Tests using boost unit test framework
|
||||
|
||||
# Requirements
|
||||
|
||||
This example requires the boost libraries to be installed in a default system
|
||||
location. The library in use is the boost unit-test-framework.
|
||||
|
||||
# Concepts
|
||||
|
||||
## Enabling testing
|
||||
|
||||
To enable testing you must include the following line in your top level CMakeLists.txt
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
enable_testing()
|
||||
----
|
||||
|
||||
This will enable testing for the current folder and all folders below it.
|
||||
|
||||
## Adding a testing executable
|
||||
|
||||
The requirement for this step will depend on your unit-test framework. In the example
|
||||
of boost, you can create binary(s) which includes all the unit tests that you want to run.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_executable(unit_tests unit_tests.cpp)
|
||||
|
||||
target_link_libraries(unit_tests
|
||||
example_boost_unit_test
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
)
|
||||
|
||||
add_definitions (-DBOOST_TEST_DYN_LINK)
|
||||
----
|
||||
|
||||
In the above code, a unit test binary is added, which links against the boost unit-test-framework
|
||||
and includes a definition to tell it that we are using dynamic linking.
|
||||
|
||||
## Add A test
|
||||
|
||||
To add a test you call the link:https://cmake.org/cmake/help/v3.0/command/add_test.html[`add_test()`] function.
|
||||
This will create a named test which will run the supplied command.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_test(test_all unit_tests)
|
||||
----
|
||||
|
||||
In this example, we create a test called `test_all` which will run the executable
|
||||
created by the `unit_tests` executable created from the call to `add_executable`
|
||||
|
||||
# Building the Example
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ mkdir build
|
||||
|
||||
$ cd build/
|
||||
|
||||
$ cmake ..
|
||||
-- The C compiler identification is GNU 4.8.4
|
||||
-- The CXX compiler identification is GNU 4.8.4
|
||||
-- Check for working C compiler: /usr/bin/cc
|
||||
-- Check for working C compiler: /usr/bin/cc -- works
|
||||
-- Detecting C compiler ABI info
|
||||
-- Detecting C compiler ABI info - done
|
||||
-- Check for working CXX compiler: /usr/bin/c++
|
||||
-- Check for working CXX compiler: /usr/bin/c++ -- works
|
||||
-- Detecting CXX compiler ABI info
|
||||
-- Detecting CXX compiler ABI info - done
|
||||
-- Boost version: 1.54.0
|
||||
-- Found the following Boost libraries:
|
||||
-- unit_test_framework
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
|
||||
|
||||
$ make
|
||||
Scanning dependencies of target example_boost_unit_test
|
||||
[ 33%] Building CXX object CMakeFiles/example_boost_unit_test.dir/Reverse.cpp.o
|
||||
[ 66%] Building CXX object CMakeFiles/example_boost_unit_test.dir/Palindrome.cpp.o
|
||||
Linking CXX static library libexample_boost_unit_test.a
|
||||
[ 66%] Built target example_boost_unit_test
|
||||
Scanning dependencies of target unit_tests
|
||||
[100%] Building CXX object CMakeFiles/unit_tests.dir/unit_tests.cpp.o
|
||||
Linking CXX executable unit_tests
|
||||
[100%] Built target unit_tests
|
||||
|
||||
$ make test
|
||||
Running tests...
|
||||
Test project /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
|
||||
Start 1: test_all
|
||||
1/1 Test #1: test_all ......................... Passed 0.00 sec
|
||||
|
||||
100% tests passed, 0 tests failed out of 1
|
||||
|
||||
Total Test time (real) = 0.01 sec
|
||||
$ make test
|
||||
Running tests...
|
||||
Test project /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
|
||||
Start 1: test_all
|
||||
1/1 Test #1: test_all ......................... Passed 0.00 sec
|
||||
|
||||
100% tests passed, 0 tests failed out of 1
|
||||
|
||||
Total Test time (real) = 0.01 sec
|
||||
----
|
||||
|
||||
If the code is changed and it causes the unit tests to produce an error.
|
||||
Then when running the tests you will see the following output.
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ make test
|
||||
Running tests...
|
||||
Test project /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
|
||||
Start 1: test_all
|
||||
1/1 Test #1: test_all .........................***Failed 0.00 sec
|
||||
|
||||
0% tests passed, 1 tests failed out of 1
|
||||
|
||||
Total Test time (real) = 0.00 sec
|
||||
|
||||
The following tests FAILED:
|
||||
1 - test_all (Failed)
|
||||
Errors while running CTest
|
||||
make: *** [test] Error 8
|
||||
|
||||
----
|
||||
12
05-unit-testing/boost/Reverse.cpp
Normal file
12
05-unit-testing/boost/Reverse.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "Reverse.h"
|
||||
|
||||
std::string Reverse::reverse(std::string& toReverse)
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
for(std::string::reverse_iterator rit=toReverse.rbegin(); rit!=toReverse.rend(); ++rit)
|
||||
{
|
||||
ret.insert(ret.end(), *rit);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
15
05-unit-testing/boost/Reverse.h
Normal file
15
05-unit-testing/boost/Reverse.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __REVERSE_H__
|
||||
#define __REVERSE_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Trivial class whose only function is to reverse a string.
|
||||
* Should use std::reverse instead but want to have example with own class
|
||||
*/
|
||||
class Reverse
|
||||
{
|
||||
public:
|
||||
std::string reverse(std::string& toReverse);
|
||||
};
|
||||
#endif
|
||||
24
05-unit-testing/boost/main.cpp
Normal file
24
05-unit-testing/boost/main.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <iostream>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::cout << "Hello Third Party Include!" << std::endl;
|
||||
|
||||
// use a shared ptr
|
||||
boost::shared_ptr<int> isp(new int(4));
|
||||
|
||||
// trivial use of boost filesystem
|
||||
boost::filesystem::path path = "/usr/share/cmake/modules";
|
||||
if(path.is_relative())
|
||||
{
|
||||
std::cout << "Path is relative" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Path is not relative" << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
46
05-unit-testing/boost/unit_tests.cpp
Normal file
46
05-unit-testing/boost/unit_tests.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <string>
|
||||
#include "Reverse.h"
|
||||
#include "Palindrome.h"
|
||||
|
||||
#define BOOST_TEST_MODULE VsidCommonTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( reverse_tests )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( simple )
|
||||
{
|
||||
std::string toRev = "Hello";
|
||||
|
||||
Reverse rev;
|
||||
std::string res = rev.reverse(toRev);
|
||||
|
||||
BOOST_CHECK_EQUAL( res, "olleH" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( empty )
|
||||
{
|
||||
std::string toRev;
|
||||
|
||||
Reverse rev;
|
||||
std::string res = rev.reverse(toRev);
|
||||
|
||||
BOOST_CHECK_EQUAL( res, "" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( palindrome_tests )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( is_palindrome )
|
||||
{
|
||||
std::string pal = "mom";
|
||||
Palindrome pally;
|
||||
|
||||
BOOST_CHECK_EQUAL( pally.isPalindrome(pal), true );
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user