以正确的方式设置Pyramid 1.5测试

时间:2015-11-18 09:42:05

标签: python integration-testing pyramid pytest

虽然Pyramid文档通常非常好,但我找不到如何设置integration tests for a Pyramid 1.5 application(注意缺少必要的代码片段!)。也就是说,在哪里放置特定的配置。

在__init__中我有main()函数,其中包含一些其他模块,其中有一个模块需要SQLAlchemy。另一个复杂因素是auth策略依赖于设置,所以所有这些都存在于main中(否则我会使用includeme,不确定它是否与此问题相关)。

起初我尝试了以下内容(在收集了我可以进入includeme函数之后):

class ViewTests(unittest.TestCase):
    def setUp(self):
        self.config = testing.setUp()
        self.config.include('myproject.includeme')

当然在sqlalchemy engine_from_config中某处失败了。 但后来我found,我可以使用main()并提供test.ini进行配置。我仍然喜欢这个包含所有内容的方法:

class IntegrationTestBase(BaseTestCase):
    @classmethod
    def setUpClass(cls):
        cls.app = main({}, **settings)
        super(IntegrationTestBase, cls).setUpClass()

    def setUp(self):
        self.app = webtest.TestApp(self.app)
        self.config = testing.setUp()
        super(IntegrationTestBase, self).setUp()

上面代码的部分问题是设置不会以self.config结尾。如果我使用self.config = testing.setUp(settings=settings)对其进行增强,则测试仍会失败:

AttributeError: 'DummyRequest' object has no attribute 'include'

pyramid_bowerstatic没有机会修改请求等等。所以,不要让开箱即用的集成测试(应用程序本身没有抱怨!)与给定的配置并集中精力编写测试,我需要关心所有第三方模块。

因此,我希望有一些更好的方法来进行集成测试,这些测试涉及多个包含的包,自定义身份验证策略,事件和其他“魔法”。

如果重要的话,可以使用Py.test。 pytest_pyramid似乎是相关的,但是文档没有任何示例。

不完全,但类似的问题:How to Make view_config decorator work with a Pyramid Unit Test?,特别是在答案的评论中。

我找到了日语的临时解决方案(现在对我有用):http://qiita.com/podhmo/items/2c6d8cb78c1f84569f0a

但问题是如何可靠地设置集成测试,相当于所有方面的应用程序,而不考虑第三方模块,除了特定的ini文件?

更新:这是有问题的电话之一:

查看:

components = pyramid_bowerstatic.create_components('sbadmin',
             os.path.join(os.path.dirname(__file__), 'bower_components'))
class MainViews(Layouts):
    @view_config(route_name='home', renderer='templates/mytemplate.pt')
    def my_view(self):
        self.request.include(components, 'jquery')
        return {'project': 'Myproject'}

在测试中:

class ViewTests(IntegrationTestBase):
    def test_my_view(self):
        from myproject.views.main import MainViews
        request = self._make_request(self.config)  # before was: DummyRequest
        info = MainViews(request).my_view()
        self.assertEqual(info['project'], 'Myproject')

由于金字塔的结构很好地分离,所以可能有足够的包容性请求。也就是说,问题可以重新表述为:什么是泛型_make_request函数,它给出的结果与正在运行的应用程序请求相同(包括扩展,补间,添加的请求属性,包括来自第三方模块的那些等)?是否有一些现成的工厂?恕我直言,如果开发人员需要模拟它自己的“集成”以进行测试而不是采用什么样的应用程序,那么它不是集成测试。我不确定这些是否是唯一的东西,但我想工厂应该至少提供一个请求,包括这里提到的所有钩子:http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/hooks.html无论包含哪些包都添加了它们。

更新2 :我想到了测试和运行时环境之间存在差异的第一个近似指标。我已经比较了对视图的正常调用和测试调用的请求。首先,这是我的_make_request,它足以添加请求方法,但缺少更多(下面):

def _make_request(self, config, path="/"):
    from pyramid.request import Request
    from pyramid.interfaces import IRequestExtensions
    request = Request.blank(path)
    extensions = config.registry.getUtility(IRequestExtensions)
    request.registry = config.registry
    request._set_extensions(extensions)
    return request

正常调用具有以下属性(request .__ dict __。keys()):

['traversed',
 'virtual_root',
 'virtual_root_path',
 'subpath',
 'request_iface',
 '__view__',
 'view_name',
 'tm',
 'environ',
 'registry',
 'context',
 'matched_route',
 'get_bowerstatic_path',
 'include',
 'root',
 'matchdict',
 'invoke_subrequest']

只测试这些:

['environ',
'registry',
'get_bowerstatic_path',
'include']

这清楚地表明,我的方法还不够,我将遇到使用其他请求功能的视图问题。使用上面的_make_request,只有最小的视图可以通过。

换句话说,如何获得在功能测试中使用的相同请求,例如在webtest的TestApp中,但不是执行testapp.get(...),而是使用该请求调用视图并对可调用的返回结果进行断言(不呈现为HTML)?

1 个答案:

答案 0 :(得分:1)

由于RTD上的临时错误,缺少必要的代码片段。 An Issue has been logged

这是未包含的代码的链接。 https://github.com/Pylons/pyramid/blob/master/docs/narr/MyProject/myproject/tests.py#L19-L43

[被修改]

以下是金字塔炼金术脚手架测试的两个例子。每个人都有自己的风格。希望你发现其中一个对你的场景很有用。

  1. 如果您安装了金字塔,您可以从炼金术脚手架创建一个示例项目。

    $ $VENV/bin/pcreate -s alchemy tutorial
    

    如果该命令不适合你,SQLAlchemy + URL Dispatch Wiki Tutorial会详细介绍和先决条件。

    脚手架包括这些tests

  2. 我们正在开发一个更新此脚手架的新分支,并且目标是在Pyramid 1.7中进行合并。这是tests

    如果你git checkout那个分支,并通过教程步骤,你可以看到完整的上下文。

  3. [被修改]

    这里还有一个地方可以看:Pyramid's own integration tests

    顺便说一句,我很难给你一个合适的答案。对于初学者,我没有看到在测试代码中调用DummyRequest的位置。你能在问题中给出一个完整的可重复的例子吗?