##1. はじめに
Lチカで始めるテスト自動化シリーズ第七弾です。
テストスクリプトの各コマンドを実行するたびに現在時刻を取得し、実行結果とともに保存するようにします。
これまでの記事はこちらをご覧ください。
- Lチカで始めるテスト自動化
- Lチカで始めるテスト自動化(2)テストスクリプトの保守性向上
- Lチカで始めるテスト自動化(3)オシロスコープの組込み
- Lチカで始めるテスト自動化(4)テストスクリプトの保守性向上(2)
- Lチカで始めるテスト自動化(5)WebカメラおよびOCRの組込み
- Lチカで始めるテスト自動化(6)AI(機械学習)を用いたPass/Fail判定
##2. テストランナーの改修
第六弾の付録A.2に掲載したtest-runner.pyとの差分を以下に示します。
test-runner.py(第六弾と第七弾のソースの差分)
$ diff test-runner_06.py test-runner_07.py
11a12
> import datetime
133a135
> timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
248a251
> cmd.insert(0,timestamp)
252a256
> cmd.insert(0,timestamp)
##3. テスト実行結果
###3.1 テストスクリプト
テストがPassするケースとFailするケースの両方を試すため、意図的にTensorFlowの画像識別のスコアの期待値を0.98にしています。
script.csv
#
exec_labelimg,str_1234_crop.jpg,str1234
eval_dbl_gt,0.98
exec_labelimg,str_abcd_crop.jpg,strabcd
eval_dbl_gt,0.98
#
###3.2 テスト実行結果
Passするケース、Failするケースのどちらも1カラム目にタイムスタンプが追加されました。
result.csv
2020/06/22 22:50:08,#,OK
2020/06/22 22:50:08,exec_labelimg,str_1234_crop.jpg,str1234,0.99075866,OK
2020/06/22 22:50:22,eval_dbl_gt,0.98,OK
2020/06/22 22:50:22,exec_labelimg,str_abcd_crop.jpg,strabcd,0.94599265,OK
2020/06/22 22:50:34,eval_dbl_gt,0.98,NG
##4. おわりに
- TensorFlowの画像識別は時間がかかるなあと思っていたのですが2回実行してそれぞれ14秒、12秒かかっていることがわかりました。
##A. 付録 test-runner.pyのソース
test-runner.py
#!/usr/bin/python3
#
# This software includes the work that is distributed in the Apache License 2.0
#
from time import sleep
import serial
import codecs
import csv
import platform
import datetime
import sys
import subprocess
import visa
import cv2
from PIL import Image
import pyocr
import pyocr.builders
UNINITIALIZED = 0xdeadbeef
def open_cam(camera_number):
return cv2.VideoCapture(camera_number)
def close_cam(cam):
if cam != UNINITIALIZED:
cam.release()
def capture_cam(cam, filename):
if cam != UNINITIALIZED:
_, img = cam.read()
cv2.imwrite(filename, img)
return True
else:
print("CAM Not Ready.")
return False
def crop_img(filename_in, v, h, filename_out):
img = cv2.imread(filename_in, cv2.IMREAD_COLOR)
v0 = int(v.split(':')[0])
v1 = int(v.split(':')[1])
h0 = int(h.split(':')[0])
h1 = int(h.split(':')[1])
img2 = img[v0:v1, h0:h1]
cv2.imwrite(filename_out, img2)
return True
def open_ocr():
ocr = pyocr.get_available_tools()
if len(ocr) != 0:
ocr = ocr[0]
else:
ocr = UNINITIALIZED
print("OCR Not Ready.")
return ocr
def exec_ocr(ocr, filename):
try:
txt = ocr.image_to_string(
Image.open(filename),
lang = "eng",
builder = pyocr.builders.TextBuilder()
)
except:
print("OCR Not Ready.")
else:
return txt
def exec_labelimg(filename, label_string):
if platform.system() == "Windows" :
python = "python"
grep = "findstr"
else:
python = "python3"
grep = "grep"
cmd = python + " label_image.py --graph=c:\\tmp\\output_graph.pb --labels=c:\\tmp\\output_labels.txt \
--input_layer=Placeholder --output_layer=final_result --image=" + filename + \
"|" + grep + " " + label_string
print(cmd)
log = subprocess.run(cmd, stdout=subprocess.PIPE, shell=True)
ret = log.stdout.strip().decode("utf-8").split(" ")[1]
return ret
def serial_write(h, string):
if h != UNINITIALIZED:
string = string + '\n'
string = str.encode(string)
h.write(string)
return True
else:
print("UART Not Initialized.")
return False
def close_uart(h):
if h != UNINITIALIZED:
h.close()
else:
#print("UART Not Initialized.")
pass
def open_dso():
rm = visa.ResourceManager()
resources = rm.list_resources()
#print(resources)
for resource in resources:
#print(resource)
try:
dso = rm.open_resource(resource)
except:
print(resource, "Not Found.")
else:
print(resource, "Detected.")
return dso
#Throw an error to caller if none succeed.
return dso
def main():
is_passed = True
val = str(UNINITIALIZED)
cam = UNINITIALIZED
ocr = UNINITIALIZED
dso = UNINITIALIZED
uart = UNINITIALIZED
with codecs.open('script.csv', 'r', 'utf-8') as file:
script = csv.reader(file, delimiter=',', lineterminator='\r\n', quotechar='"')
with codecs.open('result.csv', 'w', 'utf-8') as file:
result = csv.writer(file, delimiter=',', lineterminator='\r\n', quotechar='"')
for cmd in script:
timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
print(cmd)
if "#" in cmd[0]:
pass
elif cmd[0] == "sleep":
sleep(float(cmd[1]))
elif cmd[0] == "open_cam":
cam = open_cam(int(cmd[1]))
elif cmd[0] == "close_cam":
close_cam(cam)
cam = UNINITIALIZED
elif cmd[0] == "capture_cam":
ret = capture_cam(cam, cmd[1])
if ret == False:
is_passed = False
elif cmd[0] == "crop_img":
crop_img(cmd[1], cmd[2], cmd[3], cmd[4])
elif cmd[0] == "open_ocr":
ocr = open_ocr()
if ocr == UNINITIALIZED:
is_passed = False
elif cmd[0] == "exec_ocr":
try:
val = exec_ocr(ocr, cmd[1])
except:
is_passed = False
else:
cmd.append(str(val))
elif cmd[0] == "exec_labelimg":
try:
val = exec_labelimg(cmd[1], cmd[2])
except:
is_passed = False
else:
cmd.append(str(val))
elif cmd[0] == "open_dso":
try:
dso = open_dso()
except:
is_passed = False
elif cmd[0] == "dso":
try:
if "?" in cmd[1]:
val = dso.query(cmd[1]).rstrip().replace(",", "-")
cmd.append(val)
else:
dso.write(cmd[1])
except:
is_passed = False
elif cmd[0] == "open_uart":
if len(cmd) == 2:
dsrdtr_val = 1
else:
dsrdtr_val = int(cmd[2])
try:
uart = serial.Serial(cmd[1], 115200, timeout=1.0, dsrdtr=dsrdtr_val)
except:
is_passed = False
elif cmd[0] == "send":
ret = serial_write(uart, cmd[1])
if ret == False:
is_passed = False
elif cmd[0] == "rcvd":
try:
val = uart.readline().strip().decode('utf-8')
cmd.append(val)
except:
is_passed = False
elif cmd[0] == "eval_str_eq":
if str(val) != str(cmd[1]):
is_passed = False
elif cmd[0] == "eval_int_eq":
if int(val) != int(cmd[1]):
is_passed = False
elif cmd[0] == "eval_int_gt":
if int(val) < int(cmd[1]):
is_passed = False
elif cmd[0] == "eval_int_lt":
if int(val) > int(cmd[1]):
is_passed = False
elif cmd[0] == "eval_dbl_eq":
if float(val) != float(cmd[1]):
is_passed = False
elif cmd[0] == "eval_dbl_gt":
if float(val) < float(cmd[1]):
is_passed = False
elif cmd[0] == "eval_dbl_lt":
if float(val) > float(cmd[1]):
is_passed = False
else:
cmd.append("#")
if is_passed == True:
cmd.append("OK")
cmd.insert(0,timestamp)
print(cmd)
result.writerow(cmd)
else:
cmd.append("NG")
cmd.insert(0,timestamp)
print(cmd)
result.writerow(cmd)
close_uart(uart)
close_cam(cam)
print("FAIL")
sys.exit(1)
if is_passed == True:
close_uart(uart)
close_cam(cam)
print("PASS")
sys.exit(0)
main()