[Zope-dev] Dependencies for ZCML
Tres Seaver
tseaver at palladion.com
Thu Mar 12 14:25:29 EDT 2009
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Martijn Faassen wrote:
> Tres Seaver wrote:
> [snip]
>> - -1 on having "configuration dependecies," including having mandatory
>> tests that ZCML will load:
>
> You mean mandatory ZCML loaded by tests? You seem to write the reverse
> here, and I don't understand what that could mean.
Sorry, I meant "mandatory tests which load ZCML." I'm actually against
ever loading ZCML in tests at all.
>> "mandatory configuration is a contradiction
>> in terms." I therefore don't believe that tests which try to load ZCML
>> are useful, at least for "library" pacakges (as opposed to "applications").
>
> Yeah, I know you're a purist on this topic.
>
> Here are some observations on configuration, mandatory or not, and ZCML.
>
> Sometimes you can only test a library when a particular utility or
> adapter or event handler is registered. The library uses this utility or
> adapter in its own logic and while the utility or adapter is intended to
> be replaceable (to make the library pluggable), it is mandatory to
> actually register a component that fulfills the interface requirements
> in order to use the library at all.
Such tests should supply a stub version of the component: they should
*never* rely on a "real" version.
> As a convenience to the users of this library, that library's
> configure.zcml will provide default implementations (which may be the
> right ones in most cases). This is a useful pattern.
That pattern does not lead to good testing.
> I'll note another pattern. A library could define an interface, and a
> few event handlers that react on this interface. Now if you use that
> interface on your own objects, your object will trigger those event
> handlers.
Not if I don't register the handlers. Choosing to register them is
*not* the purview of a library writer.
> Your interest as a library user is not directly in those event
> handlers and you may be unaware of their existence, but they do maintain
> something that is important to you as a user (an index, for example).
Registering such machinery is the job of the application writer, not the
library writer: it is *policy*.
> So this is an example of registrations that should be loaded in order to
> use the library, and there's not even much interest here in overriding
> those registrations - mandatory configuration.
That would defat the whole point of the events machinery, which is to
decouple things. If you can't use a package at all without reigstering
some event handler, then the package isn't a library, it is an application.
> Now when testing these libraries you could do three things:
>
> * not use ZCML at all and recreate the effect of these registrations in
> Python code.
+1.
> * use the ZCML in the package's configure.zcml. (perhaps through
> ftesting.zcml)
- -lots.
> * construct ZCML in the tests itself and load it.
- -0 (I don't see a win over just doing it in Python).
> In fact there's a fourth way you could go and use martian-style
> patterns, where you can manually 'grok' a component in tests that
> inherits a particular base class.
>
> We could argue that all ZCML in use in tests should be rewritten to
> manual registrations from Python code. Is this indeed a useful exercise?
Yes.
> Doesn't that in some cases make tests harder to understand, as
> lower-level APIs are in use that are not as recognizable as the
> equivalent ZCML directives? (say, registering an event) Don't we place a
> burden on the test writers to learn these APIs while they could use the
> ones abstracted away behind ZCML instead?
No. Relying on "real" ZCML in testing, as is using the "real"
components is an anti-pattern: it makes tests fragile, couples the
packages tightly, etc.
> I will also repeat my observation that if a package has ZCML in it that
> never gets loaded by the tests of that package, that means that there
> are no automatic tests for this ZCML. There is something in this package
> that is not tested and can only be tested indirectly. Isn't that
> something we try to avoid?
*I* don't care about testing ZCML at the package level: I don't think
it is useful, and I find that it actively screws up "real" tests.
Testing the "real" configuration is something which makes sense for
applications, not reusable library packages.
> What do we gain dependency-wise by avoiding the loading of ZCML during
> tests but do manual registrations instead?
We don't try to re-use the "real" components which that ZCMl would
register, and therefore don't depend on the other package at all.
> We *may* get rid of
> dependencies on zope.configuration. If the definition of ZCML directives
> were always strictly separated from the functionality that these
> directives manipulate, then this would often be the case. In reality
> this is frequently not so, however. We may also get rid of such "ZCML
> directive definition only" packages, for instance zope.componentzcml.
>
>> Any ZCML file which needs something like zope.component or zope.security
>> to be present should signalt that by either including the meta.zcml
>> (e.g., to define directives) or nesting the dependent directives inside
>> a "conditional" block, whose predicate documents the requirement.
>
> You're saying that we should be an include of the zope.component
> 'meta.zcml' in *all* ZCML files that register an adapter? This is
> certainly not happening always now. That's like import before usage in
> Python modules, right?
Yes. If you are going to try to make ZCML reusable, then it can't make
assumptions about another package having done meta-registrations on its
behalf.
> I'll note that martian-based code actually does use that pattern - any
> package based on grokcore.* for instance automatically follows this
> pattern.
>
> I'll also note that with martian-based configuration the situation is
> clear for setup.py: the dependencies needed for configuration are always
> normal dependencies of a package.
>
> With ZCML-based configuration the situation is far less clear.
>
> So what does all of this mean for Dan's question? I don't know yet.
>
> I think we should observe some packages. We strive for library-like
> packages. More library-like packages should likely not have to do a lot
> of work in their configure.zcml, but the amount of work is not always
> zero. Dan, do you have any examples of packages where you are wondering
> about what to do? Let's examine then and reason about how they could be
> organized.
I don't think "library" packages have ZCML in them at all, except as
examples, because trying to reusing ZCML doesn't actually win
unambiguosly over copying it.
Tres.
- --
===================================================================
Tres Seaver +1 540-429-0999 tseaver at palladion.com
Palladion Software "Excellence by Design" http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFJuVOZ+gerLs4ltQ4RAmYqAJ0d2XMSXSV7YFg40lmAzSmAlMNA9QCeKfof
kIRv8VvmcFehqJLkI7T3U9w=
=FEjR
-----END PGP SIGNATURE-----
More information about the Zope-Dev
mailing list