ソフトな忘却力(14) ラズパイでgtest、CMakeLists.txt書くだけでOK

Joseph Halfmoon

GoogleTest(gtest)は、C++用の単体テストツールとして定番ですが、遥か昔にちょっと使ったキリでとんとご無沙汰、すっかり忘却。おぼげな記憶によるとセットアップがメンドかった記憶が?今回ラズパイ上でやってみたら、まったくメンドくないです。CMakeLists.txtにチョイと仕込みを入れるだけで速攻テスト可能。テスト自体は書かないとダメだけどね。

今回 Raspberry Pi OS buster <32bit>上で GoogleTestをするにあたって参照させていただいたのは、GoogleTest User’s Guide 内の以下のページです。

Quickstart: Building with CMake

Quickstartには、CMake版以外にBazel版(Google様が推し?のビルドツール)もあるのですが、私はBazelよく分からない(CMakeも良く分からないのだけれど、Bazelよりはまだマシ?)のでCMakeの方を選択いたしました。「本シリーズ」は一応CMake指向ということで、ホントか?

さて、上記のQuickstartによるとGoogleTest(gtest)は、事前にgtestのライブラリなどインストールされていなくても、以下の5ステップで「可能」でした。

  1. CMakeLists.txtを書く
  2. 単体テストのソースコードを書く
  3. “cmake -S . -B build” コマンドを走らせる
  4. “cmake –build build” コマンドを走らせる
  5. build ディレクトリ内に単体テストの実行ファイルできているので走らせる

ミソは1のところですね。CMakeLists.txt内に「仕込み」を入れておくだけで、必要なgtestのライブラリなどが全てセットアップされて使えるようになりました。便利。こんな楽だったの。

まあ、2は自分がテストしたい対象次第なのでどのくらいの分量になるかはお好み次第ですが、3,4,5は機械的な作業。

今回ターゲットの単体テストコード

sampleFuncなる、かなりベタなサンプル関数をテストする、というのが今回のターゲットです。ソースコード、sampleFunc_test.cc はこんな感じ。わざとNGになるテスト項目も入れてみましたぜ。

#include <gtest/gtest.h>

int sampleFunc(int a, int b) {
    return a + b;
}

TEST(sampleFuncTest, BasicTest) {
    EXPECT_EQ( sampleFunc(3, 4), 7); //GOOD
    EXPECT_EQ( sampleFunc(1, 1), 3); //NG!
}

どこにも main 関数が存在しないですが、これはデフォルトの gtest_mainなるライブラリとリンクして面倒見てもらっているので省略可みたいです。テスト書くのもお楽。

CMakeLists.txt

さて、肝心の「仕込み」の入ったCMakeLists.txt が以下に。これは上記のQuickstartの例を sampleFunc_test用に改造させていただいたもの。

FetchContent_Declare() こそ「仕込み」の本体であります。

cmake_minimum_required(VERSION 3.14)
project(gtestTrial)
set(CMAKE_CXX_STANDARD 11)

include(FetchContent)
FetchContent_Declare(
    googletest
    URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

add_executable(
    sampleFunc_test
    sampleFunc_test.cc
)

target_link_libraries(
    sampleFunc_test
    gtest_main
)

include(GoogleTest)
gtest_discover_tests(sampleFunc_test)

CMakeのドキュメント FetchContent へのリンクはこちら。このドキュメントの中でも例にあがっているのが gtest なので CMakeで gtestのプロジェクトをビルドするならば「使わないではいられない」的なものみたいです。知らなかった。上記の記述を見れば分かるように、gtestの特定のバージョンを持ってきて使えるようにしてくれるみたい。これまたお楽。

cmakeする 

テスト用のソースファイルと、CMakeLists.txtだけが入っているディレクトリでCmakeをかけます。 “-S .” はカレントディレクトリがプロジェクトルートだぞ、と。”-B build”は、ビルドディレクトリのお名前は “build”だぞ(無かったら作ってね)と。初回はいろいろやることがあるのでこんな感じで以下大量に出力されます。

setupSTEP1

テスト用ソースを変更して2回目ともなると素っ気ないです。こんな感じでたったの3行でした。

setupSTEP1again

buildする

Cmakeはbuildツールではないので、Cmakeから buildせよ、と命じると多分Ninjaがやってきて始末してくる?のかな(少なくとも今回使用したラズパイ3上にはNinjaインストール済であります。)初回の様子がこちら。やはり初回は大量に出力されます。

setupSTEP2

ビルド後、buildディレクトリ配下にできたlibディレクトリ内を覗いてみるとこんな感じ。ちゃんと gtest のライブラリ群が出来ておりますぞ。

libs

なお、2回目以降ともなると、サクッとビルドされるだけとなります。

setupSTEP2again

 

テスト実行

以下は、Quickstartに書かれていた「例題ファイル」をビルド後実行したもの。全PASSで、あまり面白くありませぬ。本当にテストしてんのか?

testRUN

一方、前述の「わざとエラーをいれてある」ものがこちら。1+1は3だって、ウソでしょ、とFAILしてます。予定どおりだね。ちゃんと単体テストしているみたいだ。

testRUNagain

今回は、CMakeLists.txtに何行か書きたせば即 GoogleTest がかけられるということをようやく知ったと。またすぐに忘れるのでないの?

ソフトな忘却力(13) ラズパイsyslog、ファイル振り分け、UDPの許可 へ戻る

ソフトな忘却力(15) VSCodeで ctest+gtest、CMakeLists.txt へ進む