システムテストの必須項目(4)・複数機能の同時実行テスト

2021年9月13日テスト品質

組み込み系では複数処理の同時実行に潜むバグの検出も大切です

組み込み系ソフトの安定性を確保するには複数処理の同時実行のテストも重要です。単独の機能については、正常系/準正常/異常系 の機能テストや性能テストや安定性テストが実施されます。しかし実際の運用の場面では、複数の機能が同時に実行される場面が良く起こります。そのような場面で起きる潜在バグを見つけ出しておくのが、複数処理の同時実行テストです。

ところが、複数機能の同時実行というテスト条件は、全ての機能の組み合わせを網羅しようとすると、テスト項目数が膨大になってしまい、実際のテスト期間でテストが終わらなくなってしまいます。ではどうやってテストケースを絞り込むのが良いでしょう? この記事ではグタラ親父のこれまでの経験を元に、複数の同時実行に潜むバグの紹介とそれらを見付けるためのテストケースの絞り込み方について紹介します。

複数の機能の同時実行はどんな時におきる

組み込みソフトに実装される機能はいろいろあります。そしてその各々の機能については正常系/準正常系/異常系という名前のテストで、単体機能についてので動作や安定性が確認されています。組み込みソフトが機能をひとつずつ実行するだけならば、この単体機能テストだけで良いのですが、実際の組み込みソフトでは複数の機能が同時並行して実行される事も良くあります。

例えば、組み込み系ソフトでは GUI 等のように操作者かららの指示を受けて処理を開始するインターフェースを持つ装置も多いです。このような装置の場合、GUI からの指示に対する機能実行の裏では組み込みソフトとしての通常の内部機能が動いている事もよくあります。そして、GUI による操作者の画面操作のタイミングと内部機能の実行とのタイミングが合うと、組み込みソフトの中では2つの機能を実行する処理が同時に並行して実行されます。

この様に、自動実行される内部機能と操作者の指示で実行される機能との実行タイミングが合うと、組み込みソフトの中で2つの機能を実施する処理が同時に走るというパターンが多いです。また、組み込みソフトによっては複数のユーザからの処理を同時に並行して実行する機能(マルチ―ユーザ・マルチタスク の機能)を持っている事もあります。この場合には、2人のユーザから同じタイミングで何等かの機能の実行が指示されると、その2つの機能を実施する処理が同時実行されます。

複数の処理の同時実行になぜバグが潜在し易い

2つの機能が同時に実行されても、各々の機能が正常に動作を終わるのならば問題は在りません。ところが、2つの機能が同時に実行される事で潜在しているバグが動いてしまう事も良くあります。一番多いのは、同じデータに同時にアクセスする事によるデータの書き壊しや、変更途中で整合性の取れていないデータの読みだしです。どちらも、複数の機能や処理が同じデータをアクセスする時の排他制御にバグがある時に起こります。

例えば、製品名と個数の2つのデータ構造をもつ Aさん向け販売内容 という情報があったとします。機能Aは今GUIから入力されたリンゴ・3個 という情報を書き込み、機能Bは他のページで昨日Aさんが入力したミカン・1個という情報を通信回線から受け取って書き込むとします。ちゃんと排他制御ができていれば、Aさん向けの販売内容にはミカン・1個とリンゴ3個 の2種類の情報が記録されます。

では排他制御ができていなくて、マズイタイミングで機能Aと機能Bが実行されると何が起きるでしょうか。機能Aがリンゴと書いた直後に機能Bが通信を受けて割り込み処理を起動して、ミカン・1個を書き込み、その後に機能Aが復帰してきて3個と書き込むような事態が起きてしまいます。そうすると、結果的にAさんの販売内容はミカン・3個とおかしな事になってしまいます。

このような排他制御に潜むバグは、そのデータに同時にデータを書き込むようなタイミングで2つの機能が実行されて初めて不具合として見えてきます。単体でどれだけテストを行っても、このような複数機能の同時実行のタイミングに依存する潜在バグは見つかりません。これは一例ですが、このような潜在バグを見付けるには複数機能の同時実行テストが必要です。

複数の処理の同時実行のテストは網羅は無理

