Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Blog / ZopeTestCase and packages

ZopeTestCase and packages

by Ross Patterson last modified Nov 23, 2008 03:06 AM
Please put ZopeTestCase out of my misery

In this wonderful world between Zope 2 and 3, called limbo... I mean Five, there's a fun little trap concerning ZCML, packages as products and ZopeTestCase.  I wanted to document it somewhere so here it is.

If you're using packages as products, then to install the package as a product for tests, you'll need the ZCML of the package to be loaded.  If the package happens to be included in the configure.zcml of a product,then you'll need Five's loadProducts to have been run in order to install the package as a product.  With ZopeTestCase, in order for a product to be available for Five's loadProducts, installProduct must be called before loadProducts is run.  Five's loadProducts is usually run in the instance's site.zcml which for Plone tests is usually loaded by the ZCML layer.

The end result is that all installProduct calls must be made *before* loadProducts is run which in turn must be run before any installPackage calls can be made if you do any including of packages as products in product configure.zcml files.

Admittedly, this problem goes away if you don't include the ZCML for packages as products inside a product's ZCML.

If anyone is interested here's an example of using layers to work around this:

from Testing import ZopeTestCase
from Products.PloneTestCase import layer

ADDONS = [
    # Your product dependencies here
    ]

class InstallProducts(object):
    """Install products before the ZCML layer so that their ZCML will
    be loaded"""

    @classmethod
    def setUp(cls):
        for dep in ADDONS:
            if ZopeTestCase.hasProduct(dep):
                ZopeTestCase.installProduct(dep)
    
    @classmethod
    def tearDown(cls):
        pass

    @classmethod
    def testSetUp(cls):
        pass

    @classmethod
    def testTearDown(cls):
        pass

class InstallPackages(InstallProducts, layer.ZCML):
    """Install packages after the ZCML layer so that products will
    have had a chance to include the package ZCML"""

    @classmethod
    def setUp(cls):
        for dep in ADDONS:
            if ZopeTestCase.hasPackage(dep):
                ZopeTestCase.installPackage(dep)
    
    @classmethod
    def tearDown(cls):
        pass

    @classmethod
    def testSetUp(cls):
        pass

    @classmethod
    def testTearDown(cls):
        pass
Navigation
OpenID Login

Contact

me@rpatterson.net

IRC: zenwryly@irc.freenode.net
plone.org: rossp
GTalk: mer@patterson.net
Yahoo IM: patterson_ross
AIM: rosspatters
MSN: me@rpatterson.net
Skype: merpattersonnet

PO Box 7775 #10587
San Francisco, CA
94120-7775

Phone
+1 (415) 894-5323