<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://www.rpatterson.net/</id>
  <title>Ross Patterson's Blog - Posts tagged Testing</title>
  <updated>2025-07-14T00:00:48.997228+00:00</updated>
  <link href="https://www.rpatterson.net/"/>
  <link href="https://www.rpatterson.net/blog/tag/testing/atom.xml" rel="self"/>
  <generator uri="https://ablog.readthedocs.io/" version="0.11.12">ABlog</generator>
  <entry>
    <id>https://www.rpatterson.net/blog/emerald-sprint-report-out/</id>
    <title>Emerald Sprint Report Out</title>
    <updated>2013-02-13T00:00:00+00:00</updated>
    <author>
      <name>Ross Patterson</name>
    </author>
    <content type="html">&lt;section id="emerald-sprint-report-out"&gt;

&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Merging versioning and and constrained types into Dexterity near Beautiful Seattle.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Thanks to the fabulous &lt;a class="reference external" href="http://seattleplone.org"&gt;Seattle Plone folk&lt;/a&gt;, we had another west
coast sprint, the &lt;a class="reference external" href="http://www.coactivate.org/projects/emerald-sprint/project-home"&gt;Emerald Sprint&lt;/a&gt;, on lovely &lt;a class="reference external" href="https://maps.google.com/maps?q=48.16269,-122.467258&amp;amp;ll=47.890564,-122.437134&amp;amp;spn=2.232193,5.410767&amp;amp;num=1&amp;amp;t=h&amp;amp;gl=us&amp;amp;z=8"&gt;Camano Island&lt;/a&gt;.  The
focus was polishing &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.dexterity"&gt;Dexterity&lt;/a&gt;, it was a gorgeous location, a very
productive sprint, and I very much hope we can make it an annual
thing.  We might have a better chance at that if we choose a topic
next year such that &lt;a class="reference external" href="http://glicksoftware.com/"&gt;David&lt;/a&gt; can just be another sprinter for once.
:-)&lt;/p&gt;
&lt;p&gt;Firstly, I have to give a huge shout out to our Maven of Fine Dining,
&lt;a class="reference external" href="http://www.linkedin.com/in/skleinfeldt"&gt;Sally&lt;/a&gt;, and to &lt;a class="reference external" href="www.linkedin.com/pub/alice-tseng/4/275/530"&gt;Alice&lt;/a&gt; for yet more above-and-beyond contributions
to the culinary experience of this sprint.  The food was simply
incredible and I have to say I &lt;em&gt;love&lt;/em&gt; a sprint that has that element.
I was spoiled before by the cooking at the &lt;a class="reference external" href="../cioppino-sprint-2012"&gt;Cioppino Sprint&lt;/a&gt; and the
&lt;a class="reference external" href="../sea-sprint-2012-report-out"&gt;Sea Sprint&lt;/a&gt; and the food at this sprint may have out done them!&lt;/p&gt;
&lt;p&gt;The sprint location was an excellent choice and everything was very
well organized by &lt;a class="reference external" href="http://crisewing.com/"&gt;Cris&lt;/a&gt;, &lt;a class="reference external" href="https://twitter.com/luke_brannon"&gt;Luke&lt;/a&gt;, &lt;a class="reference external" href="http://solitonconsulting.com/"&gt;Fulvio&lt;/a&gt; and &lt;a class="reference external" href="http://glicksoftware.com/"&gt;David&lt;/a&gt;.  I was
very sad to learn that &lt;a class="reference external" href="http://crisewing.com/"&gt;Cris&lt;/a&gt; wasn’t going to be able to stay for the
sprint and wish him the best.  Thanks also to &lt;a class="reference external" href="http://andersonleeb.com/"&gt;Ian Anderson and Andy
Leeb&lt;/a&gt; for treating us to a delicious dinner out on our first night.&lt;/p&gt;
&lt;p&gt;We did a brainstorming session where we all voted for what we found to
be the most important.  Then &lt;a class="reference external" href="http://glicksoftware.com/"&gt;David&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/MatthewWilkes"&gt;Matthew&lt;/a&gt; marked the items
that they thought were clear low-hanging fruit that didn’t require a
lot of design or other discussion. After seeing what the other
sprinters chose for I opted for tackling some of the remaining
low-hanging fruit.  That ended up being two tasks both of which
involved merging work done by others previously in add-ons or other
packages not in Dexterity core where they belong: &lt;a class="reference external" href="https://trello.com/card/better-versioning-support/50d18b10540c21f830003269/9"&gt;versioning&lt;/a&gt; and
&lt;a class="reference external" href="https://trello.com/card/ui-for-setting-the-subtypes-for-containers/50d18b10540c21f830003269/21"&gt;constrained types&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Working on &lt;a class="reference external" href="https://trello.com/card/better-versioning-support/50d18b10540c21f830003269/9"&gt;versioning&lt;/a&gt; involved merging two add-on packages into
&lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.dexterity"&gt;Dexterity&lt;/a&gt; core.  The &lt;a class="reference external" href="http://pypi.python.org/pypi/collective.cmfeditionsdexteritycompat"&gt;collective.cmfeditionsdexteritycompat&lt;/a&gt;
add-on makes it possible to use the history view on Dexterity content
and I merged it into &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.versioningbehavior"&gt;plone.app.versioningbehavior&lt;/a&gt;.  The
&lt;a class="reference external" href="http://pypi.python.org/pypi/collective.dexteritydiff"&gt;collective.dexteritydiff&lt;/a&gt; add-on brings parity with &lt;a class="reference external" href="http://plone.org/products/archetypes"&gt;Archetypes&lt;/a&gt;
when viewing diffs between versions and I merged it into
&lt;a class="reference external" href="http://pypi.python.org/pypi/Products.CMFDiffTool"&gt;Products.CMFDiffTool&lt;/a&gt;.  Both packages were done by &lt;a class="reference external" href="http://rafaelb.objectis.net/"&gt;Rafael
Oliveira&lt;/a&gt; and worked perfectly, my only job was doing the merge and
reconciling the tests.  Fortunately, &lt;a class="reference external" href="http://rafaelb.objectis.net/"&gt;Rafael&lt;/a&gt; had written tests &lt;em&gt;and&lt;/em&gt;
had done so using &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.testing/4.2.2"&gt;plone.app.testing&lt;/a&gt;.  &lt;em&gt;Unfortunately&lt;/em&gt;,
&lt;a class="reference external" href="http://pypi.python.org/pypi/Products.CMFEditions"&gt;Products.CMFEditions&lt;/a&gt; does not use &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.testing/4.2.2"&gt;plone.app.testing&lt;/a&gt; and since
such tests can not run in the same test run as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ZopeTestCase&lt;/span&gt;&lt;/code&gt; tests
are run, that meant I had to back-port the tests &lt;a class="reference external" href="http://rafaelb.objectis.net/"&gt;Rafael&lt;/a&gt; wrote off
of &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.testing/4.2.2"&gt;plone.app.testing&lt;/a&gt; back to &lt;cite&gt;ZopeTestCase&lt;/cite&gt;.  I hate going
backwards but enough things build on the &lt;a class="reference external" href="http://pypi.python.org/pypi/Products.CMFEditions"&gt;Products.CMFEditions&lt;/a&gt; tests
that I guessed it would take too long and be to disruptive to convert
all those tests.  After that, I spent the rest of the sprint trying to
complete my &lt;a class="reference external" href="https://github.com/plone/plone.app.testing/tree/simpler-helpers"&gt;plone.app.testing.api&lt;/a&gt; branch which is intended to make
such conversions easier.&lt;/p&gt;
&lt;p&gt;I also had the opportunity to bring &lt;a class="reference external" href="https://picasaweb.google.com/lh/photo/Pq5EEJ3K2izy6gP4aGsrJNMTjNZETYmyPJy0liipFm0?feat=directlink"&gt;Gin Apocrypha&lt;/a&gt; with me and bar
tend for the event.  It was my first time trying to check enough items
on the plane to be able to mix my whole menu and it actually worked
out very well.  So I think I may be willing to check a bag in the
future to be able to bring &lt;a class="reference external" href="https://picasaweb.google.com/lh/photo/Pq5EEJ3K2izy6gP4aGsrJNMTjNZETYmyPJy0liipFm0?feat=directlink"&gt;Gin Apocrypha&lt;/a&gt; to events I don’t drive to
in the future!&lt;/p&gt;
&lt;p&gt;It was a great sprint and I love the Seattle area so I really hope
this happens again.  This sprint being focused on &lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.dexterity"&gt;Dexterity&lt;/a&gt; and
&lt;a class="reference external" href="http://glicksoftware.com/"&gt;David&lt;/a&gt; being Dexterity’s maintainer and fearless leader, I know I
pestered him a lot as I needed to ask questions and get perspective,
but he did a great job facilitating everything.  For that reason if no
other, I hope the next Emerald Sprint can be on a topic such that
David can get back to basics and enjoy being just another sprinter
again.  :-)&lt;/p&gt;
&lt;div class="note update admonition"&gt;
&lt;p class="admonition-title"&gt;Updated on 13 February 2013&lt;/p&gt;
&lt;p&gt;Imported from Plone on Mar 15, 2021.  The date for this update is the last
modified date in Plone.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
</content>
    <link href="https://www.rpatterson.net/blog/emerald-sprint-report-out/"/>
    <summary>Merging versioning and and constrained types into Dexterity near Beautiful Seattle.</summary>
    <category term="Plone" label="Plone"/>
    <category term="Python" label="Python"/>
    <category term="Testing" label="Testing"/>
    <category term="Zope" label="Zope"/>
    <published>2013-02-13T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://www.rpatterson.net/blog/looking-for-projects-and-or-a-team/</id>
    <title>Looking for Projects and/or a Team</title>
    <updated>2012-11-09T00:00:00+00:00</updated>
    <author>
      <name>Ross Patterson</name>
    </author>
    <content type="html">&lt;section id="looking-for-projects-and-or-a-team"&gt;

