メインコンテンツまでスキップ

組み込みソフトウェア開発の現状

私はとあるメーカーで組み込みソフトウェア開発をしています。それほど経験が豊富なわけではありませんが、私が経験したプロジェクトのソフトウェア開発プロセスは非常に遅れていました。テストコードは一切なく、テストはすべて手動で実行され、デグレが頻繁に発生し、リリースが遅れることはもはや日常茶飯事でした。

なぜテストの自動化を行わないのか?と上司や同僚に尋ねたところ、こんな答えが返ってきました。

  • 「組み込みは実際に機械を動かさないと結果がわからないからテストの自動化なんてできないでしょ」
  • 「テストコードとかってウェブ系の話だよね?」
  • 「組み込みソフトは組み込み基板上で動くからそれをエミュレートするのは大変だよ」
  • 「テストコードってなに?」

総じてテストの自動化なんて無理だよね。結局、今のやり方を続けるしかないんだよ、という感じです。

彼らの言っていることはわかります。ウェブ開発はブラウザという統一的な環境であり、SeleniumPlaywriteといったブラウザを自動操作するための優れたオープンソースのツールがあります。プロジェクトごとに異なる無数の組み込みデバイスの一つをエミュレートする環境を作るのはコストが釣り合わないでしょう(医療や宇宙開発分野のような一つのバグが致命的な損害につながるところなら必要だと思います)。

しかしそれはE2Eテストに限った話です。単体テストや統合テストが難しい理由にはなりません。組み込みソフトウェアもロジックの集合体である以上、単体テストで十分にバグを発見できるはずです。実際、手動テストや市場で見つかるバグのほとんどは分岐処理における条件ミスといったロジックに起因するものでした。これらは明らかに手動テストで発見すべき問題ではありません。単体テストで早期に見つけるべきバグです。私には、組み込みであることを言い訳に、自動化は無理だと早合点し、ソフトウェアテストに関する十分な知識を得ようともせずに、現状の方法に固執しているように感じられました。

テストの種類

自動テストには、単体テスト、統合テスト、E2Eテストがありますが、マニュアルテストしか行っていない現場では、どのテストを最初に導入すべきでしょうか?

単体テストは、統合テストやE2Eテストに比べて実行時間が短く、開発者が迅速にフィードバックを得ることができます。また、テストするコードのスコープが小さいため、比較的簡単にテストコードを実装できるという利点もあります。一方、統合テストやE2Eテストはシステム全体の動作をより忠実に再現できるものの、実行時間が長くなり、テストのスコープが大きいことから障害リスクが高まりやすいという特徴があります。

実際にチームに自動テストを提案したとき、手動テストの自動化を考えている人が多いことに気づきました。チームではこれまで手動テストしか行っておらず、そもそも単体テストの概念が浸透していなかったため、手動で行っているテスト作業をそのまま自動化しようと考えるのは当然の流れでした。たとえば、人の代わりに手動テストを行うロボットを開発する、といった具合です。これは、ウェブ業界で(しばしばテストに詳しくない人々によって)キャプチャ&リプレイツールの導入が検討される事例に似ています。こうしたツールは手動テストの置き換えに過ぎず、テストの本質的な効率化や品質向上には直結しません。

テストの導入には一定の工数がかかるため、どれくらいの期間でその投資を回収できるかを考慮することが重要です。この観点から、私はまず単体テストを導入すべきだと考えています。単体テストは、より早くリターンを得ることができ、開発サイクルを迅速化する効果が期待できます。Googleでも、テストの約80%を単体テストで構成することが推奨されており、単体テストがテストピラミッドの最も重要な基盤として位置づけられています。1

テストピラミッド2

手動テスト100%

前述の通り、私の職場はすべてのバグを開発工程の終盤に手動テストで発見しようとしていました。これはテストピラミッドのアンチパターンとして知られている「アイスクリームコーン型」よりもさらにひどい状態であり、(単体テストが一切ないのでコーンもない)。ピラミッドの基盤すらない状態です。

アンチパターン3

このような非効率なテストの構成を見直し、手動テストにかかる工数の削減とバグの早期発見による品質向上を達成するため私は自身の担当製品に単体テストとCI4を導入しました。これによりバグの発見がリリース前の手動テストフェーズから実装フェーズに早期化されました。カバレッジレポートにより分岐を網羅できているかどうかの確認が容易になり、テストの品質を定量化できるようになりました。

チームの反応

私が単体テストを導入した成果をメンバーに紹介したところ、反応はまちまちでした。単体テストに興味を持ち、導入し始めてくれている人ももいれば、無関心な人もいました。

  • とても良い! 私の担当製品にも導入したい
  • なんかすごそうだけど実践方法がよくわからない
  • 今のプロジェクトが忙しいから新しいこと覚えてる暇がない
  • そもそも単体テストについてピンときていない

ということで、組み込みソフト開発チームにテストを根付かせる活動はまだ道半ばです。テスト導入の効果を引き続き紹介し、今後もテストの重要性を広める活動を続けていく予定です。

本ガイドは、私がチームに単体テストを導入する方法を説明した資料を一部修正したものです。テストの重要性はわかるけど組み込みで単体テストを導入する方法がわからない、という方にとって参考になれば嬉しいです。

Footnotes

  1. Software Engineering at Google 16章 Testing Overview Test Scope

  2. Software Engineering at Google 16章 Testing Overview Figure 11-3

  3. Software Engineering at Google 16章 Testing Overview Figure 11-4

  4. CIとは、Continuous Integrationの(継続的インテグレーション)略で、開発者が書いた新しいコードをマスターブランチに頻繁に統合するプロセスのこと