4.6K Views
October 31, 22
スライド概要
2022/10/31 社内勉強会向け資料です。
TDDでLEDドライバをホストPCでつくります。
組込みソフトウェアエンジニア。 技術バックボーンはC言語・ベアメタル。 CQ EVカートのオーナーで、ハード・ソフトウェアの改造を通じて自身のスキルアップを日々考え中・・・。 LAPRASポートフォリオ: https://lapras.com/public/k-abe GitHub: http://github.com/grace2riku Qiita: https://qiita.com/juraruming Zenn: https://zenn.dev/k_abe よろしくね。
組み込みソフトウェア基礎 【連続講座 #6】TDD #2 LED ライ (ホスト PC編) 2022/10/31 パーソルテクノロジースタッフ株式会社 バ ド 阿部耕二 [email protected]
目次 • 自己紹介 • 参加者一言コメント • 講座開催の背景・目的 • 本日のテーマ【LED ライ (ホストPC編)】 • TDD学習の参考 • 参加者感想 • 次回予告 バ ド 2
自己紹介 • 阿部 耕二(あべ こうじ) • 技術本部 機電技術部 首都圏2G • [email protected] • 医療機器開発 • 組込みソフトウェア開発。C言語、ベアメタルの開発業務経験がほとんど。 • LAPRASポートフォリオ:https://lapras.com/public/k-abe • twitter: @juraruming 3
参加者一言コメント ご自由に一言コメントいただけますとありがたいです。 例) お名前 例) 今回の講座に期待すること 例) お仕事内容(話せる範囲で) 例) ソフトウェア開発担当工程(要求仕様の定義?設計?実装?テスト?) 4
講座開催の背景・目的 • なにかテーマを決めて、ソフトウェア開発の上流工程から下流工程まで 説明する講座を開催し、スキルアップを図る。 ■要求仕様の理解 資料・記事 ■要求仕様の仕様化 資料・記事 ■設計 ●概要 資料・記事 ●詳細 資料・記事 ■TDD ●#1 テスト駆動開発はじめの一歩 資料・記事 ●#2 LEDドライバ(ホストPC編) ★いまここ ●#3 LEDドライバ(ターゲット編) ●#4 ●#5 5
講座開催の背景・目的 テーマ: 【既存組込み製品(CQ EVカート)の マイコンを移植する】 6
講座開催の背景・目的 テーマ:【既存組込み製品のマイコンを移植する】 対象装置:CQ EVカート 背景: ・講師が持っており、対象装置のドメイン知識を理解している。 ・ソフトウェアの構造を理解している。 ・対象装置のマイコンが新規採用非推奨品になった。 ⇛学習・スキルアップのため別マイコンに移植してみよう!!! 7
本日のテーマ 【LED ライ (ホストPC編)】 • LED ライ (ホストPC編)とは何か? • TDDする前に • TDDやってみる バ バ ド ド 8
本日のテーマ 【LED ライ (ホストPC編)】 • LED ライ (ホストPC編)とは何か? • TDDする前に • TDDやってみる バ バ ド ド 9
LED ライ (ホストPC編)とは何か? ・何故、LEDドライバをホストPCでTDDするのか? ▪LED点灯・消灯の単純なパターンからTDDを始める。 理由:最初は簡単なものからはじめたい。 ▪ホストPCで完結するテストを実施する。 理由:ハードウェアがなくてもテストが進める。 ホストPC・ターゲットでTDDをどう進める試してみたかった。 バ ド 10
LED ライ (ホストPC編)とは何か? ・LEDドライバとは? ▪EVカートのLEDを点灯・消灯する機能を持つデバイスドライバとする。 モーター現在位置と制御の状況を9つのLEDで視覚化できる。 バ ド 11
本日のテーマ 【LED ライ (ホストPC編)】 • LED ライ (ホストPC編)とは何か? • TDDする前に • TDDやってみる バ バ ド ド 12
TDDする前に ・私のTDD開発環境 ▪ホストPC: macOS Monterey バージョン 12.6 ▪テストフレームワーク: CppUTest 4.0 ▪コンパイラ: Apple clang version 11.0.0 (clang-1100.0.33.8) ▪テスト対象プログラミング言語: C ▪ビルドシステム: cmake 3.21.1 13
TDDする前に ・私のTDD開発環境 補足 >▪ホストPC: macOS Monterey バージョン 12.6 ・Windows, Linuxでも可能かと思います。 >▪テストフレームワーク: CppUTest 4.0 ・マイコン環境でもTDDしたかったのでCppUTestに決めました。 >▪テスト対象プログラミング言語: C ・テストはC++, システムはC >▪ビルドシステム: cmake 3.21.1 ・makeはできなかった・理解できなかったのでcmakeにしました。 14
TDDする前に ・私のTDD開発環境 補足2 >▪ビルドシステム: cmake 3.21.1 ・makeはできなかった・理解できなかったのでcmakeにしました。 ・GitHubのテンプレートリポジトリをつくりました。 cmakeでCppUTestのテストを実行できます。 今回のソースコードはつぎのリポジトリに置きました。 https://github.com/grace2riku/evkart_tdd/tree/LedDriver_221031 15
TDDする前に ・TDDの大事な原則を確認 ・テストを書く。 ・テスト失敗を確認する(レッド)。 ・テスト成功させるためのプロダクトコードを書く。 ・テスト成功を確認する(グリーン)。 ・テスト成功したままソースコードを綺麗する(リファクタリング) 小さなステップで1つの課題解決に集中する!!! 16
本日のテーマ 【LED ライ (ホストPC編)】 • LED ライ (ホストPC編)とは何か? • TDDする前に • TDDやってみる バ バ ド ド 17
TDDやってみる ・TDDの進め方 ・テストの項目を書く(テストリスト) ・テストを書く 18
TDDやってみる ・TDDの進め方 ・テストの項目を書く(テストリスト) ・テストを書く 19
TDDやってみる ・テストの項目を書く(テストリスト) テストしたい項目を書く。今回は3つのテストやってみたい。 ・ドライバを初期化したら、すべてのLEDがオフしている ・ホールセンサーUが1の場合、ホールセンサーLEDをオンにする ・ホールセンサーUが0の場合、ホールセンサーLEDをオフにする 詳しくはこちら https://github.com/grace2riku/evkart_tdd/blob/LedDriver_221031/ README.md 20
TDDやってみる ・TDDの進め方 ・テストの項目を書く(テストリスト) ・テストを書く 21
TDDやってみる ・テストを書く テストリストのテストを書いていく。 書いていきたいですが、最初はTDD環境の確認をやってみます。 ※コミットは細かく刻み、割と丁寧にコメントを書いたのでコミットロ グを追うとTDDの流れがなんとなくわかるかと思います。 コードを写経しTDDのサイクルを体感するとより理解が深まると思いま す。そして楽しくなる。 22
TDDやってみる ・テストを書く 〜TDD環境の確認 1〜 ・buildディレクトリを作成する 今回のソースコードのリポジトリをクローンしてきて、その階層でbuild ディレクトリを作成する。 $ mkdir build buildディレクトリに移動する。 $ cd build/ 23
TDDやってみる ・テストを書く 〜TDD環境の確認 2〜 buildディレクトリでcmakeを実行し、Makefileを作成する $ cmake .. -- The C compiler identification is AppleClang 11.0.0.11000033 -- The CXX compiler identification is AppleClang 11.0.0.11000033 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done Using CppUTest found in /usr/local/Cellar/cpputest/4.0 -- Configuring done Makefileが出来た -- Generating done -- Build files have been written to: /Users/k-abe/evkart/evkart_tdd/build $ ls CMakeCache.txt CMakeFiles Makefile bin cmake_install.cmake lib tests src 24
TDDやってみる ・テストを書く 〜TDD環境の確認 3〜 作成されたMakefileをmakeする $ make [ 20%] Building C object src/hello/CMakeFiles/hello.dir/Hello.c.o [ 40%] Linking C static library ../../lib/libhello.a [ 40%] Built target hello [ 60%] Building CXX object tests/CMakeFiles/tdd_test.dir/AllTests.cpp.o [ 80%] Building CXX object tests/CMakeFiles/tdd_test.dir/hello/HelloTest.cpp.o [100%] Linking CXX executable ../bin/tdd_test [100%] Built target tdd_test KojinoMacBook-2:build k-abe$ ls bin tdd_test 実行ファイル(tdd_test)ができる 25
TDDやってみる ・テストを書く 〜TDD環境の確認 4〜 実行ファイルを実行する $ ./bin/tdd_test テストを実行し、テストが失敗し たことがわかる。 /Users/k-abe/evkart/evkart_tdd/tests/hello/HelloTest.cpp:23: error: Failure in TEST(Hello, Create) Start here!!! . Errors (1 failures, 1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 1 ms) 26
TDDやってみる
・テストを書く 〜TDD環境の確認 5〜
テストファイルを確認する。
evkart_tdd/tests/hello/HelloTest.cpp
FAILでテスト失敗させている。
TEST(Hello, Create)
{
FAIL("Start here!!!");
}
※CppUTestで使えるアサーションがこちらを参照
27
TDDやってみる ・テストを書く 〜テストの雛形作成〜 ここから今回のテストを書いていく。まずはテストの雛形をつくる。 今回のソースコードのルートの階層(evkart_tdd)で次のコマンドを実行する。 $ NewPackageDirs HallSensorLedDriver creating src/HallSensorLedDriver creating include/HallSensorLedDriver ディレクトリをつくり、 その中にCコードのスケルトンを作成してくれる CppUTestのスクリプトを実行する。 creating tests/HallSensorLedDriver $ NewCModule.sh HallSensorLedDriver HallSensorLedDriver creating include/HallSensorLedDriver/HallSensorLedDriver.h creating src/HallSensorLedDriver/HallSensorLedDriver.c creating tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp 28
TDDやってみる ・テストを書く 〜cmake設定変更1〜 追加したファイルをmakeするようにcmake設定ファイル (CMakeLists.txt)を変更する。 今回の主題はTDDでcmakeではないので詳しくは説明しません。 具体的な変更点はつぎのコミットを参考にしてください。 29
TDDやってみる ・テストを書く 〜cmake設定変更2〜 cmake設定変更後にMakefile作成・makeし生成された実行ファイルを実行すると今回追加した HallSensorLedDriverのテストが失敗していることが確認できた。 $ ./bin/tdd_test /Users/k-abe/evkart/evkart_tdd/tests/hello/HelloTest.cpp:23: error: Failure in TEST(Hello, Create) Start here!!! . /Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:23: error: Failure in TEST(HallSensorLedDriver, Create) Start here . Errors (2 failures, 2 tests, 2 ran, 2 checks, 0 ignored, 0 filtered out, 1 ms) 30
TDDやってみる
・テストを書く 〜GitHubテンプレートのhelloテストを無視するよう変更〜
GitHubテンプレートのhelloテストは不要になったので無視するテストに
変更する(IGNORE_TESTに変更する)。
evkart_tdd/tests/hello/HelloTest.cpp
//TEST(Hello, Create)
IGNORE_TEST(Hello, Create)
{
FAIL("Start here!!!");
}
31
TDDやってみる ・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜 テスト【ドライバを初期化したら、すべてのLEDが消灯している】をテスト 名称【LedsOffAfterCreate】として書く。 既存のCreateテストをLedsOffAfterCreateに変更する。 // ドライバを初期化したら、すべてのLEDが消灯している TEST(HallSensorLedDriver, LedsOffAfterCreate) { FAIL("Start here"); } 32
TDDやってみる ・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜 make、実行すると想定とおりテストは失敗している。 $ ./bin/tdd_test ! /Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/ HallSensorLedDriverTest.cpp:24: error: Failure in TEST(HallSensorLedDriver, LedsOffAfterCreate) Start here テスト名がCreateから変更後 のLedsOffAfterCreateになっている。 . Errors (1 failures, 2 tests, 1 ran, 1 checks, 1 ignored, 0 filtered out, 1 ms) 33
TDDやってみる ・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯してい る〜 レッドからグリーン(テストが成功)にする。 テスト成功させるためにはFAILアサーションを消せばよい。 makeし実行するとテスト成功を確認できる。 $ ./bin/tdd_test !. OK (2 tests, 1 ran, 0 checks, 1 ignored, 0 filtered out, 1 ms) 34
TDDやってみる ・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜 テストは成功したがテストすべきことをしていない。意味のあるテストを書いていく。 正しく初期化することを確認するためにつぎのようなテストを書く。 リファクタリング // ドライバを初期化したら、すべてのLEDが消灯している TEST(HallSensorLedDriver, LedsOffAfterCreate) { unsigned char virtualLeds = 0xff; HallSensorLedDriver_Create(&virtualLeds); BYTES_EQUAL(0, virtualLeds); } 35
TDDやってみる ・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜 makeするとコンパイルエラーとなる。 $ make [ 25%] Built target hello [ 50%] Built target HallSensorLedDriver Consolidate compiler generated dependencies of target tdd_test [ 62%] Building CXX object tests/CMakeFiles/tdd_test.dir/HallSensorLedDriver/HallSensorLedDriverTest.cpp.o /Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:25:3: error: no matching function for call to 'HallSensorLedDriver_Create' HallSensorLedDriver_Create(&virtualLeds); ^~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/k-abe/evkart/evkart_tdd/include/HallSensorLedDriver/HallSensorLedDriver.h:10:6: note: candidate function not viable: requires 0 arguments, but 1 was provided void HallSensorLedDriver_Create(void); ^ 1 error generated. make[2]: *** [tests/CMakeFiles/tdd_test.dir/HallSensorLedDriver/HallSensorLedDriverTest.cpp.o] Error 1 make[1]: *** [tests/CMakeFiles/tdd_test.dir/all] Error 2 make: *** [all] Error 2 36
TDDやってみる
・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜
コンパイルエラーを解消しmake、テスト実行するとつぎになる。
LEDドライバの初期化をしていないためテストは失敗する。
KojinoMacBook-2:build k-abeKojinoMacBook-2:build k-abe$ ./bin/tdd_test
!
/Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:26:
error: Failure in TEST(HallSensorLedDriver, LedsOffAfterCreate)
LONGS_EQUAL((0) & 0xff, (virtualLeds) & 0xff) failed
expected < 0 (0x0)>
but was <255 (0xff)>
.
Errors (1 failures, 2 tests, 1 ran, 1 checks, 1 ignored, 0 filtered out, 1 ms)
37
TDDやってみる
・テストを書く 〜ドライバを初期化したら、すべてのLEDが消灯している〜
LEDドライバの初期化をしてmake、実行する。テストは成功する。
void HallSensorLedDriver_Create(unsigned char* address)
{
*address = 0; // これを追加した
}
$ ./bin/tdd_test
!.
OK (2 tests, 1 ran, 1 checks, 1 ignored, 0 filtered out, 1 ms)
$ ./bin/tdd_test -v
IGNORE_TEST(Hello, Create) - 0 ms
TEST(HallSensorLedDriver, LedsOffAfterCreate) - 0 ms
38
OK (2 tests, 1 ran, 1 checks, 1 ignored, 0 filtered out, 1 ms)
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオン にする〜 テスト名称【TurnOnHallULed】として書く。 これを確認したい!!! 39
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンに する〜 テスト名称【TurnOnHallULed】として書く。 ホールセンサU・V・WのLEDは同じアドレスのGPIOデータレジスタに割り付 けられている。 所有しているEVカート(2013年発売モデル)だと8ビットのデータレジスタにつ ぎのように割り当てられている。 2bit目: ホールセンサーU LED →0x04書き込みでLED点灯 3bit目: ホールセンサーV LED →0x08書き込みでLED点灯 4bit目: ホールセンサーW LED →0x10書き込みでLED点灯 40
TDDやってみる
・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜
テスト名称【TurnOnHallULed】として書く。
テストを追加し、失敗することを確認する。
// ホールセンサーUが1の場合、ホールセンサーLEDをオンにする
TEST(HallSensorLedDriver, TurnOnHallULed)
{
FAIL("Fail: TurnOnHallULed!!!");
}
makeしテストを実行する。追加したテストが想定とおり失敗していることを確認できる。
$ ./bin/tdd_test
!
/Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:32: error: Failure in
TEST(HallSensorLedDriver, TurnOnHallULed)
Fail: TurnOnHallULed!!!
..
Errors (1 failures, 3 tests, 2 ran, 2 checks, 1 ignored, 0 filtered out, 4 ms)
41
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオン にする〜 テスト名称【TurnOnHallULed】として書く。 FAILのアサーションを削除し、make・テストを実行する。テストが成功す る。 $ ./bin/tdd_test !.. OK (3 tests, 2 ran, 1 checks, 1 ignored, 0 filtered out, 1 ms) 42
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜 テスト名称【TurnOnHallULed】として書く。 テストが機能することは確認できた。確認したいテストを書く。 // ホールセンサーUが1の場合、ホールセンサーLEDをオンにする TEST(HallSensorLedDriver, TurnOnHallULed) { unsigned char virtualLeds; HallSensorLedDriver_Create(&virtualLeds); HallSensorLedDriver_TurnOn(0x04); BYTES_EQUAL(0x04, virtualLeds); } テストを書いたらmakeする。 43
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜 エラーが発生する。HallSensorLedDriver_TurnOnは関数定義していないので想定通り。 $ make [ 25%] Built target hello [ 50%] Built target HallSensorLedDriver Consolidate compiler generated dependencies of target tdd_test [ 62%] Building CXX object tests/CMakeFiles/tdd_test.dir/HallSensorLedDriver/HallSensorLedDriverTest.cpp.o /Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:34:3: error: use of undeclared identifier 'HallSensorLedDriver_TurnOn'; did you mean 'HallSensorLedDriver_Create'? HallSensorLedDriver_TurnOn(0x04); ^~~~~~~~~~~~~~~~~~~~~~~~~~ HallSensorLedDriver_Create /Users/k-abe/evkart/evkart_tdd/include/HallSensorLedDriver/HallSensorLedDriver.h:10:6: note: 'HallSensorLedDriver_Create' declared here void HallSensorLedDriver_Create(unsigned char* address); ^ /Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:34:30: error: cannot initialize a parameter of type 'unsigned char *' with an rvalue of type 'int' HallSensorLedDriver_TurnOn(0x04); ^~~~ /Users/k-abe/evkart/evkart_tdd/include/HallSensorLedDriver/HallSensorLedDriver.h:10:48: note: passing argument to parameter 'address' here void HallSensorLedDriver_Create(unsigned char* address); ^ 2 errors generated. make[2]: *** [tests/CMakeFiles/tdd_test.dir/HallSensorLedDriver/HallSensorLedDriverTest.cpp.o] Error 1 make[1]: *** [tests/CMakeFiles/tdd_test.dir/all] Error 2 make: *** [all] Error 2 44
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜 ヘッダーファイルにHallSensorLedDriver_TurnOnをプロタイプ宣言する。 コンパイルエラーは解消されるが、関数の実体がないからリンクエラーになる。 $ make [ 25%] Built target hello [ 37%] Building C object src/HallSensorLedDriver/CMakeFiles/HallSensorLedDriver.dir/HallSensorLedDriver.c.o [ 50%] Linking C static library ../../lib/libHallSensorLedDriver.a [ 50%] Built target HallSensorLedDriver Consolidate compiler generated dependencies of target tdd_test [ 62%] Building CXX object tests/CMakeFiles/tdd_test.dir/HallSensorLedDriver/HallSensorLedDriverTest.cpp.o [ 75%] Linking CXX executable ../bin/tdd_test Undefined symbols for architecture x86_64: "_HallSensorLedDriver_TurnOn", referenced from: TEST_HallSensorLedDriver_TurnOnHallULed_Test::testBody() in HallSensorLedDriverTest.cpp.o (省略) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [bin/tdd_test] Error 1 make[1]: *** [tests/CMakeFiles/tdd_test.dir/all] Error 2 make: *** [all] Error 2 45
TDDやってみる
・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜
関数の実体を書く。処理は未実装にしておく。リンクが成功するので
テストを実行する。
$ ./bin/tdd_test
!
/Users/k-abe/evkart/evkart_tdd/tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp:35:
error: Failure in TEST(HallSensorLedDriver, TurnOnHallULed)
LONGS_EQUAL((0x04) & 0xff, (virtualLeds) & 0xff) failed
expected <4 (0x4)>
but was <0 (0x0)>
Errors (1 failures, 3 tests, 2 ran, 2 checks, 1 ignored, 0 filtered out, 1 ms)
HallSensorLedDriver_TurnOnは未実装のためテストが想定とおり失敗する。
46
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオンにする〜 テストを成功させるためのつぎの実装を行う。 HallSensorLedDriver_TurnOnではHallSensorLedDriver_Createの引数に指定したアドレス のLEDをオンすればテストは成功するはず。 static unsigned char* hallSensorLedsAddress; void HallSensorLedDriver_Create(unsigned char* address) { // *address = 0; hallSensorLedsAddress = address; *hallSensorLedsAddress = 0; } void HallSensorLedDriver_TurnOn(unsigned char ledBitNumber) { *hallSensorLedsAddress = 0x04; } 47
TDDやってみる ・テストを書く 〜ホールセンサーUが1の場合、ホールセンサーLEDをオン にする〜 makeしテストを実行する。テスト成功が確認できた。 $ ./bin/tdd_test -v IGNORE_TEST(Hello, Create) - 0 ms TEST(HallSensorLedDriver, TurnOnHallULed) - 0 ms TEST(HallSensorLedDriver, LedsOffAfterCreate) - 0 ms OK (3 tests, 2 ran, 2 checks, 1 ignored, 0 filtered out, 2 ms) 48
TDDやってみる ・テストを書く 〜ホールセンサーUが0の場合、ホールセンサーLEDをオフ にする〜 テスト名称【TurnOffHallULed】として書く。 これを確認したい!!! 49
TDDやってみる ・テストを書く 〜ホールセンサーUが0の場合、ホールセンサーLEDをオフにする〜 LEDオンのときと同様の手順でテスト追加、実装を行う。 // 追加したテスト // ホールセンサーUが0の場合、ホールセンサーLEDをオフにする TEST(HallSensorLedDriver, TurnOffHallULed) { unsigned char virtualLeds; HallSensorLedDriver_Create(&virtualLeds); HallSensorLedDriver_TurnOn(0x04); HallSensorLedDriver_TurnOff(0x04); BYTES_EQUAL(0x00, virtualLeds); } // テストを成功させる実装 void HallSensorLedDriver_TurnOff(unsigned char ledBitNumber){ *hallSensorLedsAddress = 0x00; } 50
TDDやってみる ・テストを書く 〜ホールセンサーUが0の場合、ホールセンサーLEDをオフに する〜 makeしテストを実行する。 $ ./bin/tdd_test -v IGNORE_TEST(Hello, Create) - 0 ms TEST(HallSensorLedDriver, TurnOffHallULed) - 0 ms TEST(HallSensorLedDriver, TurnOnHallULed) - 0 ms TEST(HallSensorLedDriver, LedsOffAfterCreate) - 0 ms OK (4 tests, 3 ran, 3 checks, 1 ignored, 0 filtered out, 4 ms) 51
TDDやってみる 多分、皆さんが思っていること・・・ ▪LEDオン・オフするテストもハードコーディングじゃない? ▪3種類あるLEDうち他のLEDのオン・オフに対応できるコードになってい ないのでは? 52
TDDやってみる 多分、皆さんが思っていること・・・ ▪LEDオン・オフするテストもハードコーディングじゃない? ⇨その通り。 ▪3種類あるLEDうち他のLEDのオン・オフに対応できるコードになってい ないのでは? ⇨その通り。 53
TDDやってみる 多分、皆さんが思っていること・・・ Q. TDD意味あるの??? 1種類のLEDを点灯するテストが書けた。 →他の機能・複雑さが実装されていない。必要最低限のコードになって いる。 他の2種類のLEDをオン・オフするテストを書き、テスト失敗を確認する。 テストを通す実装をインクリメンタルに追加していく (これまでのテストが成功することを保持しながら)。 54 テスト主導でコードが徐々に実装され成長していく。
TDD学習の参考 1. テスト駆動開発による組み込みプログラミング 2. [動画で解説]和田卓人の“テスト駆動開発”講座 記事一覧 3. 『テスト駆動開発による組み込みプログラミング』を読んで学んだこと 4. TDDによるマイコンのLチカ開発(1) 5. TDDによるマイコンのLチカ開発(2)(完) 55
参加者感想 • 是非とも講座の感想を一言お願いします。 56
次回予告 TDDの講座の次回は【12/xx(x) 19:30〜20:30】で開催予定です。 【連続講座 #7】テスト駆動開発#2 LEDドライバ(ターゲット編) 次回はマイコン基板でTDDしたいと考えています。 参加の方、是非ともよろしくおねがいします。 57
参考【テーマの前提説明】 • テーマの前提説明 【CQ EVカート】とは??? ・動画1: 走行中 ・動画2: 基板を拡大 過去に書いた技術書(EV カート 始めるモ ル ース開発)をベースに説明します。 記載箇所:【第1章 EVカートとは何か】 ベ デ で 58
参考【テーマの前提説明】 • テーマの前提説明 テーマ:【既存組込み製品のマイコンを移植する】は次の前提とする。 ・派生開発(既にある装置でマイコンのみ変更) ・ハードウェアあり。電気的仕様確認OK。 ・旧マイコンでのソフトウェア資産あり。※GitHub, 資料 の各リンク ・個人開発(お仕事にも適用できるエッセンスはあるかと思います) 59
終わり ご静聴ありがとう ございました。 60