*

Eclipseで単体テストするときの注意点(?)

公開日: : 最終更新日:2020/03/25 HACK, 開発

どもです。

今回のエントリは、Eclipse/cygwinで単体テストを行う際にハマってしまった内容について書きます。
単体テストの対象としているのは、ここ最近作成しているライブラリです

なお、開発は以下の環境で開発を行っています。
(今更ですが…)

項目スペック
OSWindows10 Pro(ver.1903)
CPUi7-8700
コンパイラgcc/cygwin
開発環境Eclipse Version:2019-06(4.12.0)
メモリ16GB

作成しているライブラリについては、下記のエントリを参照して下さい。
ライブラリでRasPiのピンにアクセス(1)-ライブラリを作ります
ライブラリでRasPiのピンにアクセス(2)-ライブラリを作ります
ライブラリでRasPiのピンにアクセス(3)-ライブラリを作ります

1.今回のテーマ

今回のテーマは、「単体テスト」です。

実装した各クラスの単体テストを行っていたのですが、この単体テストのコードが期待した通りに動かずテストができない、という状況に陥りました。
今回のエントリでは、この「状況」の原因と、その解決策について書きます。

2.発生した状況

一部ですが、具体例を示しながら状況を説明します。

2.1.基本的なフォルダ構成

現在、以下のようなフォルダ構成で開発を行っています。
raspiberrypi_gpio_lib_ex_001_001
ノートPCががEclipseのワークスペース、CPart_UTestとRaspiGpioLibraryがEclipseのプロジェクトに、それぞれ対応しています。
RaspiGpioLibraryのCPartクラスの単体テストを、CPart_UTestプロジェクトで行う、という構成になっています。
ここで、CPartの単体テストを行う際に、そのプロジェクトであるCPart_UTestにCPartクラスのソースコード(.cppと.h)を「リンクする」形式で取り込んでいました。
CPartクラスのソースコードはRaspiGpioLibrary/srcに配置されており、テストコードはCPart_UTest/srcに配置される、という構成です。

2.2.問題となった状況

問題となったのは、CPartの単体テストで作成したCGpioのスタブです。
CPart本体はCGpio.hをインクルードするのですが、これがRaspiGpioLibrary/srcにある「CGpio.h」をインクルードします。
しかしCGpioのスタブはCPart_UTest/srcにあり、テストコードはこちらをインクルードします。
1つのプロジェクトで、CGpio.hが複数存在し、かつファイルによってインクルードするファイルが異なる、という現状況が発生します。
raspiberrypi_gpio_lib_ex_001_002
これに対して、ビルドに使用されるCGpioのクラス/ソースコードは1つ(ここでは、CPart_UTest/srcに配置された「スタブ」)です。
即ち、「クラスの宣言と定義で齟齬がある」という状況です。
これが、問題なのです。
raspiberrypi_gpio_lib_ex_001_003

2.3.何が起きる?

私の環境では、「関数が、期待通りに呼び出されない」という現象が発生しました。
例えば、CPartでCGpioのメソッドAを呼び出す処理があった場合、本来であればスタブのメソッドAを呼び出したいにも関わらず、スタブのメソッドBが呼び出される、という現象です。

詳細な原因は調べられていませんが、先にも書いた通り、「クラスの宣言と定義で齟齬がある」ことが原因と考えています。

3.解決策

残念ながら、上記の現象の詳細な解析はできていません。
なので、ここで紹介する対処方法は、根本的な原因の解決にはならないかと思います。
…というか、なっていません。
その点を理解して、読み進めてください。

3.1.何をした?

対策として、テスト対象のソースコード(CPart.cpp/.h)を「リンクする」から、「コピーする」方式に変えました。
こうすることで、テスト対象のソースコードが参照/インクルードするCGpioのファイルがスタブのものになり、結果として期待する通りの関数呼び出しが行われるようになります。

3.2.更新した場合は?

