[Zope-dev] zope.component test isolation

Wolfgang Schnerring ws at gocept.com
Sat Mar 26 08:41:50 EDT 2011


Hello,

* Martin Aspeli <optilude+lists at gmail.com> [2011-03-26 11:22]:
> On 26 March 2011 08:11, Wolfgang Schnerring <ws at gocept.com> wrote:
> > * Martin Aspeli <optilude+lists at gmail.com> [2011-03-25 13:58]:
> Please also take my word for it when I say that copying the whole
> registry is non-trivial and would rely on brittle ZCA internals. I
> tried. :)

I tried, too, and yup, in the end you'd have to write C to do it
properly (because the AdapterLookupBase or something in zope.interface
is written in C and would need to gain __deepcopy__ support).
But it didn't seem unfeasible, and, when it was all said and done in
Python, not very ugly either.

I appreciate that you've already fought (and won!) against the
whole persistence story (which hadn't even been on my radar so far),
and I guess copying would necessitate reopening that can of worms.

> > I've wanted to specifically nuke registrations sometimes, the pattern
> > being, load the package's configure.zcml in the layer, and then delete
> > something (to demonstrate some error handling behaviour).
> 
> I think you either need to consider a package's ZCML-loaded
> configuration as an atomic part of test setup, or you need to break it
> down into individual registrations. In the first case, your test
> fixture is "package foo's configuration is loaded", which is of course
> valid. In the second case, your fixture is "the following components,
> some of which happen to be in package foo, are registered".
> 
> I don't think a fixture of "package foo's configuration except
> component X and Y" is all that useful.

It seems I can't convey why I think that precisely this is valuable
even without taking into account the desire for non-leaky
abstractions (in the ZODB-analogy it would be quite strange to have to
write on top, please don't delete stuff, it's not supported).

And of course I know how one could work around the limitation that
unregistering is not supported. That doesn't make it any less
inconvenient.

The other point about getSiteManager below is *much* more important
than unregistration support, though:

> > Because that's the API that zope.component offers, it conceptually
> > deals with *two* registries: the one you get from getSiteManager and
> > the one you get from getGlobalSiteManager.
> >
> > I agree that it is unlikely that client code will *read* registrations
> > using getGlobalSiteManager -- since most everyone uses
> > zope.component.getUtility etc. (which in turn uses getSiteManager).
> > But *writing* is a different matter. Just one example:
> > zope.component.provideUtility etc. uses getGlobalSiteManager, while
> > the ZCML directives use getSiteManager.
> >
> > At least as long as zope.component.provide* uses getGlobalSiteManager
> > instead of getSiteManager, I maintain that test infrastructure needs to
> > 1. wrap the global registry
> > 2. wrap whatever getSiteManager currently returns
> > (Otherwise we might be able get away with not doing (1), but I think
> > we'll always need to do (2).)
> >
> > plone.testing has it the other way around, doing (1) but not (2), as
> > Martin says himself...

> We do definitely need to allow the global site manager to be stacked
> (which you can achieve with __bases__ as in plone.testing,
> unregistration notwithstanding). But once you do that, the rest is
> pretty easy. The local site manager will always have the global as one
> of its (nested) __bases__.

I'm sorry, but no, it isn't that easy. When the only local site
consumer is zope.site, well, maybe. But please think of this in terms
of zope.component *only*.

Its API is getSiteManager.sethook(callable), and AFAICT the contract
is that the return value of callable must provide IComponents
(briefly: get* and register*). Nowhere does it say that you have to
delegate back to the global registry, and neither it should. To bring
up Pyramid once again, they explicitly don't, because they want to
allow several applications (thus, several registries) coexisting in
the same process.

And since we can't assume this delegation, I think there is no other
way to properly do the stacking than to bend getSiteManager.

Wolfgang

-- 
Wolfgang Schnerring · ws at gocept.com
gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development


More information about the Zope-Dev mailing list