[Zope3-Users] Calling a view in a doc test

Florian Lindner mailinglists at xgm.de
Mon Jun 18 16:14:14 EDT 2007


Am Dienstag, 5. Juni 2007 schrieb Marius Gedminas:
> On Tue, Jun 05, 2007 at 04:49:37PM +0200, Florian Lindner wrote:
> > Am Montag, 4. Juni 2007 schrieb Marius Gedminas:
> > > On Mon, Jun 04, 2007 at 03:14:16PM +0200, Florian Lindner wrote:
> > > > in a doctest I have an object which has a view registered.
> > > > I want to call this view and test for the XML it returns.
> > > > How can I call the view so that it is being rendered, just like
> > > > called by a browser?
> >
> > I have thes setup and tearDown methods:
> >
> > import unittest
> > import zope.testing.module
> > from zope.testing import doctest
> > from zope.component import testing, eventtesting
> > from zope.app.container.tests.placelesssetup import PlacelessSetup
> > from zope.app.testing import setup
> >
> > container_setup = PlacelessSetup()
> >
> > def blogSetUp(test):
> >     zope.testing.module.setUp(test, 'Blog.doctest')
> >     testing.setUp(test)
> >     eventtesting.setUp(test)
> >     container_setup.setUp()
> >     setup.placelessSetUp()
> >     setup.setUpTraversal()
> >
> > def blogTearDown(test):
> >     setup.placelessTearDown()
> >     zope.testing.module.tearDown(test)
> >     testing.tearDown(test)
>
> Oh, my, this feels like cargo-cult programming[1] to me.  For example,
> zope.app.testing.setup.placelessSetUp() calls
> zope.app.container.tests.placelesssetup.PlacelessSetup().setUp() for you
> already, you don't need to do it twice.  In fact the
> CleanUp().cleanUp(), which is the first thing that placelessSetUp()
> calls, undoes all the changfes made by container_setup.setUp().  The
> same applies to zope.component.testing.setUp.
>
>   [1] http://en.wikipedia.org/wiki/Cargo_cult_programming

You're probably right about that, I've very little experience with the testing 
framework.

> I would suggest that you remove everything and keep just
>
>   def blogSetUp(test):

zope.testing.module.setUp(test, 'Blog.doctest')

it worked after I've added the line above.

>       setup.placelessSetUp()
>       setup.setUpTraversal()
>
>   def blogTearDown(test):
>       setup.placelessTearDown()
>
> > and this is my README.txt containing the test:
> >     >>> context = MyBlog
>
> You may want to actually create the object:
>       >>> context = MyBlog()

MyBlog is the instance.

> and sometimes it is a good idea to put it into the containment
>
> hierarchy, if you're going to look up things like absolute URLs:
>       >>> from zope.app.folder import rootFolder
>       >>> root = rootFolder()
>       >>> root['my_blog'] = context
>       >>>
> >     >>> from zope.publisher.browser import TestRequest
> >     >>> from browser.views import RSSFeed
> >     >>> request = TestRequest()
> >     >>> view = RSSFeed(context, request)
> >     >>> print view()
> >
> > Since my code includes a call to absoluteURL I have added your setup and
> > tearDown methods. But there is still an error:

Thanks, now it works!

> > BTW: What would be the name of the MyViewClass if the page would be
> > registered without a class set?
>
> There isn't one.  When you use the <browser:page> directive, the ZCML
> maaagick creates a new class (with a funky name) at runtime, with extra
> attributes and methods.  You cannot access that class from a unit test,
> because it doesn't exist in your source code.
>
> My suggestion is "don't do that".  If you want a view with just a
> template, and you want to render it in a unit test, define a view class
>
>    class MyTrivialViewClass(BrowserPage):
>        __call__ = ViewPageTemplateFile('mytemplate.pt')

Regards,

Florian


More information about the Zope3-users mailing list