しかしこの対応では、RaspiGpioLibrary/srcのCPartを更新したら、それを逐次CPartの単体テスト環境(CPart_UTest/src)にコピーしなければならない、という作業が新たに発生します。
この作業を忘れてしまうと、更新されていないコードに対して単体テストを行うだけで、まったく意味がありません。
忘れてしまうと、致命的な間違いになってしまいます。

3.3.ではどうする?

今回は、Eclipseの機能を使って対応することにしました。
CPart_UTestプロジェクトのプロパティダイアログを開いて、[C/C++ビルド]-[設定]-[ビルド・ステップ]タブを開きます。
表示された画面において、「ビルド前のステップ」にファイルのコピーを実行する処理を記載します。
eclipse_post_build_cp_001
これにより、ビルドを実行する前に、必ずRaspiGpioLibrary/src/のCPart.cpp/.hが、テストフォルダにコピーされるようになり、「コピー忘れ」の発生を回避できます。

4.まとめ

このエントリ、分かりにくい内容になっているかと思います。
それでも、Eclipseで単体テストを行っている、またはこれから行おうという方の助けになれることを願っています。

ではっ!

関連記事

c_sharp_eye_catch

セル内の「取り消し線で消された文字列」を削除してみた

どもです。 今回は、C#/OpenXmlの組み合わせで、エクセルのセル内の文字列から 「取り

記事を読む

RasPi_Qt

QtでRaspberryPi/GUI開発(6):pigpioを使用したチャタリング対策

どもです。 前回のエントリーで、pigpioを使用したボタンを使用したLEDの点灯/消灯について書

記事を読む

c_sharp_eye_catch

外部からMariaDbにアクセスする(1)-データベースの設定

どもです。 今回は、Linux上のMariaDbにWindowsからアクセスしてデータを取得で

記事を読む

think_about_utest

middle_unit
最小…よりも(ほんの)少し大きいテストフレームワーク

どもです。 今回は、単体テストのフレームワークについて書きます。 1.最小のフレームワーク

記事を読む

GitHub

Windowsでのカバレッジ測定-OpenCppCoverageを使ってみた(1)

どもです。 ここ最近、Windows上で開発を行っています。 その際に、当然単体テストを行うので

記事を読む

iot_at_home_eye_catch

IoT開発(14)
ESP-WROOM-02の稼働時間を延ばす工夫をしてみる

どもです。この記事は、以下の続きです。 IoT開発(4)-ESP-WROOM-02を電池で駆動

記事を読む

no image

C言語でEV3開発(7)

どもです。 今回のエントリーでは、いよいよEV3を動かしていきます。 新しい環境に対して、最もよ

記事を読む

eclipse-juno-logo

C言語でEV3開発(2)

どもです。 今回のエントリーの内容は、前回に引き続き「EV3の開発環境の構築」の追記です。

記事を読む

think_about_utest

単体テストの効率化を考える(5)-スタブの自動生成への入力

どもです。 「単体テストの効率化について考える」の5回目です。 1回目から4回目はコチラ:

記事を読む

Arduino_Logo

ホールセンサーの種類と使い方

どもです。 今回のエントリは、表題にある「ホールセンサー」についてです。 1.「ホールセンサ

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」の削除を簡単にしてみた

どもです。 前回、C#/OpenXmlを用いて、エクセルのセル内

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」を削除してみた

どもです。 今回は、C#/OpenXmlの組み合わせで、エクセル

c_sharp_eye_catch
C#でバッファの内容を表示する処理を実装してみた-
データ型に従って動的に書式を設定する

どもです。 最近、C#でバッファ/配列の値をコンソールに表示した

arduino_relay_switch_003_self_preservation_circuit_eye_catch
Arduinoでリレースイッチ(3)-自己保存回路

どもです。 前回の記事で、リレースイッチ「AE-G5V-DRV」

arduino_relay_switch_002_ae_g5v_drv_eye_catch
Arduinoでリレースイッチ(2)-AE-G5V-DRV

どもです。 前回の記事では、「フォトカプラリレー」を使用したLチ

→もっと見る

PAGE TOP ↑