PlatformIO でユニットテストが書きたい

先日、うっかりM5Paperを買ってしまったので、肥やしにならぬよう、ちょくちょくプログラムを書いているのだが、プロジェクト内で書いた自分のクラスをテストしたいと思った時に少しハマったので、解決策を書いておく。

前提

Arduino IDEは使わない。PlatformIOを使います。ビルドがめちゃくちゃ早いので(Arduino IDEが遅いとも言う)オススメ。

本旨とズレるが、PlatformIO Coreっていうのがあったんだな。PlatformIO IDEしかないのかと思って、VSCodeで書いてた……。

testフォルダ

最初、何も考えずにプロジェクト内のtestフォルダ内に、test_hoge.cppを置いて、以下のようなコードを書いたところうまくいった。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <Arduino.h>
#include <unity.h>

void test0()
{
TEST_ASSERT_TRUE(true);
}

void test1()
{
TEST_ASSERT_FALSE(false);
}

void setup()
{
UNITY_BEGIN();
RUN_TEST(test0);
RUN_TEST(test1);
UNITY_END();
}

void loop()
{
}

しかし、ここで既にあった自分のクラスをテストしたいと思って以下のようなコードを追加したら、テストコードのビルドが通らなくなった。

1
2
3
4
5
6
7
#include "test_class.h"

void test0()
{
auto t = new TestClass();
TEST_ASSERT_TRUE(t != nullptr);
}

test_build_project_src = yes

ドキュメントを確認すると、プロジェクト設定であるplatformio.iniに、test_build_project_srcという設定があり、それを有効にしないとsrcフォルダがビルドされないらしい(test_class.hincludeフォルダ、test_class.cppsrcフォルダにあった)。

なるほど、と思い有効にしてビルドしたが、今度はsetup()loop()が二重定義になってると怒られる。当たり前だ。

lib_dir

更にドキュメントを読んでいくと、Shared Codeと言うところに、本体とテストで共有するコードはlib_dirに置けとある。

なるほどなるほど、と思いtest_class.cpplibに移動して試すがダメ。test_class.hもか?と思い試すがダメ。

ちなみに、test_build_project_srcは無効にしている。

サンプル

更にドキュメントを精査すると、サンプルを見なさいと書いてあった。

自分のプロジェクトと比較すると、libフォルダ内の構成が全く違うことに気づいたので、サンプルに合わせたところ、バッチリうまくいった。

結論

最終的なプロジェクト構成は以下のようになった。

ポイントは二つ。

  • libの中は、lib/$(好きなモジュール名)/srcに共有するコードを入れる。ヘッダも一緒に入れちゃっておk。共有ヘッダの#include<>
  • testの中は、test/$(テストケース名)にテストコードを入れる。

今回はやってないけど、テストケースの設定で、実際にデバイスに送って実行するテスト以外に、ホストPCで実行するテストとかも書けるみたい。