I've added a couple of BrowserViews through paster, now I'm trying to run them from plone.app.testing, because I like repeatable and consistent tests. Calling the view manually from the browser works without any problems.
I've tried both importing and initializing views manually, as well as calling the class from restricted traverse. In both cases an object gets initialized just fine but when I try to trigger rendering either calling the instance as a function or using __call__() method, I get the following error:
*** KeyError: 'global_cache_settings
I looked at the example in README.rst in plone.app.testing it doesn't seem to mention the problem, quick googling didn't yield any results either. It could be one of the site customization, however when greping the source, I found 'global_cache_settings' mentioned in Products.CMFPlone, so it's probably a plone thing:
eggs/Products.CMFPlone-4.1.4-py2.6.egg/Products/CMFPlone/skins/plone_templates/main_template.pt
28: <metal:cache use-macro="context/global_cache_settings/macros/cacheheaders">
29: Get the global cache headers located in global_cache_settings.
eggs/plone.app.layout-2.1.13-py2.6.egg/plone/app/layout/presentation/presentation.pt
11: <metal:cache use-macro="here/global_cache_settings/macros/cacheheaders">
12: Get the global cache headers located in global_cache_settings.
eggs/plonetheme.sunburst-1.1.6-py2.6.egg/plonetheme/sunburst/skins/sunburst_templates/main_template.pt
20: <metal:cache use-macro="context/global_cache_settings/macros/cacheheaders">
21: Get the global cache headers located in global_cache_settings.
Here's relevant class declarations:
from zope.interface import implements, Interface
from Products.Five import BrowserView
from Products.CMFCore.utils import getToolByName
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.MyProduct import MyProductMessageFactory as _
class IPromoBoardHome(Interface):
"""
PromoBoardHome view interface
"""
def __init__(self, context, request):
pass
def __call__(self):
pass
def test():
""" test method"""
class PromoBoardHome(BrowserView):
"""
PromoBoardHome browser view
"""
implements(IPromoBoardHome)
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self):
return ViewPageTemplateFile('pt/promoboardhome.pt')(self)
@property
def portal_catalog(self):
return getToolByName(self.context, 'portal_catalog')
@property
def portal(self):
return getToolByName(self.context, 'portal_url').getPortalObject()
def test(self):
"""
test method
"""
dummy = _(u'a dummy string')
return {'dummy': dummy}
Template:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en"
metal:use-macro="here/main_template/macros/master"
i18n:domain="Products.MyProduct">
<body>
<div metal:fill-slot="main">
<tal:main-macro metal:define-macro="main"
tal:define="testview view/test">
<span tal:content="testview/dummy">test</span>
</tal:main-macro>
</div>
</body>
</html>
configure.zcml declaration:
<browser:page
for="*"
name="promoboardhome"
class=".promoboardhome.PromoBoardHome"
allowed_interface=".promoboardhome.IPromoBoardHome"
permission="zope2.View"
/>
test file:
import unittest2 as unittest
from . import PROD_INTEGRATION_TESTING
from plone.app.testing import setRoles, TEST_USER_ID
from Products.CMFCore.utils import getToolByName
from Products.MyProduct.browser.promoboardhome import PromoBoardHome
class TestPromoBoardHome(unittest.TestCase):
layer = PROD_INTEGRATION_TESTING
def setUp(self):
self.portal = self.layer['portal']
def test_call(self):
pbh = self.portal.restrictedTraverse('@@promoboardhome')
try:
pbh()
except KeyError:
print "that didn't work!"
import pdb; pdb.set_trace()
Am I doing something wrong here?
Browser views are nothing but named multi adapters; to test them you have call them on the right context and to manually set up the request to provide the interface declared for the view; in you case is probably something like this:
from zope.interface import alsoProvides
from Products.MyProduct.browser.promoboardhome import IPromoBoardHome
class TestPromoBoardHome(unittest.TestCase):
layer = PROD_INTEGRATION_TESTING
def setUp(self):
self.portal = self.layer['portal']
self.request = self.layer['request']
alsoProvides(self.request, IPromoBoardHome)
I have a bunch of browser views tests on packages like collective.nitf.
Happy testing!
You probably want to test the views with testbrowser instead:
from plone.testing import z2
browser = z2.Browser(self.layer['app'])
browser.open(self.layer['portal'].absolute_url() + '/@@promoboardhome')
Or similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With