Python 单元测试时如何获得实际的金字塔请求

Python 单元测试时如何获得实际的金字塔请求,python,unit-testing,pyramid,Python,Unit Testing,Pyramid,我有一个金字塔应用程序,我仍在努力学习。我应该为它编写单元测试,但我不知道如何构建请求 我看到Pyramid有一个带有DummyRequest的测试模块,但这是空的,显然,如果我将它传递到视图中,它将失败,因为它没有填充请求在运行时所具有的属性 所以问题是,如何在测试时传递一个看起来像运行时请求的请求?如果您还没有这样做,请查看和。IMHO从功能测试开始,而不是使用DummyRequest进行单元测试,在许多情况下,IMHO倾向于提供更好的结果(即更易于实现和维护)。我建议使用或库(或两者的组合

我有一个金字塔应用程序,我仍在努力学习。我应该为它编写单元测试,但我不知道如何构建请求

我看到Pyramid有一个带有
DummyRequest
的测试模块,但这是空的,显然,如果我将它传递到视图中,它将失败,因为它没有填充请求在运行时所具有的属性


所以问题是,如何在测试时传递一个看起来像运行时请求的请求?

如果您还没有这样做,请查看和。IMHO从功能测试开始,而不是使用DummyRequest进行单元测试,在许多情况下,IMHO倾向于提供更好的结果(即更易于实现和维护)。我建议使用或库(或两者的组合)。使用webtest将允许您测试基本功能,测试通常比Selenium运行得更快。Selenium实际上可以启动浏览器并允许更细粒度的控件。因为它启动了浏览器,所以selenium测试往往需要更长的时间来运行。我认为一个很好的经验法则是,如果您只需要基本测试(例如,查看某个特定页面是否加载),那么请坚持使用Webtest。如果您的测试需要对浏览器进行更多控制(例如调试javascript),请尝试Selenium。查看上面链接的文档,以获取有关如何使用这些库进行测试的示例

我认为Brian的答案是好的,但我想补充一点,“尽可能多地编写易于测试的代码”是一个有用的口号。如果您能够使用您熟悉的非请求依赖的方式使功能模块化并编写易于单元测试的可移植库,那么您将很高兴

与单元测试相比,功能测试更难、更慢、更不好;正如Brian提到的,Webtest是Pyramid的目标。硒是另一个数量级更难、更混乱、更慢的元素。小心;如果您的测试依赖于实际数据,它们将随着时间的推移随着数据的变化而中断。模拟和良好的虚拟数据可以帮助实现这一点。必要时使用更高级别、更困难的测试形式,但不仅仅是为了好玩——您可以在某种程度上使用您的体系结构来减少对它的需求

要回答实际的“你怎么做”问题:如果你有Webtest之类的东西,你只需做一些设置,然后做类似的事情

response = app.get('/form.html')

然后,您就有了一个方便的响应对象,其中包含了您想要的所有信息,然后您就可以编写断言了。这将比我解释得更好。

无论何时进行单元测试(与功能测试不同),都要意识到,您正在测试一个小的“单元”。这个单元(您在本例中的观点)不需要“真实”的请求,也不需要完全工作的系统。该视图对称自己为“请求”的对象可能具有的功能有一定的期望,但仅此而已,它当然不需要真实请求中的所有可用功能。这就是模拟或虚拟对象发挥作用的地方。您希望测试视图,以便可以将某些内容传递到视图中,并提供其所需的属性,以检查其是否正在执行任务。假设您具有以下配置:

def main():
config=Configurator()
config.add_路由('user','/users/{uid}'))
return config.make_wsgi_app()
@查看\u配置(路由\u name='user',渲染器='user\u template.mako')
def用户视图(请求):
uid=request.matchdict['uid']
用户=查找用户(请求,uid)
如果用户为无:
未找到raise HTTPNotFound
返回{'user':user}
def查找用户(请求,uid):
return request.db.query(User).filter_by(id=uid).first()
很好,这是一个真实的视图,您会注意到它只需要请求有两个属性,
matchdict
db
。我们可以做到:

类测试用户视图(unittest.TestCase):
def测试_it(自身):
req=DummyRequest()
req.db=DummyDB()
req.matchdict={uid':'3'}
结果=用户视图(req)
self.assertEqual(结果['user'].id,3)
现在我们这里没有提到的一件事是
DummyDB
的实现,但是更好的方法可能是模拟
find\u user
以返回一个伪值。这使测试保持简单,并集中于视图本身,而不会陷入与数据库的对话中。这是一个单独的测试


这里的其他答案更全面地介绍了功能测试,您应该考虑使用WebTest来帮助确保您的整个应用程序按预期工作,但这不是单元测试的领域。

您可以在设置功能中建立这样的“假”请求:

request = testing.DummyRequest()
request.errors = errors.Errors([])
request.validated = {}
然后在一个测试中设置要测试的参数。像这样:

request.GET['app_id'] = 'xxxxxxxxx'
valid_register(request)
self.assertTrue('app_id' in request.validated)

希望这有助于实现
request.db.query
方法的最佳实践是什么<代码>MagicMock()?回想起来,SQLAlchemy中的查询实际上会返回
User
的一个实例,因此可以模拟让
DummyDB()返回预期的用户号?