Python 2.7 如何为嵌入IPythonInteractiveShell的python应用程序编写单元测试
我有一个长时间运行的模拟,我需要在模拟中的给定时间停止,检索并观察一些信息,然后允许模拟继续。我最近开始使用测试驱动的设计方法,不幸的是,我不知道如何对放入交互式shell的应用程序进行单元测试 以下是我尝试做的基本想法:Python 2.7 如何为嵌入IPythonInteractiveShell的python应用程序编写单元测试,python-2.7,ipython,python-mock,Python 2.7,Ipython,Python Mock,我有一个长时间运行的模拟,我需要在模拟中的给定时间停止,检索并观察一些信息,然后允许模拟继续。我最近开始使用测试驱动的设计方法,不幸的是,我不知道如何对放入交互式shell的应用程序进行单元测试 以下是我尝试做的基本想法: # peekaboo.py from IPython import embed from IPython.config.loader import Config PAB_HEADER = 'Hello, my name is PAB. How may I help you?
# peekaboo.py
from IPython import embed
from IPython.config.loader import Config
PAB_HEADER = 'Hello, my name is PAB. How may I help you?'
PAB_EXIT_MESSAGE = 'Goodbye, sir.'
PAB_PROMPT_IN_TEMPLATE = 'In [PAB \\#]: '
PAB_PROMPT_IN2_TEMPLATE = ' .\\D.: '
PAB_PROMPT_OUT_TEMPLATE = 'Out [PAB \\#]: '
def activate(**vars):
"""
Activate PAB 0.1 by starting an interactive shell and putting
the variables in the scope of the caller into the scope of this
method.
"""
# Add variables from caller to this scope
locals().update(vars)
cfg = None
try:
get_ipython
except NameError:
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = PAB_PROMPT_IN_TEMPLATE
prompt_config.in2_template = PAB_PROMPT_IN2_TEMPLATE
prompt_config.out_template = PAB_PROMPT_OUT_TEMPLATE
embed(config=cfg, header=PAB_HEADER, exit_msg=PAB_EXIT_MESSAGE)
下面是一个如何使用peek_a_boo模块的示例:
# long_running_app.py
import peek_a_boo
import datetime
import random
start_dt = datetime.datetime(2013,1,1)
datetimes = [start_dt + datetime.timedelta(days=i) for i in range(10)]
dt_of_interest = datetime.datetime(2013, 1, 8)
def long_running_process(dts):
"""
simulate long running process
"""
some_data = {}
for dt in dts:
some_data[dt] = random.random()
if dt.date() == dt_of_interest.date():
peek_a_boo.activate(**locals())
return some_data
if __name__ == '__main__':
data = long_running_process(datetimes)
print data
我的第一个倾向是使用mock和补丁嵌入方法,并验证是否使用正确的参数调用了它,但我想知道是否有人有其他建议
更新:
因此,我使用nose进行单元测试,并尝试了以下方法:
# test_peek_a_boo.py
import nose
import mock
class TestPeekABoo(object):
def setup(self):
pass
def teardown(self):
pass
@mock.patch('IPython.embed')
def test_activate(self, mock_embed):
"""
Test that the activate method calls IPython embed with the correct arguments
"""
import peek_a_boo
a = 'Hello'
b = 'World'
peek_a_boo.activate(**locals())
mock_embed.assert_called_once_with(header=peek_a_boo.PAB_HEADER, ...)
# test_peek_a_boo.py
import nose
import mock
class TestPeekABoo(object):
def setup(self):
pass
def teardown(self):
pass
@mock.patch('IPython.embed')
def test_activate(self, mock_embed):
"""
Test that the activate method calls IPython embed with the correct arguments
"""
import peek_a_boo
a = 'Hello'
b = 'World'
peek_a_boo.activate(**locals())
mock_embed.assert_called_once_with(header=peek_a_boo.PAB_HEADER, ...)
但当我跑步时:
鼻子测试测试偷看
进程挂起。如果我跑步:
鼻测试测试-偷看测试
我可以看到,我正在将进程放入交互式Shell中
更新2:
通过在测试类的test_方法中导入peek_a_boo,我可以运行上面的测试
这个测试实际上是调用嵌入,但我希望能够测试a和b是否都进入激活方法的本地范围。我提出的解决方案似乎有效,所以我将其作为解决方案发布