LoginSignup
4
0

More than 3 years have passed since last update.

自作の自動テストツールをJenkinsで実行する

Last updated at Posted at 2020-12-02

1. はじめに

こちらはソフトウェアテストの小ネタ Advent Calendar 2020の3日目の記事です。

システムテスト自動化 標準ガイドで自動化すべきでないテストの一つに「物理的なやりとりがあるテスト。例えば、カードリーダーにカードを通す、何かの装置の接続を外す、電源をオフかオンにするなど」が挙げられていますがホントはこの手のテストも自動化したいですよね。

Lチカで始めるテスト自動化は初めて作る自動テストシステムを目標としながらも、このようなテストの自動化を目指してそこそこ機能が充実してきたことや連載1回目Jenkinsでの実行にちょっとだけ触れたものの詳細は割愛していたため、Jenkinsでの実行を記事にまとめます。

2. 目標

Jenkinsのコントローラ(Windows10)とエージェント(Raspberry Pi)でパイプラインを組んで以下のプロジェクトを実行し1、Pass/Fail判定を行います。
本稿では所定の文字列をファイルへ出力することでテストを実行したとみなしJenkinsでの実行にフォーカスします。

  1. コントローラ
    • テストランナー(test-runner.py)2とテストスクリプト(CSVファイル)をエージェントへ転送する
  2. エージェント
    • テストランナーのrunコマンド3でテストを実行し、所定の文字列をファイルへ出力する
  3. コントローラ
    • エージェントからファイルを取得する
    • テストランナーのrunコマンドでファイルに記入されている文字列をテストランナーに読み込む
    • テストランナーのeval_str_eqコマンドで期待値の文字列と比較する

3. 環境

  • Python
    • コントローラ(Windows10 PC & Miniconda3)
      • C:\Users\****\Miniconda3\python.exe
      • Python 3.6.9
    • エージェント(Raspberry Pi 3B+)
      • Raspbian GNU/Linux 10 (buster)
      • Python 3.7.3
  • Jenkins 2.249.34

4. 作るもの

  1. テスト実行を模したテストスクリプト(pass版)
  2. テスト実行を模したテストスクリプト(fail版)
  3. 実行結果と期待値を比較するテストスクリプト

4.1 テスト実行を模したテストスクリプト(pass版)

echoコマンドで文字列passをtest.txtへ出力します。

execute-pass.csv
run,echo pass>test.txt

4.2 テスト実行を模したテストスクリプト(fail版)

echoコマンドで文字列failをtest.txtへ出力します。

execute-fail.csv
run,echo fail>test.txt

4.3 実行結果と期待値を比較するテストスクリプト

コントローラ(Windows10)で実行します。typeコマンドで標準出力へ出力したテキストファイルの内容と期待値の文字列passを、改行コードを無視して比較します。

evaluation.csv
run,type test.txt
eval_str_eq,pass

5. Jenkinsのプロジェクト

パイプラインのプロジェクトを作成します。アイテム名はtest-runner-sampleとしました。

5.1 passする版