&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;I’m available for work and am interested in contract/consultant projects or a position with a team.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;I’m available and looking for new opportunities.  My strengths are
&lt;a class="reference external" href="http://www.python.org/"&gt;Python&lt;/a&gt; web programming, particularly &lt;a class="reference external" href="http://plone.org"&gt;Plone&lt;/a&gt; and &lt;a class="reference external" href="http://zope.org"&gt;Zope&lt;/a&gt; with
strong testing skills and habits.  See &lt;a class="reference external" href="http://www.linkedin.com/in/rossp"&gt;my LinkedIn profile&lt;/a&gt; or &lt;a class="reference external" href="http://careers.stackoverflow.com/rpatterson"&gt;my
Careers 2.0 profile&lt;/a&gt; for more details.  I’m interested in the
following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Pyramid or Plone are preferred technologies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;open to any Python web work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;would be nice to work on social justice or other activism projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;open to work with a good team on any kind of project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;working from remote most of the time is preferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;open to on-site opportunities in San Francisco&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please contact me if you’re looking for anyone or know of anyone who is.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Name&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Ross Patterson&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Resume&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.linkedin.com/in/rossp"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;Resume&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;&lt;a class="reference external" href="http://careers.stackoverflow.com/rpatterson"&gt;Careers 2.0&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;GitHub&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/rpatterson?tab=activity"&gt;rpatterson&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;Email&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:me&amp;#37;&amp;#52;&amp;#48;rpatterson&amp;#46;net"&gt;me&lt;span&gt;&amp;#64;&lt;/span&gt;rpatterson&lt;span&gt;&amp;#46;&lt;/span&gt;net&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Phone&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;+1 (415) 894-5323&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;IRC&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:zenwryly&amp;#37;&amp;#52;&amp;#48;irc&amp;#46;freenode&amp;#46;net"&gt;zenwryly&lt;span&gt;&amp;#64;&lt;/span&gt;irc&lt;span&gt;&amp;#46;&lt;/span&gt;freenode&lt;span&gt;&amp;#46;&lt;/span&gt;net&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;plone.org&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;&lt;a class="reference external" href="http://plone.org/author/rossp"&gt;rossp&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;GTalk&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:merpattersonnet&amp;#37;&amp;#52;&amp;#48;gmail&amp;#46;com"&gt;merpattersonnet&lt;span&gt;&amp;#64;&lt;/span&gt;gmail&lt;span&gt;&amp;#46;&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Yahoo IM&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;patterson_ross&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;AIM&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;rosspatters&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;MSN&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:me&amp;#37;&amp;#52;&amp;#48;rpatterson&amp;#46;net"&gt;me&lt;span&gt;&amp;#64;&lt;/span&gt;rpatterson&lt;span&gt;&amp;#46;&lt;/span&gt;net&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-odd"&gt;Skype&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;merpattersonnet&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="note update admonition"&gt;
&lt;p class="admonition-title"&gt;Updated on 09 November 2012&lt;/p&gt;
&lt;p&gt;Imported from Plone on Mar 15, 2021.  The date for this update is the last
modified date in Plone.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
</content>
    <link href="https://www.rpatterson.net/blog/looking-for-projects-and-or-a-team/"/>
    <summary>I’m available for work and am interested in contract/consultant projects or a position with a team.</summary>
    <category term="Plone" label="Plone"/>
    <category term="Pyramid" label="Pyramid"/>
    <category term="Python" label="Python"/>
    <category term="TDD" label="TDD"/>
    <category term="Testing" label="Testing"/>
    <category term="Zope" label="Zope"/>
    <published>2012-10-30T00:00:00+00:00</published>
  </entry>
  <entry>
    <id>https://www.rpatterson.net/blog/sea-sprint-2012-report-out/</id>
    <title>Sea Sprint 2012 Report-Out</title>
    <updated>2012-09-26T00:00:00+00:00</updated>
    <author>
      <name>Ross Patterson</name>
    </author>
    <content type="html">&lt;section id="sea-sprint-2012-report-out"&gt;

