我正在尝试使用Python3构建一种简单的DSL(特定于域的语言)以进行特殊的测试。 DSL基础结构将定义一些测试命令,然后运行根据这些命令编写的外部Python脚本,但也可能包含任何其他有效的Python。
第一个问题是独立运行外部脚本,而不会在脚本循环执行时累积一个脚本对另一个脚本的副作用。
第二个问题是执行外部脚本本身定义的函数(例如on_setup()
)。这些功能需要在DSL解释器级别执行。
以下是测试框架的基本代码(“ cutest.py”):
# DSL command
def test(title):
print("test:", title)
try:
on_setup() # function from the current test
except:
print("on_setup() not found")
# DSL command
def expect(str):
print("expect:", str)
# other DSL commands...
def main():
import glob
scripts = glob.glob("test*.py")
for fname in scripts:
print("*******", fname)
try:
exec(open(fname).read(), globals())
except:
print("errors in script:", fname)
if __name__ == "__main__":
main()
这是“ test_1.py”脚本:
def on_setup():
print("test_1.py:on_setup")
test("My first test")
expect("foo")
最后,这是“ test_2.py”脚本:
test("My second test")
expect("bar")
请注意,“ test_2.py”没有不定义其on_setup()
函数。
现在,当我在具有python cutest.py
和test_1.py
的目录中运行test_2.py
时,将得到以下输出:
******* test_1.py
test: My first test
test_1.py:on_setup
expect: foo
******* test_2.py
test: My second test
test_1.py:on_setup
expect: bar
问题是test_2.py
的输出显示“ test_1.py:on_setup”(运行test_1.py
的副作用,而它应显示“ on_setup()not found”,因为{{ on_setup()
中未定义1}}。
在我的框架代码“ cutest.py”中,我使用了Python test_2.py
调用,但是也许可以使用exec(.., globals())
或其他某种机制来解决问题。
答案 0 :(得分:0)
我找到了一种可以使它工作的可接受方法,并且我想知道Python专家对它的看法。
因此,这是修改后的“ DSL解释器”代码(“ cutest.py”):
# DSL command
def test(title):
print("test:", title)
global glb_dict
try:
glb_dict['on_setup']() # function from the current test
except:
print("on_setup() not found")
# DSL command
def expect(str):
print("expect:", str)
# other DSL commands...
def main():
import glob
scripts = glob.glob("test*.py")
global glb_dict
for fname in scripts:
glb_dict = {
"test": test,
"expect": expect
# other commands...
}
print("*******", fname)
try:
exec(open(fname).read(), glb_dict)
except:
print("errors in script:", fname)
if __name__ == "__main__":
main()
第一个更改是使用全局字典glb_dict
而不是globals()
。为每个测试脚本初始化glb_dict
字典,以便从以前的运行中消除任何副作用。
第二个更改是对特定于测试的on_setup()
函数的调用,该函数现在从glb_dict
字典开始,如下所示:glb_dict['on_setup']()
。
修改后的cutest.py
代码执行相同的两个测试脚本,如下所示:
python cutest.py
******* test_1.py
test: My first test
test_1.py:on_setup
expect: foo
******* test_2.py
test: My second test
on_setup() not found
expect: bar
具体来说:(1)找到“ test_1.py:on_setup”函数,(2)在test_2.py中找不到“ on_setup”函数(因为它不存在)。