Reputation: 653
I have a simple test bench implemented in python.
The test runner exposes a set of functions to the test. This may be considered as a domain specific language for writing tests. Most test cases form simple sequences of calls to these functions, sometimes involving control flow statements, but nothing more complicated than that.
Now a few test cases have become too complex and would benefit from being refactored using functions. This is where I run into problems. From within the functions I cannot access local symbols defined inside the test case. I can also not access the functions exposed by the runner (log and verify).
''' 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()
Any idea on how I can get this to work? Maybe there is a different (and better way) to accomplish this, that I as a C++ developer do not see.
$ 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
Upvotes: 1
Views: 93
Reputation: 826
If you do:
def run(self):
exec(self.prg, {'log': self.log, 'verify': self.verify})
Produces:
42
Generally a good idea to avoid dynamic code execution like this anyway!
Upvotes: 2