GitHub Actions で C/C++のテストを自動実行できるようにしてみた

どもです。

今回は、Google Testを使って実装されている単体テストを、GitHub Actionsで実行される環境を作成してみたので、その内容について書いてみます。

1. テスト対象コード

単体テストを自動実行できるようにするにあたり、まずテスト対象とするコードを決定してみます。
サンプルの関数をテキトーに作成してもよいのですが、今回は以下のリポジトリのあるコードを対象としてみることにしてみました。

Ev3MindStormCar

このコードの中でも、特に以下のフォルダに格納されたコードのいくつかを対象にしてみます。

dev/sdk/Ev3Car/src

※だいぶ昔に、LEGOのMindSTORMを動かすために作成したコードです。自分のコードなので、文句は言われない。

このコードをテストするにあたり、以下のようなフォルダ構成を作成します。

(work_space_root)
├─.github
│  └─workflows
└─dev
    ├─src
    │  ├─CLC
    │  │      CLC_TravelDistance.cpp
    │  │      CLC_TravelSpeed.cpp
    │  │      
    │  ├─include
    │  │      ev3api.h
    │  │      
    │  └─UTIL
    │          util.cpp
    │          util.h
    │          
    └─test
        ├─framework
        │  └─googletest
        └─src
            │  CMakeLists.txt
            │  
            ├─CLC
            │      CMakeLists.txt
            │      UTEST_TravelSpeed_calc_travel_speed.cpp
            │      UTEST_TravelSpeed_init_travel_speed.cpp
            │      
            └─UTIL
                    CMakeLists.txt
                    UTEST_util_init_buff.cpp
                    UTEST_util_limit_int.cpp

この構成の中で、dev/srcの下にテスト対象関数が実装されたソースコードが格納されています。
dev/test/srcの下に、単体テストのコードを配置しています。
このコードは、今回はGoogleTestを使用して実装しています。
単体テストのフレームワークであるGoogleTestは、dev/test/frameworkの下にヘッダファイル、およびライブラリを格納しています。

細かく記載すると長くなるので、本投稿では詳細を割愛します。
また、テストプログラムのビルドにcmakeを使用します。そのために必要なCMakeLists.txtも作成しています。
GoogleTestやcmake、CMakeLists.txt の内容はGitHub Actionsの本質ではないので、内容の説明は省略します。

ただ、/dev/test/srcの下、およびCLCやUTILの各フォルダにおいて、cmakeによるビルドができるようにしておく必要はあります。

2. GitHub Actionsの設定

開発環境、および作業環境の確認ができたので、次はGitHubActionsの設定を行います。
GitHubActionは、.github/workflows内に、拡張子が.ymlとなっているファイルに記述、定義します。
今回は、CMake_UTest.ymlという名前で作成します。

このファイルの内容は、以下の通りです。

name: CMake Unit Test

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y cmake g++ make

    - name: Configure
      run: cmake -S dev/test/src -B dev/test/src/build

    - name: Build
      run: cmake --build dev/test/src/build

    - name: Run tests (build root)
      run: cd dev/test/src/build && ctest --output-on-failure

    - name: Run tests (UTIL)
      working-directory: dev/test/src/build/UTIL
      run: ./UTEST_util --gtest_output=xml:utest_util_results.xml

    - name: Run tests (CLC)
      working-directory: dev/test/src/build/CLC
      run: ./UTEST_TravelSpeed --gtest_output=xml:utest_util_results.xml

2.1. 名前

先頭のnameは、GitHubActionsの名前を指定します。この値が、GitHubのサイトで表示されます。

2.2. 実行タイミング

GitHubActionsの実行タイミングは、on句の中で設定します。
今回の例は、pushあるいはpull_requestが行われた場合に実行されることを示しています。
また、対象のブランチも指定可能で、今回の例ではmainブランチが対象です。

2.3. 実行内容

実行する内容はjobsで設定します。

2.3.1. ジョブのID

今回の例では、build-and-testがIDに該当します。

2.3.2. 実行環境

runs-onで指定します。今回はubuntu-latestを使用。

2.3.3. 実際に実行される内容

steps内に記載します。
usesで再利用可能なアクションを呼び出し、runで実行コマンドを記述。
また、working-directoryで作業ディレクトリを指定できます。

3. 実行結果の確認

この設定が実行されると、GitHubActionsの画面に結果が表示されます。

GitHub Actions 実行結果

各stepを展開して、GoogleTestの出力を確認することも可能です。

GitHub Actions 実行結果

4. まとめ

今回は、GitHubActionsを設定して、リポジトリにpushされる度にテストが実行される環境の構築を行いました。
基本的な内容だけでも、自動テストの実行と結果確認が可能です。
設定も簡単で、紹介した設定だけでCI環境を構築できました。

CI環境はソフトウェア開発において必須です。これからもGitHubActionsを活用してCI環境を整えていきたいです。

今回の内容が、だれかの役に立てば幸いです。
ではっ!

ex. 公開しています。

今回の投稿の内容、および紹介を省略したコード類はGitHubに公開しています。
よろしければ、参考にしてください。