LoginSignup
2
5

More than 5 years have passed since last update.

CでgoogletestとCMakeを使ってみた

Last updated at Posted at 2017-10-16

C向けにgoogletestを使ってcmakeでビルドするサンプルです。

例は書籍 Test-Driven Development for Embedded Cテスト駆動開発による組み込みプログラミング のLED Driverのスケルトンとして使えます。

ディレクトリ構成

build/            ビルド用のディレクトリ
ext/
ext/googletest    googletestのソースコード
inc/              ヘッダ
src/        ソース
test/       テスト

googletestの準備

gitの初期化とgoogletestの取得を行う。

% git init
% mkdir build ext inc src test
% cd ext
% git submodule add https://github.com/google/googletest.git

googletest用のcmakeファイルを作成する。

CMakeLists.txt
project("led driver")
cmake_minimum_required(VERSION 2.8)
add_subdirectory(ext)
ext/CMakeLists.txt
option(BUILD_GTEST "Builds the googletest subproject" ON)
option(BUILD_GMOCK "Builds the googlemock subproject" OFF)
add_subdirectory(googletest)

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
-- Found PythonInterp: /usr/bin/python (found version "2.7.6")
-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sekine/github/leddriver2/build
$ make
Scanning dependencies of target gtest
[ 50%] Building CXX object ext/googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
Linking CXX static library libgtest.a
[ 50%] Built target gtest
Scanning dependencies of target gtest_main
[100%] Building CXX object ext/googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
Linking CXX static library libgtest_main.a
[100%] Built target gtest_main

ここまでの作業をgit commit しときます。

$ cd ..
$ git add CMakeLists.txt ext/CMakeLists.txt
$ git commit -m "setup googletest."

ソースコードの例

inc/LedDriver.h
#ifndef LEDDRIVER_H
#define LEDDRIVER_H

void LedDriver_Create(uint16_t *address);
void LedDriver_Destroy(void);
void LedDriver_TurnOn(int ledNumber);
void LedDriver_TurnOff(int ledNumber);

#endif
src/LedDriver.c
#include <stdint.h>
#include "LedDriver.h"

static uint16_t *ledsAddress;

void LedDriver_Create(uint16_t *address)
{
    ledsAddress = address;
    *ledsAddress = 0;
}

void LedDriver_Destroy(void)
{
}

void LedDriver_TurnOn(int ledNumber)
{
    *ledsAddress = 1;
}

void LedDriver_TurnOff(int ledNumber)
{
    *ledsAddress = 0;
}
test/LedDriverTest.cpp
#include <stdint.h>
#include "gtest/gtest.h"
extern "C"
{
#include "LedDriver.h"
}

uint16_t virtualleds;

class LedDriver : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        LedDriver_Create(&virtualleds);
    }
    virtual void TearDown()
    {
        LedDriver_Destroy();
    }
};

TEST_F(LedDriver, LedsOffAfterCreate)
{
    uint16_t virtualleds1 = 0xffff;
    LedDriver_Create(&virtualleds1);
    ASSERT_EQ(0, virtualleds1);
}

TEST_F(LedDriver, TurnOnLedOne)
{
    LedDriver_TurnOn(1);
    ASSERT_EQ(1, virtualleds);
}

TEST_F(LedDriver, TurnOffLedOne)
{
    LedDriver_TurnOn(1);
    LedDriver_TurnOff(1);
    ASSERT_EQ(0, virtualleds);
}

CMakeの設定です。

CMakeLists.txt
project("led driver")

cmake_minimum_required(VERSION 2.8)

add_subdirectory(ext)
add_subdirectory(src)
add_subdirectory(test)

ADD_CUSTOM_TARGET(check test/led_driver_test_app)
src/CMakeLists.txt
add_library(LedDriver LedDriver.c)
target_include_directories(LedDriver PUBLIC ../inc)
test/CMakeLists.txt
add_executable(led_driver_test_app
    LedDriverTest.cpp)
target_link_libraries(led_driver_test_app
    gtest
    gtest_main
    LedDriver)

実行例です。

$ cd build
$ cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sekine/github/leddriver2/build
$ make
[ 25%] Built target gtest
[ 50%] Built target gtest_main
[ 75%] Built target LedDriver
[100%] Built target led_driver_test_app
$ make check
Running main() from gtest_main.cc
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from LedDriver
[ RUN      ] LedDriver.LedsOffAfterCreate
[       OK ] LedDriver.LedsOffAfterCreate (0 ms)
[ RUN      ] LedDriver.TurnOnLedOne
[       OK ] LedDriver.TurnOnLedOne (0 ms)
[ RUN      ] LedDriver.TurnOffLedOne
[       OK ] LedDriver.TurnOffLedOne (0 ms)
[----------] 3 tests from LedDriver (0 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[  PASSED  ] 3 tests.
Built target check
$
2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5