PipelineScript
node('master'){
    stash name: 'test'
}
node('RPi00'){
    deleteDir()
    unstash 'test'
    sh 'python3 test-runner.py execute-pass' // <- pass version
    //sh 'python3 test-runner.py evaluation'
    stash name: 'result'
}
node('master'){
    unstash 'result'
    bat 'C:/Users/****/Miniconda3/python.exe test-runner.py evaluation'
}
コンソール出力
ユーザー****が実行
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\test-runner-sample
[Pipeline] {
[Pipeline] stash
Stashed 4 file(s)
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on RPi00 in /home/pi/jenkins/workspace/test-runner-sample
[Pipeline] {
[Pipeline] deleteDir
[Pipeline] unstash
[Pipeline] sh
+ python3 test-runner.py execute-pass
['run', 'echo pass>test.txt']
CompletedProcess(args='echo pass>test.txt', returncode=0, stdout='', stderr='')
['2020/12/02 22:51:36', 'run', 'echo pass>test.txt', 'OK']
PASS
[Pipeline] stash
Stashed 6 file(s)
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\test-runner-sample
Terminated
[Pipeline] {
[Pipeline] unstash
[Pipeline] bat

C:\jenkins\workspace\test-runner-sample>C:/Users/****/Miniconda3/python.exe test-runner.py evaluation 
C:\Users\****\Miniconda3\lib\site-packages\numpy\__init__.py:140: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
  from . import _distributor_init
['run', 'type test.txt']
CompletedProcess(args='type test.txt', returncode=0, stdout='pass\n', stderr='')
['2020/12/02 22:51:38', 'run', 'type test.txt', 'OK']
['eval_str_eq', 'pass']
['2020/12/02 22:51:38', 'eval_str_eq', 'pass', 'OK']
PASS
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

5.2 failする版

fail版を実行して実際にfailすることを確認します。

PipelineScript
node('master'){
    stash name: 'test'
}
node('RPi00'){
    deleteDir()
    unstash 'test'
    sh 'python3 test-runner.py execute-fail' // <- fail version
    //sh 'python3 test-runner.py evaluation'
    stash name: 'result'
}
node('master'){
    unstash 'result'
    bat 'C:/Users/****/Miniconda3/python.exe test-runner.py evaluation'
}
コンソール出力
ユーザー****が実行
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\test-runner-sample
[Pipeline] {
[Pipeline] stash
Stashed 4 file(s)
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on RPi00 in /home/pi/jenkins/workspace/test-runner-sample
[Pipeline] {
[Pipeline] deleteDir
[Pipeline] unstash
[Pipeline] sh
+ python3 test-runner.py execute-fail
['run', 'echo fail>test.txt']
CompletedProcess(args='echo fail>test.txt', returncode=0, stdout='', stderr='')
['2020/12/02 22:53:29', 'run', 'echo fail>test.txt', 'OK']
PASS
[Pipeline] stash
Stashed 6 file(s)
[Pipeline] }
[Pipeline] // node
Terminated
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\test-runner-sample
[Pipeline] {
[Pipeline] unstash
[Pipeline] bat

C:\jenkins\workspace\test-runner-sample>C:/Users/****/Miniconda3/python.exe test-runner.py evaluation 
C:\Users\****\Miniconda3\lib\site-packages\numpy\__init__.py:140: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
  from . import _distributor_init
['run', 'type test.txt']
CompletedProcess(args='type test.txt', returncode=0, stdout='fail\n', stderr='')
['2020/12/02 22:53:30', 'run', 'type test.txt', 'OK']
['eval_str_eq', 'pass']
['2020/12/02 22:53:30', 'eval_str_eq', 'pass', 'NG']
FAIL
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE

6. おわりに

  • 自作の自動テストツールをJenkinsで実行しPass/Fail判定ができました。
  • 以下の理由によりPythonはテストツールを作りやすいと思いました。
    • テストに有用なライブラリがいろいろある
    • WindowsやLinuxなど複数のプラットホーム、アーキテクチャで共用しやすい
    • Jenkinsと組合わせて自動テストシステムを組むといった応用を利かせやすい
  • この記事が品質技術開発を始めるきっかけとなりましたら幸いです。

付録A. Lチカで始めるテスト自動化・記事一覧

  1. Lチカで始めるテスト自動化
  2. Lチカで始めるテスト自動化(2)テストスクリプトの保守性向上
  3. Lチカで始めるテスト自動化(3)オシロスコープの組込み
  4. Lチカで始めるテスト自動化(4)テストスクリプトの保守性向上(2)
  5. Lチカで始めるテスト自動化(5)WebカメラおよびOCRの組込み
  6. Lチカで始めるテスト自動化(6)AI(機械学習)を用いたPass/Fail判定
  7. Lチカで始めるテスト自動化(7)タイムスタンプの保存
  8. Lチカで始めるテスト自動化(8)HDMIビデオキャプチャデバイスの組込み
  9. Lチカで始めるテスト自動化(9)6DoFロボットアームの組込み
  10. Lチカで始めるテスト自動化(10)6DoFロボットアームの制御スクリプトの保守性向上
  11. Lチカで始めるテスト自動化(11)ロボットアームのコントローラ製作
  12. Lチカで始めるテスト自動化(12)書籍化の作業メモ
  13. Lチカで始めるテスト自動化(13)外部プログラムの呼出し
  • 1~11と13の記事を電子書籍化し技術書典で頒布しています。

付録B. ソフトウェアテストのアドベントカレンダー参加記事


  1. 従来はMaster、Slave、Jobという用語が用いられていましたが、Jenkinsの公式用語集に倣ってController、Agent、Projectとしています。なお、中国語版の用語集にはControllerの項目はなくMasterとなっています。 

  2. テストランナー(test-runner.py)はコントローラとエージェントで同じものを使用します。エージェントにインストールしていないライブラリ(cv2、PIL、pyocr)は今回は使用しないこともありimportしないようコメントアウトしています。 

  3. runコマンドは外部プログラムを実行するコマンドです。詳しくはLチカで始めるテスト自動化(13)外部プログラムの呼出しをご参照ください。 

  4. Jenkinsのインストールは「マイコンのUARTコマンド制御をJenkins、Raspberry Pi、Pythonで行う」の4.マスター側Jenkinsをご参照ください。 

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0