組み込み機器のテストの際、地味に面倒なのが結果判定です。

ひたすら積み上げられたテスト項目と手順を眺めつつ、
「ボタンを押して風量が変わった、OK」
「スリープに入るまでの時間5秒、OK」
という風に、
ひとつひとつOK/NGを確認していくのは気が遠くなる作業ですね。

ぼーっとどこかへ行ってしまいそうになる意識を、必死に現実に引き留めて行う結果判定。

「ヨシ!」
と思っても、やはり人間が実施するものなので、ヒューマンエラーは付きものです。

で、あとになってから確認したはずの部分で不具合が発覚して
「ねえ。これ。ちゃんと確認してOK出したんだよね? (圧」
なんてこともあったりなかったり…。

そんなときもやっぱりAUTOmeal!!!
ヒューマンエラーに泣く人を減らすために、自動化を取り入れていきましょう。

「制御」「計測」に続き、第3回目は満を持して「判定」を行います!

今回も自動テスト初心者の私がやってみました!
(もうこれで自動テスト経験者にステップアップしてもいいでしょうか…)

※本連載ではAUTOmealプロトタイプを使用しています。現在発売されている製品版とは一部異なりますのでご了承ください。

 

はじめに。前回の振り返り

AUTOmealは、組み込み機器のテストにおける「制御」「計測」「判定」を、人に代わって自動で実行してくれる、
夢のようなソリューションです。

連載第1回、第2回ではそれぞれ「制御」と「計測」をやってみました。

第1回:制御編の振り返り

制御編では、Pythonスクリプトを使って扇風機を自動制御してみました! ボタンをポチポチしたり、距離センサの前で手を近づけたり離したりするところを AUTOmealが代わりにやってくれたわけです。
【記事へのリンク】💡 「【連載】ラズパイとPythonでテスト自動化やってみた~AUTOmeal:制御編~」

第2回:計測編の振り返り

計測編では、I/Fボードを付け替えて計測をできるようにしました! アナログの波形をリアルタイムで計測してAUTOmealアプリ上に表示させるところをご覧いただきました。 波形のChart表示だけでなく、スクリプトを使って取得した値をログに出力させることもできました。
【記事へのリンク】 💡 「【連載】ラズパイとPythonでテスト自動化やってみた~AUTOmeal:計測編~」

今回は、ついに第3回「判定」ということで、「制御」「計測」後、OK/NGの結果判定を行います!!

 

計測の準備

前回、前々回はそれぞれの機能をお見せすることに特化した構成でお届けしていましたが、
今回は「制御」→「計測」→「判定」の流れを、つなげてお見せしていきます!

具体的な工程を一連の流れとして実施する今回の構成をご参考にしていただけると
テスト自動化のイメージがより具体的になるのではないでしょうか!

拡張I/Fボードの付け替え

おなじみのI/Fボード、今回は以下のような構成にします。
今までは制御も計測もそれぞれ2つのI/Fボードをラズパイにアタッチしていましたが、
「制御」「計測」「判定」を合わせて実施するため、ちょっと増えます。
重ね付けされてどんどん背が高くなっていくのがなんだか面白いですね。
いつかMAXの8段まで付けてやってみたいです。

ターゲットと接続すると五重の塔(ラズパイ+I/Fボード)も相まって近未来的お寺(上から見た図)のようですね。

設定ファイルの編集

今回、”FunctionSettings.json”では以下のように設定しました。

ロジックとアナログ、ともに制御と計測を実施したいため、
前回使用した”LogicBoardControl” と ”AnalogMeasureBoardControl”に加え、PulseBoardControlをtrueにしました。

ファームウェアの書き込み

前回同様、その他 > RaspberryPiセットアップ…(S) をクリックし、
ポップアップに対して 接続するラズパイのIPアドレス、ポート、ユーザ名、パスワードを入力し、
「ファームウェア書き込み」をクリックするだけでOKです。

 

(余談)手動テスト時代

実際に結果判定の自動化のお話しに入る前に、
すこしだけ手動テストのことについてお話ししたいと思います。

冒頭でも少し触れましたが、
今までのテストはテスト管理書などに書かれた以下のような項目を参考に、
人が手で操作を実施し、操作した結果が想定通りのものになっているかを判定していました。

  • テスト項目
  • 確認手順
  • 期待する動作 …等

上記のような内容を、↓のようにExcelなどを使って管理されている方もまだまだ多いのではないでしょうか?

私も新人研修のときに作ったテスト管理書がExcelでした(そういえばこんなことやったなあ)。

テスト系の課だったので、テストガッツリやっとくかということで、
とりあえずひと通り思いつく項目を挙げて実施しました。

単体も統合も妥当性確認も、ぜんぶがぜんぶ結構な項目数になりました。

  • ・ボタンでターゲットのON/OFFがちゃんと切り替わるか
  • ・ブザーの音の高さが変わるか
  • ・距離センサの前で手を動かして、それに合わせてLEDの色が変わるか

などを一つ一つ確認していましたが、シンプルに疲れました。

テストにNGが出ようものならもう最悪。
不具合修正!
NG項目再テスト!
確認OK!よし、やっとテストから解放!

…かと思いきや。

先輩「じゃあ、影響範囲も再度実施してデグレチェックしてね。結合からでいいから。」

え、NGやり直すだけじゃないの?
”からでいい”って何?
と思わず顔に出てしまった思い出…。

実際の開発の際も妥当性確認の作業に入ったときには上のようなテスト管理書を渡され、
それに沿ってテストを実施しました。
ひよっこゆえ、妥当性確認中分からないところがある度に先輩に聞きに行っていました。

手動テストだと、このようにテスト実施者の負担が大きくなったり(手戻りがあるとさらに大変)、
経験値の差が出てしまうことがありました。

そんな課題を解決するためにもAUTOmealは生まれたんですね。
(個人的に「あの時AUTOmeal的なものがあれば」と思わずにはいられない。)

 

結果判定の自動化

さて、それでは自動テストの方に入っていきましょう!
まずはテストシナリオについてです。

テストシナリオ

第1回、第2回目の記事では、それぞれ制御と計測だけをスクリプトの命令として書いていました。
今回は制御したターゲットがどのように動作しているかを計測し、その結果が想定したものかを判定するように書きます。

今回計測の対象としているものは以下の3種類です。

  • 1, 電源、ECOモードのLED信号(Logic)
  • 2, 風量制御のモータ制御信号(PWM)
  • 3, 風量の状態表示LED信号(PWM)

それぞれについて、以下のような内容を判定していきます。

  • ・LED信号:操作に応じて点灯/消灯の状態が切り替わっているか
  • ・モータ信号:状態に応じてモータに回転/停止しているか
  • ・状態LED信号:風量に応じてRGBそれぞれのLEDが点灯/消灯が切り替わっているか

それに対し、Python上ではそれぞれ以下のような値が取得できます。

  • ・Logic:計測ラインの”Hi = 1 / Lo = 0”をint値で取得
  • ・PWM:単位時間当たりのパルス周波数とパルス幅をint値で取得

これらを踏まえて、実際の判定スクリプトを作成していきます。
次に続きます。

電源、ECOモードのON/OFF判定

LEDが点灯しているかどうかを判断したいので、
LEDの制御ラインの状態を判定します。

まずは電源/ECOモードボタンの操作を再現して、
点灯/消灯の状態を作ります。

そして、LEDの制御ラインの状態を計測します。
APIの戻り値が0か1かで、LEDのOFF/ONを判定していきます。
戻り値が1ならHi、つまり点灯しているということですね。
後はIF文で期待値かどうかを判定し、処理を分岐させていきます。

以下のようなスクリプトになります。
LEDが付いていればOKの判定になります。

tlog.info(‘電源ON’)
tm.key(‘GPO_17’, True)
time.sleep(0.1)
tm.key(‘GPO_17’, False)
time.sleep(1)
tlog.info(‘電源ランプ点灯チェック…’)
time.sleep(1)
value = tm.get_input(‘GPI_23’)
if value == LED_ON:
 tlog.info(‘…OK’)
else:
 tlog.info(‘…NG’)
time.sleep(1)

風量制御のモータの動作判定

モータが回っているかを確認したいので、
モータ制御ラインのパルス周波数を判定します。

まずはAnalog電圧を操作してモータの動作状態を変化させます。

そして、モータ制御信号の周波数を取得していきます。
APIでは周波数はHz単位で取得できるので、
0でなければモータに対してパルスが入力されているということです。
今回はモータが止まっていると判断できる範囲内に周波数が収まっているかを確認していきます。
こちらも期待値と異なればIF文で処理を分岐させていきます。

以下のようなスクリプトになります。
モータが止まっていればOKの判定になるはずです。

 tlog.info(‘距離値有効範囲外設定’)
 tm.dac(‘DAC1’, 2000)
 time.sleep(1)
 tlog.info(‘ファン無回転チェック…’)
 time.sleep(1)
 value = tm.get_pulse_input(‘pulse4’)
 if FAN_OFF_FREQ_MIN <= value <= FAN_OFF_FREQ_MAX:
  tlog.info(‘…OK’)
else:
 tlog.info(‘…NG’)
time.sleep(1)

風量の状態表示LEDの判定

各LED(RGB)が期待通りに点灯しているかを確認したいので、
状態LED制御ラインのパルス周波数を判定します。

風量切り替えボタンへの出力を制御して風量を切り替えます。

そして、状態LEDへの出力信号を計測します。
APIの戻り値でパルス周波数が取得できます。
モータ同様に、周波数が0であれば制御信号がなく消灯しているはずなので、
RGBそれぞれ適切なLEDに対して出力ができているかを判定していきます。
周波数はぶれる可能性もあるため、
今回は取得できた周波数がマクロ定義した値の範囲内であれば、
点灯していると判断します。

スクリプトは以下のようになります。

tlog.info(‘風量切り替え’)
tm.key(‘GPO_22’, True)
time.sleep(0.1)
tm.key(‘GPO_22’, False)
time.sleep(1)
tlog.info(‘LED_GREEN周波数チェック…’)
time.sleep(1)
value = tm.get_pulse_input(‘pulse2’)
if LED_GREEN_FREQ_MIN <= value <= LED_GREEN_FREQ_MAX:
  tlog.info(‘…OK’)
else:
 tlog.info(‘…NG’)
time.sleep(1)

今回実際に実行したシナリオはこちらです。

  1. 電源ON – Logic制御
  2. 電源ランプ点灯したかif文で判定 (OK/NG) – Logic計測
  3. 風量切り替え – Logic制御
  4. 風量切り替わったかif文で判定 (OK/NG) – PWM計測
  5. 風量切り替え – Logic制御
  6. 風量切り替わったかif文で判定 (OK/NG) – PWM計測
  7. ECOモードON – Logic制御
  8. ECOモードランプ点灯したかif文で判定 (OK/NG) – Logic計測
  9. 電圧印加 (ファン止める) – DAC制御
  10. ファン止まったかif文で判定 (OK/NG) – PWM計測
  11. 電圧印加 (ファン動かす) – DAC制御
  12. ファン動いたかif文で判定 (OK/NG) – PWM計測
  13. ECOモードOFF – Logic制御
  14. ECOモードランプ消灯したかif文で判定 (OK/NG) – Logic計測
  15. 風量切り替え – Logic制御
  16. 風量切り替わったかif文で判定 (OK/NG) – PWM計測
  17. 電源OFF Logic制御
  18. 電源ランプ消灯したかif文で判定 (OK/NG) – Logic計測

以下はそれぞれを組み合わせて作成したスクリプトの抜粋です。


async def main():
    try:
        ### TestLoggerの初期化
        tlog.Setup(“pythonLog.log”,__name__)

        tlog.info(‘===== テストシナリオを開始します。 =====’)
  tlog.info(‘テストを開始します。’) 

       ### 自動テストを開始
        tm.start()

    ### 初期化
        ### GPIOをLowに設定
        tm.key(‘GPO_17’, False)
        tm.key(‘GPO_22’, False)
        tm.key(‘GPO_5’, False)
        tm.key(‘GPO_6’, False)
        ### DAC出力を0に設定
        tm.dac(‘DAC1’, 0)
        tm.dac(‘DAC2’, 0)
        tm.dac(‘DAC3’, 0)
        tm.dac(‘DAC4’, 0)
        tm.dac(‘DAC5’, 0)
        tm.dac(‘DAC6’, 0)
        tm.dac(‘DAC7’, 0)
        tm.dac(‘DAC8’, 0)
        ### 待機[sec]
        time.sleep(1)

        tlog.info(‘電源ON’)
        tm.key(‘GPO_17’, True)
        time.sleep(0.1)
        tm.key(‘GPO_17’, False)
        time.sleep(1)
        tlog.info(‘電源ランプ点灯チェック…’)
        time.sleep(1)
        value = tm.get_input(‘GPI_23’)
        if value == LED_ON:
            tlog.info(‘…OK’)
        else:
            tlog.info(‘…NG’)
        time.sleep(1)

        tlog.info(‘風量切り替え’)
        tm.key(‘GPO_22’, True)
        time.sleep(0.1)
        tm.key(‘GPO_22’, False)
        time.sleep(1)
        tlog.info(‘LED_GREEN周波数チェック…’)
        time.sleep(1)
        value = tm.get_pulse_input(‘pulse2’)
        if LED_GREEN_FREQ_MIN <= value <= LED_GREEN_FREQ_MAX:
            tlog.info(‘…OK’)
        else:
            tlog.info(‘…NG’)
        time.sleep(1)

・・・

      tlog.info(‘ECOモードON’)
        tm.key(‘GPO_5’, True)
        time.sleep(0.1)
        tm.key(‘GPO_5’, False)
        time.sleep(1)
        tlog.info(‘ECOモードランプ点灯チェック…’)
        time.sleep(1)
        value = tm.get_input(‘GPI_24’)
        if value == LED_ON:
            tlog.info(‘…OK’)
        else:
            tlog.info(‘…NG’)
        time.sleep(2)

・・・

        tlog.info(‘距離値有効範囲外設定’)
        tm.dac(‘DAC1’, 2000)
        time.sleep(1)
        tlog.info(‘ファン無回転チェック…’)
        time.sleep(1)
        value = tm.get_pulse_input(‘pulse4’)
        if FAN_OFF_FREQ_MIN <= value <= FAN_OFF_FREQ_MAX:
            tlog.info(‘…OK’)
        else:
            tlog.info(‘…NG’)
        time.sleep(1)

・・・

上で書いたように、
ターゲットを制御したあとにその状態を取得して、if文でOK/NGの判定を実施しています。

Pythonはシンプルで分かりやすい言語なので、一度やってみるとかんたんにできてしまうと思います!
電源のON/OFFや風量の切り替えなど、何度か実施するような動作はコピペしてやりました。

コピペは偉大です。

制御、計測、結果判定のようす

それでは実際にターゲットの制御から状態の計測と、
それに基づいた結果判定までの流れを動画で見てみましょう!

今回もターゲットは扇風機です。
スクリプトで制御し、その動作結果に基づきOK/NGを判定しています。

コマンドライン上に何をどのように制御するか、
結果判定 (OK/NG)はどうかを出力しているので、
何をやっているのかがお分かりいただけると思います。

スクリプトでターゲットの制御、計測、結果判定を行っています。


 

自動で結果判定してみた感想

ひとことで言うと、かんたんにいろいろできそう。

ベースがPython言語なので、今回のように割とシンプルな判定もできますし、
複雑な判定処理を書いて厳密な判定を実現することもできそうです。
設定もかんたんだし、スクリプトも一度書いてしまえば実行させるだけで
回帰テストもスクリプトを回すだけになるので、精神的にくる地獄の再テストからも解放されそう。
(実際はスクリプトの正当性を評価したり、もう少し作業が必要だと思いますが)
何より今まで都度手動で行っていた作業の手間が省け効率化が図れますし、楽。

判断や判定って、個人的に人間が頭で考えてやるイメージがあります。
ですが、人間よりも機械の方が(たいてい)正確で頭がいいんだから機械にやってもらった方がいいかなと思います。
また、人がやるとどうしてもふわっとした部分が出てくるのではないかなと思います。
そうすると、実施者によって結果判定のばらつきが出てしまったりもしますよね。
そういうところを避けるためにも機械にはっきりとOK/NGを判定してもらうのがいいですね。

結果判定部分に限った話ではないし、以前にも書いたかもしれませんが、
やっぱりツールの学習コスト的にもコスパがいい気がします。
使い方が難しくてノウハウを持ったそのツールのエキスパートしか
なかなか使いこなせてないツールもたまにあったりするかと思います。
その点、AUTOmealは設定も操作もかんたんで誰でもすぐに使いこなせそうだなと感じました。

スクリプトはPython言語なので、使った経験がある人も多いと思いますし、
初めて書く人も言語自体の難易度が低いのですぐにできるようになると思います。
ツールを使うにあたって習得したPythonの書き方も個人の経験、資産として残り、
その後のエンジニアライフにも役立つものになるのではないでしょうか。なんだかお得!!

 

最後に

いかがでしたか?

これまで3回にわたってAUTOmealでの「制御」「計測」「判定」について連載してきました。
なんとなくイメージが湧いたという方がいらっしゃれば幸いです。

テスト自動化やってみた!的な記事を書いてきましたが、
正直、振り返っていただくとお分かりになるかも、なのですが…

私、ほとんど何もしてません。
だいたいAUTOmeal任せでした。

(自動化なのでそりゃそうですね)

楽することは悪いことではありません。
開発も楽しく、楽にやっていきたいですよね(*’▽’)
気の遠くなるようなテスト作業はAUTOmealに任せて、そこで温存した労力や時間を他のことに充てていきましょう!

そして、結果判定まで終わったからといって、今回でAUTOmealについての連載記事が終了するわけではありません!
3回の連載ではお伝えしきれていない情報がたくさんあります。
今後もまだまだ続くのでご期待ください(*^-^*)

さっそくですが次回はシリアル通信の自動化についてお話ししたいと思います。
今後ともよろしくお願いいたします!

最後までお読みいただき、ありがとうございました!

「パート4:シリアル通信編」はコチラ!

シリアル通信部分のテストについて、どのように自動化すればいいのか? というところをご紹介します。「いまから環境構築」という方はモチロン、「もうテストのシステムができあがってるし、今更自動化は難しいよな…」とお悩みの方にもおすすめです!
パート4:シリアル通信編

テスト自動化ツールまとめ
~どれを使えばいいのか書いてみた~

年々、大規模化するソフトウェア開発。品質に対する要求レベルも上昇しており、テストにかかる工数も増加しています。そこで、自動化へ一歩踏み出す皆さんが導入からつまずかないよう、テスト自動化の始め方と自動化ツールについてまとめてみました。
記事を読む

【 無料セミナー 】
組込み開発向けテスト自動化プラットフォームAUTOmeal デモウェビナー

AUTOmealによる環境構築から実際の自動テストの様子まで、基本的な使い方をデモンストレーションいたします。ぜひ実動作をご覧いただき、その効果をご確認ください。

お申し込みはこちら!