複数の処理の同時実行テストが潜在するバグの洗い出しに効果があるのは確かなのですが、実際にテスト設計をしてみると大きな壁にぶち当たります。俗にいうテスト項目の爆発ですね、機能が10種類あるとして、2つの機能の同時実行の組み合わせは 10 X 10 で 100種類です。この 100種類というのは正常系の代表的な機能実行だけを考えた場合です。

しかし実際の機能の実行の場面を考えてテストを計画しようとすると、正常系1種類に加えて準正常系を3つと異常系を1つ程度は加えたいと思います。その上に、複数機能の同時実行で現れる潜在バグは、それぞれの機能の実行タイミングに依存する可能性を考えると、それぞにに実行タイミングを変えた2種類を想定したくなります。これだけで、1つの機能の実行条件が10種類に増えるので、その掛け算となると (10 X 10) X (10 X 10) となって既に 1万件のテスト項目です。

複数機能の同時実行テストだけをやっていれば良い訳ではないので、この件数のテストはちょっと現実的ではありません。複数機能の同時実行テストでは、網羅性の確保は諦めざるを得ません

テストを行う複数処理の組み合わせはどうやって選ぶのか

網羅性の100%の確保が無理となるとできるだけ潜在バグの洗い出しが効果的にできるような組み合わせに限定してテスト計画を作らないといけません。複数機能の同時動作テストで、どの機能とどの機能の同時動作をテストの候補として選ぶのが良いのでしょうか。これが正しいという答えは無いのですが、複数機能の同時実行で見つかる潜在バグは何らかの処理が衝突したタイミングで見つかる事が多いので、ソフト内部で処理の衝突が起き易いような機能の組み合わせを探すのが良いと思います。ここではグータラ親父が使っていた考え方を幾つか紹介します。

(1)内部処理に同じ下位の処理を使っていそうな機能を選ぶ

同じ下位の処理を使っていると、2つの処理から呼び出された下位の処理の実行で衝突が起きます。そうすると、先の例で紹介したように必要な排他制御に関する潜在バグが見つかる事が良くあります。

(2)同じデータにアクセスしている機能を選ぶ

使っている下位の処理は異なるけれども、同じデータにアクセスしている機能でも潜在バグが見つかる事があります。データの検索機能とデータの更新機能よのうに、同じデータを扱うけれども異なる種類の処理というのも、排他制御の潜在バグを洗い出すので複数機能のテスト項目に使えます。

(3)CPUやメモリや通信用バッファなど共通のハードウエア資源を大量に使う機能を選ぶ

大抵の組み込みソフトでは、動的メモリや通信用ソケットや通信ようバッファなどの動的資源を使っています。またCPUの処理能力自体も動的資源です。これらの動的資源のうちのどれかを大量に消費するような機能があれば、それを同時実行するという考え方です。この場合には、動的資源の一時的な枯渇による資源の空き待ち等の処理の潜在バグを洗い出す事ができます。

(4)実際の運用で起こりそうな同時動作の組み合わせ

実際に装置を使う時に同時に事項される場面がありありそうな機能を選ぶというのも、必要な選択方法です。

複数機能の同時実行テストでは複数のタイミングも必要

複数機能の同時実行テストでは網羅性の確保が難しいのでテストする組み合わせを絞り込むのですが、一方で2つの内部処理が衝突するようなタイミングで実行するという事も大切です。ソフトの内部処理まで含めて、処理のタイミングを正確にコントロールするのはとても難しいので、どうしても少しずつズラした複数のタイミングで複数機能を実行するようなテストの工夫も必要です。テスト項目数が増えてしまうのでテストの網羅性との兼ね合いが難しいのですが、ここは余り細かく悩んでも仕方が無いので、ある程度エイヤっで決めるしか無いと思います。

複数機能の同時実行の次ぎは起動時の異常系/準正常系のテストです

動的メモリや動的資源のリークテスト、タイマやカウンタのロールオーバテスト、複数機能の同時実行テストは、主に通常の動作時の安定性を確認するテストです。組み込みソフトでは通常の動作時とは別に起動時の安定性を確認するテストも必要なので、次の記事では起動時の異常系/準正常系テストについて紹介しましょう。