Load overrides.zcml in plone.app.testing

Today I was working on a project where we use overrides.zcml to easily override some default Plone behavior. All was working fine (in the browser, that is) until I started writing tests for our custom behavior.

First thing I noticed was that the overrides.zcml was not loaded in our test layer. “Doh, I need to load it manually with the loadZCML() method!” I thought to myself. Boy was I wrong :).

The problem with using loadZCML() is that it loads whatever ZCML you tell it to load in a “normal” way. So, obviously, you get conflict errors, since declarations in your overrides.zcml directly map declarations that they override. Hence I needed to find a way to tell plone.app.testing to load my overrides.zcml in an “override” manner and not throw conflict errors.

After quite some research and asking around, I got a tip from JC Brand on the #plone IRC channel: use xmlconfig.includeOverrides(). This indeed got me the exact result I wanted.

Here’s a snippet for my future self and any other plonista struggling with the same problem that happen to stumble upon this blog:

from plone.app.testing import PLONE_FIXTURE
from plone.app.testing import PloneSandboxLayer
from plone.testing import z2
from zope.configuration import xmlconfig


class MyProductLayer(PloneSandboxLayer):

    defaultBases = (PLONE_FIXTURE,)

    def setUpZope(self, app, configurationContext):
        import my.product
        self.loadZCML(package=my.product)
        xmlconfig.includeOverrides(configurationContext, 'overrides.zcml', package=my.product)
        z2.installProduct(app, 'my.product')