-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add support for GTest based unit tests. #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3aa409d
37d83a9
335d67b
289889d
f50c919
0d971fd
aad55e9
3de932e
1cafd58
7ed4a95
cc5ce7e
914bfb1
18bf4e1
4660646
d4ba15d
6a209b9
0806e80
969426f
fb279be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,3 +44,7 @@ rules.ninja | |
# out-of-source build top-level folders. | ||
build/ | ||
_build/ | ||
|
||
# in-source dependancies | ||
/googletest/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,31 @@ IRC channel: https://freenode.net #googlebenchmark | |
[Additional Tooling Documentation](docs/tools.md) | ||
|
||
|
||
## Building | ||
|
||
The basic steps for configuring and building the library look like this: | ||
|
||
```bash | ||
$ git clone https://github.com/google/benchmark.git | ||
# Benchmark requires GTest as a dependency. Add the source tree as a subdirectory. | ||
$ git clone https://github.com/google/googletest.git benchmark/googletest | ||
$ mkdir build && cd build | ||
$ cmake -G <generator> [options] ../benchmark | ||
# Assuming a makefile generator was used | ||
$ make | ||
``` | ||
|
||
Note that Google Benchmark requires GTest to build and run the tests. This | ||
dependency can be provided three ways: | ||
|
||
* Checkout the GTest sources into `benchmark/googletest`. | ||
* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during | ||
configuration, the library will automatically download and build any required | ||
dependencies. | ||
* Otherwise, if nothing is done, CMake will use `find_package(GTest REQUIRED)` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be the default, no? ie, why do we have it required to have it in-tree instead of just letting cmake do the right thing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
to resolve the required GTest dependency. | ||
|
||
|
||
## Installation Guide | ||
|
||
For Ubuntu and Debian Based System | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
|
||
macro(split_list listname) | ||
string(REPLACE ";" " " ${listname} "${${listname}}") | ||
endmacro() | ||
|
||
macro(build_external_gtest) | ||
include(ExternalProject) | ||
set(GTEST_FLAGS "") | ||
if (BENCHMARK_USE_LIBCXX) | ||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") | ||
list(APPEND GTEST_FLAGS -stdlib=libc++) | ||
else() | ||
message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++") | ||
endif() | ||
endif() | ||
if (BENCHMARK_BUILD_32_BITS) | ||
list(APPEND GTEST_FLAGS -m32) | ||
endif() | ||
if (NOT "${CMAKE_CXX_FLAGS}" STREQUAL "") | ||
list(APPEND GTEST_FLAGS ${CMAKE_CXX_FLAGS}) | ||
endif() | ||
string(TOUPPER "${CMAKE_BUILD_TYPE}" GTEST_BUILD_TYPE) | ||
if ("${GTEST_BUILD_TYPE}" STREQUAL "COVERAGE") | ||
set(GTEST_BUILD_TYPE "DEBUG") | ||
endif() | ||
split_list(GTEST_FLAGS) | ||
ExternalProject_Add(googletest | ||
EXCLUDE_FROM_ALL ON | ||
GIT_REPOSITORY https://github.com/google/googletest.git | ||
GIT_TAG master | ||
PREFIX "${CMAKE_BINARY_DIR}/googletest" | ||
INSTALL_DIR "${CMAKE_BINARY_DIR}/googletest" | ||
CMAKE_CACHE_ARGS | ||
-DCMAKE_BUILD_TYPE:STRING=${GTEST_BUILD_TYPE} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since all this is just to propagate the current params, maybe it would be simpler to just use 2-step approach? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've looked into 2 step approaches, but I think that they're less idiomatic CMake. |
||
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} | ||
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} | ||
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> | ||
-DCMAKE_CXX_FLAGS:STRING=${GTEST_FLAGS} | ||
-Dgtest_force_shared_crt:BOOL=ON | ||
) | ||
|
||
ExternalProject_Get_Property(googletest install_dir) | ||
|
||
add_library(gtest UNKNOWN IMPORTED) | ||
add_library(gtest_main UNKNOWN IMPORTED) | ||
|
||
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") | ||
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}") | ||
|
||
if("${GTEST_BUILD_TYPE}" STREQUAL "DEBUG") | ||
set(LIB_SUFFIX "d${CMAKE_STATIC_LIBRARY_SUFFIX}") | ||
endif() | ||
file(MAKE_DIRECTORY ${install_dir}/include) | ||
set_target_properties(gtest PROPERTIES | ||
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest${LIB_SUFFIX} | ||
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include | ||
) | ||
set_target_properties(gtest_main PROPERTIES | ||
IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}gtest_main${LIB_SUFFIX} | ||
INTERFACE_INCLUDE_DIRECTORIES ${install_dir}/include | ||
) | ||
add_dependencies(gtest googletest) | ||
add_dependencies(gtest_main googletest) | ||
set(GTEST_BOTH_LIBRARIES gtest gtest_main) | ||
#set(GTEST_INCLUDE_DIRS ${install_dir}/include) | ||
endmacro(build_external_gtest) | ||
|
||
if (BENCHMARK_ENABLE_GTEST_TESTS) | ||
if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/googletest) | ||
add_subdirectory(${CMAKE_SOURCE_DIR}/googletest) | ||
set(GTEST_BOTH_LIBRARIES gtest gtest_main) | ||
elseif(BENCHMARK_DOWNLOAD_DEPENDENCIES) | ||
build_external_gtest() | ||
else() | ||
find_package(GTest REQUIRED) | ||
endif() | ||
endif() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
//===---------------------------------------------------------------------===// | ||
// statistics_test - Unit tests for src/statistics.cc | ||
//===---------------------------------------------------------------------===// | ||
|
||
#include "../src/statistics.h" | ||
#include "gtest/gtest.h" | ||
|
||
namespace { | ||
TEST(StatisticsTest, Mean) { | ||
std::vector<double> Inputs; | ||
{ | ||
Inputs = {42, 42, 42, 42}; | ||
double Res = benchmark::StatisticsMean(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 42.0); | ||
} | ||
{ | ||
Inputs = {1, 2, 3, 4}; | ||
double Res = benchmark::StatisticsMean(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 2.5); | ||
} | ||
{ | ||
Inputs = {1, 2, 5, 10, 10, 14}; | ||
double Res = benchmark::StatisticsMean(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 7.0); | ||
} | ||
} | ||
|
||
TEST(StatisticsTest, Median) { | ||
std::vector<double> Inputs; | ||
{ | ||
Inputs = {42, 42, 42, 42}; | ||
double Res = benchmark::StatisticsMedian(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 42.0); | ||
} | ||
{ | ||
Inputs = {1, 2, 3, 4}; | ||
double Res = benchmark::StatisticsMedian(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 2.5); | ||
} | ||
{ | ||
Inputs = {1, 2, 5, 10, 10}; | ||
double Res = benchmark::StatisticsMedian(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 5.0); | ||
} | ||
} | ||
|
||
TEST(StatisticsTest, StdDev) { | ||
std::vector<double> Inputs; | ||
{ | ||
Inputs = {101, 101, 101, 101}; | ||
double Res = benchmark::StatisticsStdDev(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 0.0); | ||
} | ||
{ | ||
Inputs = {1, 2, 3}; | ||
double Res = benchmark::StatisticsStdDev(Inputs); | ||
EXPECT_DOUBLE_EQ(Res, 1.0); | ||
} | ||
} | ||
|
||
} // end namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd highly recommend
/usr/src/googletest/
, since that is the natural location, and is where debian puts it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, I don't really care to allow users to specify random/arbirtrary out-of-tree GTest source directories. We already have a mechanism to allow users to specify arbitrary GTest installation using
CMAKE_MODULE_PATH
to influencefind_package(GTest)
.I've changed the build, as you've suggested, to only download dependencies if
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
is specified. So GTest installations among/usr/
and/usr/local/
should work by default.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not git submodules?