既に、先達が個々に作ってるような気もするのだけど、外部プログラムを実行するプログラムをちょっと便利にしたらテストを自動実行するプログラムになるんじゃないかという説。
プログラムをテストするのにプログラムを書くのはナンセンスじゃないの?
pythonのpytestとかunittestは下記のように手書きコードでガリガリテストコードを書くのだけど・・・、正直、面倒過ぎませんか?
import pytest
import subprocess
def test_execute_external_program(subprocess):
# 外部プログラムの実行
result = subprocess.run(['echo', 'Hello, world!'], capture_output=True, text=True)
# 実行結果の検証
assert result.returncode == 0
assert result.stdout.strip() == 'Hello, world!'
import unittest
def add(x, y):
return x + y
class TestAdd(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(1, 2), 3)
def test_add_negative_numbers(self):
self.assertEqual(add(-1, -2), -3)
def test_add_mixed_numbers(self):
self.assertEqual(add(1, -2), -1)
if __name__ == '__main__':
unittest.main()
プログラムにはテスト必須のこの時代にプログラムをテストするためにプログラムを書くとか・・・。じゃあ、そのテストプログラムに不具合無いの?
何ならそこはプログラマーじゃない人、仕様決めた人とか、試験の人に仕事振りたい位の話なのに、こんなんやってたらプログラマーの仕事増えるばっかりという話で。
理想のプログラムテストってどんな形か考えてみよう。
ほぼ、テスト駆動プログラミングの考え方なんだけど・・・
①仕様段階でテストする条件と、その結果の設定を作る。
②プログラムを作る。
③設定でプログラムを動作テストして問題無ければOK.
[
{
"name":"normal_test",
"type": "ExecuteProgram"
"settings": {
"arguments": [
2,
1
],
"check_result": {
"expected": 2
},
"function_name": "Division",
"program_path": "./Sources/Common/Division.py"
}
},
{
"name":"division by zero_test",
"type": "ExecuteProgram"
"settings": {
"arguments": [
1,
0
],
"check_result": {
"expected": {
"error": "division by zero",
"success": false
}
},
"function_name": "Division",
"program_path": "./Sources/Common/Division.py"
}
}
]
テスト専用のプログラムさえ作ればこの設定で多くのプログラムが確認できるという事になりそうです。
しかも、この文法さえ覚えればプログラマーでなくてもテストできるのではないでしょうか?
まぁ、日本人的にはJSON形式よりも、Excelで設定できるよう表形式の方が好みという人もメッサ居そうですが、JSONにしてるのは後で拡張するときに楽なので・・。
例えば、"check_result": { "expected": 2 }は現状は結果とイコールしか設定できない作りですが、Min:1,Max:10とかの設定を追加する可能性も有るわけで。
テストのイメージはどんな感じか?
で、この方法だとテストはどんなイメージになるのかというと・・・
python test_program.py test_settings.json
TestName:normal_test(OK pattern)
function: Division(A = 2 ,B = -1)
result :2
OK!
こんな感じになるでしょう。
テスト内容と結果が明確なので、プログラマでなくても仕様書見ながらテストできそうじゃないですか?特に、仕様書作成者自身がテストするなら余裕でしょう。
そして、らくちんテストへ・・・
NGパターンでは実際の結果で設定を上書きする機能を用意するのというのはどうでしょうか?
python test_program.py test_settings.json
TestName:normal_test(NG pattern)
function: Division(A = 2 ,B = -1)
result :2
expected:''
NG.Press 'y' to change the expected setting in check_result.
こういう機能を用意すれば・・・
①プログラムが出来上がる。
②テスト設定の結果を書かずに、動作設定だけ作る。
③テストで動かしてみて、結果が正しそうだったらテスト設定のexpectedを結果で上書きする。
④テスト内容が足りないなら手で設定を追加する。
こういうお手軽テストができるのではないでしょうか?
テスト設定を動的に変えられる設定ファイルでのテストの強みですね。
らくちんテスト、その先
さて、動的にテスト設定を作れるのであれば、そもそもテスト内容を自動作成できるようにしてしまえば、前準備も不要でプログラムができた瞬間に簡単なテストを開始できてしまうのではないかと、気づいた方々も居るのではないでしょうか?
完全なテストを自動で作るのはまず無理ですよ?
ただ、元々、完全なテストって存在するのという話で、この世には問題ない程度テストしたプログラムしかないのです。完全か、不完全かの二元論で言ってしまえば、最低限度動くかどうかの自動生成テストと50歩100歩とも言えるかもしれません。
というか、定型テスト的に自動テストさせて、その後にきちんとしたテストしたら少し楽だよね、というのが現実的な話ですかね。
ソースや実行ファイルのシグニチャなどから引数の型が数字、文字列、配列、辞書、名前から内容を予想とかする事でテストする引数をテキトーに決めちゃって、テスト設定を自動生成するようにしてしまえば、テスト立案の手間が少し減るハズです。
まぁ、そんな話を徒然なるままに検証していきたいという企画です。