私はPythonで実装された簡単なテストベンチを持っています。exec()で実行されるコードで定義された関数のスコープ
テストランナーは一連の機能をテストに公開します。 これはテストを書くためのドメイン固有の言語と考えることができます。 ほとんどのテストケースは、これらの関数の呼び出しの単純なシーケンスを形成します。制御フロー文を含むこともありますが、それより複雑なものはありません。
ここで、いくつかのテストケースが複雑すぎるため、関数を使用してリファクタリングすると恩恵を受けます。 これは私が問題にぶつかるところです。 関数内から、テストケース内で定義されたローカルシンボルにアクセスできません。ランナーが公開する機能にアクセスすることもできません(ログと確認)。
''' Testing variable scopes in exec()'''
PRG_1 = '''
a = 42
log('Testing a = ' + str(a))
verify(a, 42)
'''
PRG_2 = '''
a = 42
def f():
c = a # Error 'a' not defined
log(c) # Error 'log' not defined
f()
'''
class TestRunner():
def __init__(self, prg):
self.prg = prg
def log(self, msg):
print(msg)
def verify(self, a, b):
print('PASSED' if a == b else 'FAILED')
def run(self):
# Bring methods into local scope to avoid having 'self.' in DSL
log = self.log
verify = self.verify
# Execute test
exec(self.prg)
r = TestRunner(PRG_1)
r.run()
r = TestRunner(PRG_2)
r.run()
どのように私はこれを動作させることができますか? 多分これを達成するための別の(そして良い方法)があります。私はC++開発者としては見えません。
$ python3 test.py
Testing a = 42
PASSED
Traceback (most recent call last):
File "test.py", line 42, in <module>
r.run()
File "test.py", line 35, in run
exec(self.prg)
File "<string>", line 7, in <module>
File "<string>", line 4, in f
NameError: name 'a' is not defined
ローカルとグローバルを 'exec'に渡すことができます。[documentation](https://docs.python.org/3/library/functions.html#exec) – FujiApple
を参照してください。' exec(self.prg、 globals = globals()、locals = locals()) 'を取得しましたが、' TypeError:exec()はキーワード引数を取りません。その後、代わりに位置引数を使用してみましたが、助けにはなりませんでした。 –