{"id":120,"date":"2011-11-03T08:19:30","date_gmt":"2011-11-03T07:19:30","guid":{"rendered":"http:\/\/blog.gocept.com\/?p=120"},"modified":"2012-12-03T15:10:28","modified_gmt":"2012-12-03T14:10:28","slug":"assertion-helper-for-zope-testbrowser-and-unittest","status":"publish","type":"post","link":"https:\/\/blog.gocept.com\/2011\/11\/03\/assertion-helper-for-zope-testbrowser-and-unittest\/","title":{"rendered":"Assertion helper for zope.testbrowser and unittest"},"content":{"rendered":"

zope.testbrowser<\/a> is a valuable tool for integration tests. Historically,\u00a0 the Zope community used to write quite a lot of doctest<\/a>s, but we at gocept have found them to be rather clumsy and too often yielding neither good tests nor good documentation. That’s why we don’t use doctest much anymore, and prefer plain unittest.TestCase<\/a>s instead. However, doctest has one very nice feature, ellipsis matching, that is really helpful for checking HTML output, since you can only make assertions about the parts that interest you. For example, given this kind of page:<\/p>\n

>>> print browser.contents\r\n<html>\r\n\u00a0 <head>\r\n\u00a0\u00a0\u00a0 <title>Simple Page<\/title>\r\n\u00a0 <\/head>\r\n\u00a0 <body>\r\n\u00a0\u00a0\u00a0 <h1>Simple Page<\/h1>\r\n\u00a0 <\/body>\r\n<\/html><\/pre>\n

If all you’re interested in is that the <h1> is rendered properly, you can simply say:<\/p>\n

>>> print browser.contents\r\n<...<h1>Simple Page<\/h1>...<\/pre>\n

We’ve now ported this functionality to unittest, as assertEllipsis, in gocept.testing<\/a>. Some examples:<\/p>\n

self.assertEllipsis('...bar...', 'foo bar qux')\r\n# -> nothing happens\r\n\r\nself.assertEllipsis('foo', 'bar')\r\n# -> AssertionError: Differences (ndiff with -expected +actual):\r\n\u00a0\u00a0\u00a0\u00a0 - foo\r\n\u00a0\u00a0\u00a0\u00a0 + bar\r\n\r\nself.assertNotEllipsis('foo', 'foo')\r\n# -> AssertionError: \"Value unexpectedly matches expression 'foo'.\"<\/pre>\n

To use it, inherit from gocept.testing.assertion.Ellipsis in addition to unittest.TestCase.<\/p>\n","protected":false},"excerpt":{"rendered":"

zope.testbrowser is a valuable tool for integration tests. Historically,\u00a0 the Zope community used to write quite a lot of doctests, but we at gocept have found them to be rather clumsy and too often yielding neither good tests nor good documentation. That’s why we don’t use doctest much anymore, and prefer plain unittest.TestCases instead. However, … Continue reading “Assertion helper for zope.testbrowser and unittest”<\/span><\/a><\/p>\n","protected":false},"author":10315341,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_newsletter_tier_id":0,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[10221],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pFP3y-1W","jetpack-related-posts":[{"id":1752,"url":"https:\/\/blog.gocept.com\/2016\/10\/04\/zope-resurrection-part-2-defibrillation\/","url_meta":{"origin":120,"position":0},"title":"Zope Resurrection Part 2 \u2013 Defibrillation","author":"Michael Howitz","date":"October 4, 2016","format":false,"excerpt":"After\u00a0reanimation\u00a0we started\u00a0defibrillation of Zope and \u2026 it kinda worked: On our\u00a0sprint we got\u00a0the following things done to help\u00a0Zope in the Python 3 wonderland: Release\u00a0zope.testbrowser 5.0\u00a0which is compatible with Python 3 and no longer uses\u00a0mechanize. PullRequest for\u00a0ExtensionClass\u00a0with the Python 3 port of the C extension. five.globalrequest\u00a0is now compatible with Python 3.\u2026","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.gocept.com\/wp-content\/uploads\/2016\/10\/zopesprint.jpg?fit=1200%2C709&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.gocept.com\/wp-content\/uploads\/2016\/10\/zopesprint.jpg?fit=1200%2C709&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.gocept.com\/wp-content\/uploads\/2016\/10\/zopesprint.jpg?fit=1200%2C709&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/blog.gocept.com\/wp-content\/uploads\/2016\/10\/zopesprint.jpg?fit=1200%2C709&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/blog.gocept.com\/wp-content\/uploads\/2016\/10\/zopesprint.jpg?fit=1200%2C709&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":39,"url":"https:\/\/blog.gocept.com\/2011\/01\/24\/testing-pyramid-applications-with-zope-testbrowser\/","url_meta":{"origin":120,"position":1},"title":"Testing pyramid applications with zope.testbrowser","author":"","date":"January 24, 2011","format":false,"excerpt":"The Pyramid documentation recommends using WebTest for functional tests, but coming from the Zope world, zope.testbrowser is the more familiar tool for this job (and it seems a little more high-level than WebTest at first glance). With the 3.11 release,\u00a0 zope.testbrowser gained out-of-the-box support for talking to WSGI applications (courtesy\u2026","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2890,"url":"https:\/\/blog.gocept.com\/2017\/10\/24\/zope4-errorhandling\/","url_meta":{"origin":120,"position":2},"title":"Catching and rendering exceptions","author":"Michael Howitz","date":"October 24, 2017","format":false,"excerpt":"Error handling in Zope 4","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2351,"url":"https:\/\/blog.gocept.com\/2017\/05\/03\/zope-2-resurrection-sprint-day-1\/","url_meta":{"origin":120,"position":3},"title":"Zope 2 Resurrection Sprint \u2013 Day 1","author":"Michael Howitz","date":"May 3, 2017","format":false,"excerpt":"Welcome to the\u00a0Zope 2 Resurrection Sprint in Halle (Saale), Germany. We hope you enjoyed the time since the\u00a0Last call for take off to the Python 3 wonderland. We already achieved some things: Zope 4 no longer depends on\u00a0sourcecodegen\u00a0which was one of Zope's dependencies Earl Zope II\u00a0had to leave behind for\u2026","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2519,"url":"https:\/\/blog.gocept.com\/2017\/05\/27\/move-documentation-from-pythonhosted-org-to-readthedocs-io\/","url_meta":{"origin":120,"position":4},"title":"Move documentation from pythonhosted.org to readthedocs.io","author":"Michael Howitz","date":"May 27, 2017","format":false,"excerpt":"Today we migrated the documentation of zodb.py3migrate\u00a0from\u00a0pythonhosted.org\u00a0to\u00a0zodbpy3migrate.readthedocs.io. This requires a directory \u2013 for this example I name it redir\u00a0\u2013 containing a file named index.html with the following content: zodb.py3migrate<\/title> <meta http-equiv=\"refresh\" content=\"0; url=http:\/\/zodbpy3migrate.rtfd.io\" \/> <\/head> <body> <p> <a href=\"http:\/\/zodbpy3migrate.rtfd.io\"> Redirect to zodbpy3migrate.rtfd.io <\/a> <\/p> <\/body> <\/html> To upload\u2026","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1357,"url":"https:\/\/blog.gocept.com\/2013\/08\/20\/viewing-scales-metrics-from-pyramid\/","url_meta":{"origin":120,"position":5},"title":"Viewing scales metrics from Pyramid","author":"","date":"August 20, 2013","format":false,"excerpt":"We've recently started experimenting with the excellent scales library to collect in-process metrics (see Coda Hale's CodeConf talk \"Metrics everywhere\" among many others for reasons why one definitely wants to do that). Scales comes with a flask-based HTTP server that allows viewing the collected measurements and dumping them as JSON.\u2026","rel":"","context":"In "en"","block_context":{"text":"en","link":"https:\/\/blog.gocept.com\/category\/en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/posts\/120"}],"collection":[{"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/users\/10315341"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/comments?post=120"}],"version-history":[{"count":3,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/posts\/120\/revisions"}],"predecessor-version":[{"id":122,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/posts\/120\/revisions\/122"}],"wp:attachment":[{"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/media?parent=120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/categories?post=120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.gocept.com\/wp-json\/wp\/v2\/tags?post=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}