&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;A Python snob’s adventures in JS testing land.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;I was surprised and excited to receive an invite to the first Sea
Sprint from &lt;a class="reference external" href="http://plone.org/author/cbc"&gt;Chris Calloway&lt;/a&gt;.  When I read that it was also being put
on by Andrew Leeb and Ian Anderson of &lt;a class="reference external" href="http://andersonleeb.com/"&gt;Anderson Leeb, Inc.&lt;/a&gt; I knew I
wanted to go.  I’d had the chance to hang out with them at the &lt;a class="reference external" href="http://weblion.psu.edu/symposium"&gt;Plone
Symposium East 2012&lt;/a&gt; and the &lt;a class="reference external" href="http://www.coactivate.org/projects/pre-pse12-strategicesque-sprintacular/project-home"&gt;sprints before&lt;/a&gt; and &lt;a class="reference external" href="http://weblion.psu.edu/symposium/schedule/sprints"&gt;after&lt;/a&gt; and
enjoyed their company a lot.  When I heard I could get my airfare
sponsored, I knew I absolutely had to go.  Not to geek out, but this
was the first sprint travel sponsorship and I’m pretty excited about
that.&lt;/p&gt;
&lt;section id="location-and-hosting"&gt;
&lt;h2&gt;Location and Hosting&lt;/h2&gt;
&lt;p&gt;This was one of the better organized sprints I’ve been to.  Flights
were coordinated to arrive and depart within 1-2 hours of each other
making rides around arrival and departure fast and easy.  We got to
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Oak_Island,_North_Carolina"&gt;Oak Island&lt;/a&gt;, a beautiful and very long barrier island not far from
the border with South Carolina, Friday afternoon and had some time to
go to the beach and go for a quick swim.&lt;/p&gt;
&lt;p&gt;I’d never been to the atlantic coast on either side nor had I been to
the Carolinas before and have always wanted to.  Living on the north
Pacific for so long, I’ve never swam in warm ocean water before, very
interesting.  The two beach houses were &lt;em&gt;right on the beach&lt;/em&gt; with deck
walks extending out to the dunes and a covered outside area.  The beds
were comfy and there were great views all the way around.  It was
off-season but the temperatures were still warm to temperate so there
were no crowds and great weather.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://plone.org/author/cbc"&gt;Chris Calloway&lt;/a&gt; is simply an &lt;em&gt;amazing cook&lt;/em&gt;.  He made breakfast,
lunch, and dinner for 14 people almost entirely by himself both
Saturday and Sunday.  As if the scope of that weren’t enough, these
meals were top-notch.  Seriously, the food really has to be called out
here.  Thanks so much Chris!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-sprint"&gt;
&lt;h2&gt;The Sprint&lt;/h2&gt;
&lt;p&gt;After a delicious dinner at a local Thai restaurant sponsored by Dylan
Jay, &lt;a class="reference external" href="http://glicksoftware.com/"&gt;David Glick&lt;/a&gt; did an excellent job facilitating the planning of the
sprint work.  This was the most efficient sprint planning I’ve been
to, great job David!  Before we went to bed Friday night, we all knew
what we were working on the next day.&lt;/p&gt;
&lt;p&gt;My biggest hope for my participation in this sprint was to get better
at &lt;a class="reference external" href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;/&lt;a class="reference external" href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMASCript&lt;/a&gt; while still contributing towards the
goals of the sprint.  I’ve been confounded by JS much more than I’d
like and have never really been able to develop the proficiency I’d
like with it.  Since I learn best by writing tests with a good
&lt;a class="reference external" href="http://docs.python.org/library/unittest.html"&gt;testing framework&lt;/a&gt;, I decided to work on writing JS unit tests for
the bits of Deco and the toolbar that are JS heavy:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.tiles"&gt;plone.app.tiles&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.deco"&gt;plone.app.deco&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.toolbar"&gt;plone.app.toolbar&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I started working with &lt;a class="reference external" href="http://blog.fourdigits.nl/robgietema/robgietema"&gt;Rob Gietema&lt;/a&gt;, someone whose mad JS skills
I’ve always admired, and &lt;a class="reference external" href="http://claytron.com/blog"&gt;Clayton Parker&lt;/a&gt;, who is much in the same
boat as I when it comes to JS skills.  Rob introduced us to
&lt;a class="reference external" href="http://busterjs.org/"&gt;Buster.JS&lt;/a&gt;, a new cross-browser JS unit testing framework that
everyone seems to prefer to use.  Clayton began writing tests for
&lt;a class="reference external" href="http://pypi.python.org/pypi/plone.app.tiles"&gt;plone.app.tiles&lt;/a&gt; JS and I began looking into ways to integrate the
Buster.JS tests into our general testing story.&lt;/p&gt;
&lt;p&gt;In Plone land, our &lt;a class="reference external" href="http://www.buildout.org"&gt;buildouts&lt;/a&gt; do a pretty good job of serving two
testing purposes:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Developers&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Deployed locally and give individual developers a &lt;a class="reference external" href="http://pypi.python.org/pypi/zope.testrunner"&gt;test runner&lt;/a&gt;
they can use to run some or all of the tests before they commit
changes.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Continuous Integration&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Deployed on our &lt;a class="reference external" href="http://jenkins-ci.org/"&gt;CI server&lt;/a&gt; to run all tests and catch regressions
and interactions.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I set my sights on providing something that served the same two purposes
for JS unit tests.&lt;/p&gt;
&lt;p&gt;When we started, running the &lt;a class="reference external" href="http://busterjs.org/"&gt;Buster.JS&lt;/a&gt; tests was a fairly manual
process and done in a very different way than running our other tests.
One had to:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;change directories&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fire up the &lt;a class="reference external" href="http://busterjs.org/docs/server-cli/"&gt;buster-server&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;capture a &lt;a class="reference external" href="http://busterjs.org/docs/capture-server/"&gt;browser slave&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run &lt;a class="reference external" href="http://busterjs.org/docs/test/runner/"&gt;buster-test&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I started working on automating as much of this as possible and
integrating it with our buildout test runners if possible.&lt;/p&gt;
&lt;p&gt;I didn’t make much progress on the first day, Saturday.  In the
morning, I was mostly learning how things were done and understanding
the architecture.  After lunch, I had a pretty good idea of what I
wanted to do, so I began trying to understand the &lt;a class="reference external" href="http://busterjs.org/"&gt;Buster.JS&lt;/a&gt;
internals enough to add what we needed.  That turned out to be a
pretty deep rabbit hole for me at my JS skill level so in the evening,
I abandoned that effort and started writing a &lt;a class="reference external" href="https://github.com/plone/buildout.deco/blob/24cddf529507cf0d1e198783dd8b8c25b6ab3fb7/buster-alltests.in"&gt;simple Python script&lt;/a&gt;
that would do the all the steps for you and finally shutdown the
browser slave and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;buster-server&lt;/span&gt;&lt;/code&gt;.  At least I was getting
somewhere.&lt;/p&gt;
&lt;p&gt;With that experience under my belt, I knew that what we needed was:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/zope.testrunner#test-runner"&gt;test discovery&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/zope.testrunner#layers"&gt;shared test fixture&lt;/a&gt; set up and tear down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;control of &lt;a class="reference external" href="http://pypi.python.org/pypi/zope.testrunner#test-selection"&gt;which tests&lt;/a&gt; are run&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Look familiar?  These are all the services provided by
&lt;a class="reference external" href="http://pypi.python.org/pypi/zope.testrunner"&gt;zope.testrunner&lt;/a&gt; that we make so much use of in our buildouts.&lt;/p&gt;
&lt;p&gt;There was one more issue in that capturing browser slaves by just
running &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;firefox&lt;/span&gt;&lt;/code&gt; meant that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;buster-test&lt;/span&gt;&lt;/code&gt; runs could potentially
be polluted by any extensions, themes, or other add-ons in your
Firefox profile.  The same would be in similar senses for other
browsers.  This is also a familiar issue, which is precisely why
&lt;a class="reference external" href="http://seleniumhq.org/docs/03_webdriver.html"&gt;selenium.webdriver&lt;/a&gt; does a lot to invoke the browsers it’s driving
in an isolated way.&lt;/p&gt;
&lt;p&gt;So on Sunday I set about integrating the running of Buster.JS tests
with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;zope.testrunner&lt;/span&gt;&lt;/code&gt; and to capture browser slaves using
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;selenium.webdriver&lt;/span&gt;&lt;/code&gt;.  I did this in a new package,
&lt;a class="reference external" href="https://github.com/plone/buster-selenium#buster-selenium"&gt;buster-selenium&lt;/a&gt;.  By Sunday night, I had it integrated with the
testrunner in &lt;a class="reference external" href="https://github.com/plone/buildout.deco"&gt;buildout.deco&lt;/a&gt; such that Buster.JS tests would be run
alongside the Python &lt;a class="reference external" href="http://docs.python.org/library/unittest.html"&gt;unittest&lt;/a&gt; tests.  By default it would use
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;selenium.webdriver&lt;/span&gt;&lt;/code&gt; to capture a Firefox slave and use it’s JS
engine to run the tests.  I also added a part to run Buster.JS unit
tests and coverage reports and &lt;a class="reference external" href="http://busterjs.org/docs/test/reporters"&gt;output XML&lt;/a&gt; that could be integrated
into our Jenkins CI.  Finally, I added support for capturing browser
slaves using &lt;a class="reference external" href="http://selenium-grid.seleniumhq.org/"&gt;Selenium Grid&lt;/a&gt;.  That was enough to &lt;a class="reference external" href="http://pypi.python.org/pypi/buster-selenium"&gt;release
buster-selenium&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is more that can be done:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;use &lt;a class="reference external" href="https://github.com/reebalazs/buster-qunit"&gt;buster-qunit&lt;/a&gt; run older QUnit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;better &lt;a class="reference external" href="http://docs.python.org/library/unittest.html"&gt;unittest&lt;/a&gt; integration, consturct one &lt;a class="reference external" href="http://docs.python.org/library/unittest.html#unittest.TestCase"&gt;unittest.TestCase&lt;/a&gt; for
each Buster.JS test case&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let me know if you think those would be valuable.  Hearing what the
interest is will make it more likely that I’ll get around to it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This was a really great sprint, we got a lot done and I feel like I
was able to make a worthy contribution.  I’m really glad that the
organizers are thinking seriously about doing this every year.&lt;/p&gt;
&lt;div class="note update admonition"&gt;
&lt;p class="admonition-title"&gt;Updated on 26 September 2012&lt;/p&gt;
&lt;p&gt;Imported from Plone on Mar 15, 2021.  The date for this update is the last
modified date in Plone.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
</content>
    <link href="https://www.rpatterson.net/blog/sea-sprint-2012-report-out/"/>
    <summary>A Python snob’s adventures in JS testing land.</summary>
    <category term="Buster.JS" label="Buster.JS"/>
    <category term="Deco" label="Deco"/>
    <category term="ECMAScript" label="ECMAScript"/>
    <category term="JavaScript" label="JavaScript"/>
    <category term="Plone" label="Plone"/>
    <category term="Python" label="Python"/>
    <category term="TDD" label="TDD"/>
    <category term="Testing" label="Testing"/>
    <category term="Toolbar" label="Toolbar"/>
    <category term="Zope" label="Zope"/>
    <category term="buildout" label="buildout"/>
    <published>2012-09-26T00:00:00+00:00</published>
  </entry>
</feed>
