2. キャプチャ上の文言をOCRで抽出し、テキストベースで文言が正しいか確認する
次に、キャプチャ画像から文言を抽出して、テキストベースで文言の正確性を確認します。
テストオラクルとしては、コードが参照する文言データを利用できる場合が多いと思います。
サンプルレベルのかなり簡略化した例ですが、今回は、次ようなCSV形式で各国文言を列挙した文言ファイルがあるとします。テストではこれを読み込んで期待値に展開します。
stringdata.csv
"Your account","アカウント","Dein Account"
"Security and account access","セキュリティとアカウントアクセス","Sicherheit und Account-Zugriff"
"Privacy and safety","プライバシーと安全","Datenschutz und Sicherheit"
"Notifications","通知","Mitteilungen"
"Accessibility, display, and languages","アクセシビリティ、表示、言語","Barrierefreiheit, Anzeige und Sprachen"
"Additional resources","その他のリソース","Zusätzliche Ressourcen"
次にテストコードですが、一例として次のように実装できます。
test_display_all_words.py
import re
import csv
from PIL import Image
import pyocr
import pyocr.builders
def check_all_words(wordsfile, language, csv_column):
'''指定された言語の表示文言が表示されているかチェック
'''
tool = pyocr.get_available_tools()[0]
txt = tool.image_to_string(
Image.open(language+'.png').crop((560, 100, 1200, 700)),
lang=language,
builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
if language == 'jpn':
result = re.sub(r'([あ-んア-ン一-龥ー、])\s+((?=[あ-んア-ン一-龥ー、]))',r'\1\2', txt)
else:
result = txt
with open(wordsfile) as f:
reader = csv.reader(f)
string_list_set = [row for row in reader]
for string_list in string_list_set:
if not string_list[csv_column] in result:
print(f'failed: [{string_list[csv_column]}] is not found')
return False
return True
def test_all_words():
'''各言語ごとの表示文言のチェック
'''
lang_list = [['eng', 0], ['jpn', 1], ['deu', 2]]
for lang in lang_list:
assert check_all_words('stringdata.csv', lang[0], lang[1]), lang[0]
テストコードの内容としては、対象領域に描画されている文言をPyOCRで読み取って、前述の文言ファイルの文言がその中で描画されているかチェックしています。
なおTwitter UIは文言描画がシンプルで明瞭なため、文言中の不正なスペース混入を除去する処理が必要な以外は、Tesseract OCRが提供するtessdata_bestの学習データをそのまま利用して十分な精度を確保できました。
テスト実行結果
テストを正常なキャプチャ画像で実行すると、テスト成功の結果が得られます。
次にキャプチャ画像を加工して、ドイツ語文言「Barrierefreiheit, Anzeige und Sprachen」の右端に文字切れを発生させてテストを実行すると、次のようにテスト失敗報告と、失敗原因となった文言を表示します。
pytest test_display_all_words.py -s
===================================================== test session starts =====================================================
(中略)
test_display_all_words.py failed: [Barrierefreiheit, Anzeige und Sprachen] is not found
F
========================================================== FAILURES ===========================================================
_______________________________________________________ test_all_words ________________________________________________________
def test_all_words():
'''各言語ごとの表示文言のチェック
'''
lang_list = [['eng', 0], ['jpn', 1], ['deu', 2]] #[lang_name, column_index of csv]
for lang in lang_list:
> assert check_all_words('stringdata.csv', lang[0], lang[1]), lang[0]
E AssertionError: deu
E assert False
E + where False = check_all_words('stringdata.csv', 'deu', 2)
test_display_all_words.py:39: AssertionError
=================================================== short test summary info ===================================================
FAILED test_display_all_words.py::test_all_words - AssertionError: deu
====================================================== 1 failed in 3.98s ======================================================