<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Testing - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2011</copyright>
        <lastBuildDate>Mon, 27 Jun 2011 12:04:36 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Selenium Mojo : IDE versus RC</title>
            <description><![CDATA[Last April I attended the first annual Selenium conference in San Francisco. It was an awesome conference with a great line up speakers that included many of the original creators of the Selenium project! It was a neat opportunity to have a lot of perspective into the history of Selenium and what they want it to be in the future.<br /><br />One great talk I heard while I was there was by Jason Huggins the original creator of Selenium IDE. I had just had an email discussion with a person on another project in our company about whether or not they should standardize on Selenium IDE or Selenium RC and I was interested to hear what Jason had to say about the future of Selenium IDE.<br /><br />When asked whether or not one should use Selenium IDE over RC he replied with something to the effect of "choose Selenium RC hands down". He went on to say that there was even discussion among the project creators about whether or not to remove Selenium IDE from the project completely. <br /><br />Very intriguing coming from the creator of Selenium IDE himself! And I have to agree with him.<br /><i><br />Note: For those new to Selenium, Selenium IDE is a Firefox browser plugin that allows you to record a test script that includes actions (such as clicks or typing text into forms) and assertions (such as verifying text on a page) to be replayed it at a later date. Selenium RC on the other hand is an API with Java bindings (and several other languages as well). It allows you to start a browser from code and issues commands to it or make assertions from it via a Java program.<br /><br /></i>On the surface Selenium IDE is appealing. It is fast and easy to get started. Testers with no programming background can create test scripts with relative easy. In a short time you can have a suite of tests to show for your efforts.<br /><br />But unfortunately the returns are very short lived. The fundamental problems with Selenium IDE (which Jason pointed out in his talk) are the inherent brittleness of the scripts, the lack of variables, conditionals, or looping support, and the lack of ability to reuse portions of the scripts.<br /><br />(1) Selenium IDE scripts are brittle. As soon as the page layout changes, the scripts will break. The Selenium IDE plugin does its best to locate page elements using id values or xpath selectors, but if the structure of the page changes at all the tests break.<br /><br />Selenium RC is not immune to this problem, but since the programmer is writing the selector it is easier to use selectors that are more resilient to change. For example, instead of the Selenium IDE generating an xpath selector like "//div/span[3]/div[2]/span[4]/div[2]/a" which is bound to break as soon as the page structure changes, Selenium RC allows a programmer to write something like "$('foo').down('bar')" which is much more resilient. <br /><br />(2) Selenium IDE lacks the support that a programming language has for variables, conditionals and looping. Imagine you have a list on a page with a large number of items in it. You might want to assert that each expected item appears on the page. But SeleniumIDE has no capacity for repeating the same action over and over again unless you manually record that action multiple times you need. <br /><br />If you have an application where the appearance of the application can vary based on the environment it is deployed to then you would have to write one Selenium IDE script for each environment. You have no way of performing "if in this environment then check this condition" kind of logic.<br /><br />Other kinds of simple assertions are difficult. Imagine trying to assert that a timestamp is no less than a day old. In Selenium IDE you have no way of providing the logic to parse a timestamp and verify it falls within the expected range.<br /><br />Selenium RC is executing in the context of a full featured programming language. Loops, conditionals, and variables are all at the disposal of the test writer and can be used to make rich assertions about the state of the application without needing to create many scripts that are variations on the same thing. The power and expressiveness you have in Selenium RC lets you write tests in entirely different ways and much less tediously than recording long scripts over and over again.<br /><br />(3) Selenium IDE lacks the ability to reuse portions of your test. In most applications there are common steps (such as logging in or searching for an item) that are repeated in many different tests. In Selenium IDE you have to repeat all those steps for each test script you write.<br /><br />Selenium RC is again executing in the context of a programming language so common portions of the test can be refactored into methods that can be reused. This dramatically reduces maintenance effort because when an application changes the tests only need to be updated in one or two places instead of being recreated altogether.<br /><br /><br /><br />These three comparisons are really just part of the debate. There are other things that make Selenium RC attractive in the long run (including easy deployments, and the ability to interact with the application in more ways than just via a web browser). The debate boils down to the fact that while Selenium RC requires a higher learning curve and requires test writers to be programmers, the results are far less brittle, far more powerful, and dramatically easier to maintain than a massive collection of Selenium IDE scripts. <br /><br />In an organization where developers have the trust and respect of management and application testing is not strictly assigned to a test team, Selenium RC is the clear choice of technology.<br />]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_ide_versus_rc.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_ide_versus_rc.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
            <pubDate>Mon, 27 Jun 2011 12:04:36 -0500</pubDate>
        </item>
        
        <item>
            <title>Selenium Mojo : Taking screenshots</title>
            <description><![CDATA[In general Selenium and JUnit mix very well. One of the few areas where I have had problems getting them to play well with each other is when I wanted JUnit to notify Selenium when a test failed.<br /><br />JUnit has a couple mechanisms for catching test failures but all these methods fire after the test is torn down. Since I typically shutdown Selenium in the test tearDown() method (or its @After annotated equivalent) it is too late to ask Selenium to capture a screenshot. <br /><br />My solution has been to capture a screenshot after every test instead of just trying to do it on failures or errors. <br /><br />Initially I had trouble capturing the screenshots because there is also no easy way to get JUnit to tell you which test just completed. Naturally I wanted to name the screenshots after the tests. <br /><br />Thankfully in JUnit 4.7 a set of test "rules" were added (see the <a href="https://github.com/KentBeck/junit/raw/23ffc6baf5768057e366e183e53f4dfa86fbb005/doc/ReleaseNotes4.7.txt">release notes</a>) which included a mechanism for capturing the currently executing test name.<br /><br />The code for this is below. I recommend putting this code in a test base class that all your Selenium tests can inherit.<br /><br /><pre class="prettyprint"><br />@Rule<br />public TestName testName = new TestName()<br /><br />@After<br />public void tearDown() {<br />&nbsp;&nbsp;&nbsp; try {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selenium.windowFocus()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selenium.captureScreenshot("&lt;YOUR PATH&gt;\\${testName.getMethodName()}-${getClass().getSimpleName()}.png")<br /><div id=":9j">&nbsp;&nbsp;&nbsp;&nbsp;} catch (Exception e) {<br />        // Swallow the exception to prevent double error reporting in the JUnit report.<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; <br />    selenium.stop()<br />}<br /></div></pre><br /><br />Note: I find it helpful to print the method name first followed by the class because the JUnit report is displayed method name first making the screenshots easier to cross reference.<br /><br />Note: If you are running your tests on Windows and your workstation screen is locked you will get a black screen for a screenshot. I have searched long and hard and there appears to be no workaround for this on Windows. It is considered a security vulnerability. If you are running on Linux you can use virtual frame buffer to simulate a screen while running headless.<br /><br />]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_taking_screensho.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_taking_screensho.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Automated Testing</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Selenium</category>
            
            <pubDate>Mon, 06 Jun 2011 16:05:44 -0500</pubDate>
        </item>
        
        <item>
            <title>Selenium Mojo : A faster isVisible()</title>
            <description><![CDATA[Several months ago a coworker and I were working on converting manual test cases into Selenium RC tests. We were running Selenium RC on IE 7 with singleBrowserMode set to false. In that situation Selenium uses two browsers: one that executes the JavaScript of your test and one that browsed to the website under test. The former is the parent of the later, and makes calls into its DOM to perform the steps of the tests.<br /><br />As we were developing we started to realize that performance was degrading severely. Tests were hanging at certain steps for thirty to forty seconds. <br /><br />After some investigation my coworker determined that the main culprit was the isVisible() method in the Selenium RC API. It was taking upwards of 4 or 5 seconds <b>per execution</b>.<br /><br />Some online research yielded the root cause. Since Selenium is running the code of your test in a separate browser (presumably to avoid cross site scripting restrictions), each DOM operation is a round trip between the two windows. This is exceedingly slow if there is a lot of chatter between the windows.<br /><br />Implementing an isVisible() method is more difficult than it looks because there is not good browser support (especially in IE) for finding the "computed style" of an element (the style of the element and all nonoverlapping styles from its entire string of ancestors.) <br /><br />A quick peek into the Selenium source code showed that Selenium was using its bundled version of Prototype to traverse the DOM to find each parent of the element under consideration and examine their style attributes. All these round trips on a page with a huge DOM was causing the performance problem.<br /><br />We circumvented this by implementing our own isVisible() method in native JavaScript and injecting it into the page using Selenium's setExtensionJs() method: <br /><br />
<pre class="prettyprint"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; selenium.setExtensionJs('''<br />
<div id=":95">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; seleniumCustom = {};<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; seleniumCustom.isVisible = function(locator) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var visible = true;<br />
<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var element = selenium.browserbot.<wbr>findElementOrNull(locator);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (element == null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Check if this is a hidden input element<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (element.type &amp;&amp; element.type == "hidden") {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Check this element and all parents for hidden style<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (element != null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (element.currentStyle) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (element.currentStyle['<wbr>display'] == 'none' ||<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; element.currentStyle['<wbr>visibility'] == 'hidden') {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; visible = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; element = element.parentNode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return visible;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ''')<br /></div></pre>

<br /><i>Note: The above code is written in Groovy. Hence the multi line String.</i><br /><br /><i>Note: The setExtensionJs() method must be called before starting the selenium client.</i><br /><br /><i>Note: This version of isVisible() was written specifically for IE since that is all we are required to test against. A cross browser version would require more elaborate logic.</i><br /><br />We had already subclassed the DefaultSelenium object in our test suite to implement several bug fixes and add some extended functionality. It was simple to then overwrite the isVisible() method with the following:<br /><br /><pre class="prettyprint">/** Overwritten with an alternate implementation to improve performance. */<br />public boolean isVisible(String locator) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getEval("seleniumCustom.isVisible(${locator})").toBoolean()<br /><div id=":9h">}</div></pre><br />This improved performance by roughly a factor of ten and reduced the test suite's run time by 20 to 30 percent. <br /><br />This technique could be extended to other methods as well if you have a similar problem.<br /><br /><i><br /><br /><b>Acknowledgments:</b> Kudos to Jesse Lentz for his detective working in figuring out that isVisible() was the problem and suggesting a solution!</i><br />]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_a_faster_isvisib.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_a_faster_isvisib.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Selenium</category>
            
            <pubDate>Sat, 20 Nov 2010 11:56:15 -0500</pubDate>
        </item>
        
        <item>
            <title>Selenium Mojo : &quot;Access Is Denied&quot; </title>
            <description><![CDATA[<p>At work we maintain a suite of Selenium RC tests that numbers 150 strong. Before each of our releases we execute the entire suite multiple times in multiple environments against Internet Explorer (IE) 7 and 8.<br /><br />Selenium scales surprisingly well in most respects but one issue stymied our team early on.&nbsp; Right as the selenium client would start up and launch the browser it would hang on this popup:<br /><br /><br /><img alt="seleniumError.jpg" src="http://www.nearinfinity.com/blogs/seleniumError.jpg" class="mt-image-center" style="text-align: center; display: block; margin: 0pt auto 20px;" width="448" height="281" /><br /><br />Access is denied? Line 857? RemoteRunner.hta? Huh?<br /><br />As you probably know Selenium is unable to control a popup, like the one above, that originates from the browser. When you run selenium tests you often have to configure your browser to supress many different kinds of popups. Unfortunately IE offered no way to disable this particular type. <br /><br />This popup would happen perhaps 1 out of 100 test runs. It would interrupt the test run and force us to kill the selenium process which would lose the test results for that run. It originated in the selenium codebase so there was no way to trap the error. Eh gads... <br /><br />We run our tests with singleBrowserMode set to false (due to a bug with Selenium not handling cookies properly with HTTPS.) This causes selenium to launch two windows: a "master" window that runs the test code and a "slave" window that browses to your application. <br /><br />Long story short our team tracked this error down deep into the selenium JavaScript code base (htmlutils.js) to a function it calls to create the "slave" window:<br /><br /><br /></p><pre class="prettyprint">function openSeparateApplicationWindow(url, suppressMozillaWarning) {<br />&nbsp;&nbsp;&nbsp; // resize the Selenium window itself<br />&nbsp;&nbsp;&nbsp; window.resizeTo(1200, 500);<br />&nbsp;&nbsp;&nbsp; window.moveTo(window.screenX, 0);<br /><br />&nbsp;&nbsp;&nbsp; var appWindow = window.open(url + '?start=true', 'selenium<em>main</em>app_window');<br />&nbsp;&nbsp;&nbsp; if (appWindow == null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var errorMessage = "Couldn't open app window; is the pop-up blocker enabled?"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG.error(errorMessage);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Error("Couldn't open app window; is the pop-up blocker enabled?");<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; try {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var windowHeight = 500;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (window.outerHeight) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; windowHeight = window.outerHeight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (document.documentElement &amp;&amp; document.documentElement.offsetHeight) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; windowHeight = document.documentElement.offsetHeight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (window.screenLeft &amp;&amp; !window.screenX) window.screenX = window.screenLeft;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (window.screenTop &amp;&amp; !window.screenY) window.screenY = window.screenTop;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appWindow.resizeTo(1200, screen.availHeight - windowHeight - 60);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appWindow.moveTo(window.screenX, window.screenY + windowHeight + 25);<br />&nbsp;&nbsp;&nbsp; } catch (e) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG.error("Couldn't resize app window");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG.exception(e);<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />&nbsp;&nbsp;&nbsp; if (!suppressMozillaWarning &amp;&amp; window.document.readyState == null &amp;&amp; !seenReadyStateWarning) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("Beware!&nbsp; Mozilla bug 300992 means that we can't always reliably detect when a new page has loaded.&nbsp; Install the Selenium IDE extension or the readyState extension available from selenium.openqa.org to make page load detection more reliable.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; seenReadyStateWarning = true;<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; return appWindow;<br />}</pre><br /><br />Aha! Notice that when they try to resize and move the "appWindow" they put a try/catch block around the resizeTo and moveTo function calls. These methods can throw an access is denied error if the browser security settings are violated or <i>if the page is not fully loaded</i>. But in the first two lines where "window" is resized and moved there is no try/catch!<br /><br />The root cause was that there was a race condition in which the "master" window would not always be fully loaded before this code was executed.<br /><br />The fix I did was to unzip the selenium server jar file, add a try/catch around the first two lines of the method above, and then zip it up again. <br /><br />Hopefully the upcoming release of Selenium 2.0 will avoid this problem, but if you are running 1.0.1 or below this may be a useful workaround.<br /> 
]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_access_is_denied.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_access_is_denied.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Selenium</category>
            
            <pubDate>Fri, 12 Nov 2010 15:22:33 -0500</pubDate>
        </item>
        
        <item>
            <title>Missing the each_line method in FakeFS version 0.2.1? Add it!</title>
            <description><![CDATA[<p>Recently we have been using the excellent <a href="http://github.com/defunkt/fakefs">FakeFS</a> (fake filesystem) gem in some specs to test code that reads and writes files on the filesystem. We are using the latest <em>release</em> version of this gem which is 0.2.1 as I am writing this. Some of the code under test uses the <code>IO</code> <code>each_line</code> method to iterate lines in relatively largish files. But we found out quickly that is a problem, since in version 0.2.1 the <code>FakeFS::File</code> class does not extend <code>StringIO</code> and so you don't get all its methods such as <code>each_line</code>. (The <a href="http://github.com/defunkt/fakefs/blob/master/lib/fakefs/file.rb">version on master in GitHub</a> as I write this does extend <code>StringIO</code>, but it is not yet released as a formal version.)

As an example suppose we have the following code that prints out the size of each line in a file as stars (asterisks):

<pre class="prettyprint">
def lines_to_stars(file_path)
  File.open(file_path, 'r').each_line { |line| puts '*' * line.size }
end
</pre>

<p>Let's say we use FakeFS to create a fake file like this:</p>

<pre class="prettyprint">
require 'fakefs/safe'
require 'stringio'

FakeFS.activate!

File.open('/tmp/foo.txt', 'w') do |f|
  f.write "The quick brown fox jumped over the lazy dog\n"
  f.write "The quick red fox jumped over the sleepy cat\n"
  f.write "Jack be nimble, Jack be quick, Jack jumped over the candle stick\n"
  f.write "Twinkle, twinkle little star, how I wonder what you are\n"
  f.write "The End."
end
</pre>

<p>So far, so good. But now if we call <code>lines_to_stars</code> we get an error:</p>

<pre class="prettyprint">
NoMethodError: undefined method `each_line' for #&lt;FakeFS::File:0x000001012c22b8&gt;
</pre>

<p>Oops. No <code>each_line</code>. If you don't want to use an unreleased version of the gem, you can add <code>each_line</code> onto FakeFS::File using the following code:</p>

<pre class="prettyprint">
module FakeFS
  class File
    def each_line
      File.readlines(self.path).each { |line| yield line }
    end
  end
end
</pre>

<p>Basically all it does is define <code>each_line</code> so that it reads all the lines from a (fake) file on the (fake) filesystem and then yields them up one by one, so you can have code under test that iterates a file and work as expected. So now calling <code>lines_to_stars</code> gives a nice pretty bar chart containing the line sizes represented by stars:</p>

<pre class="prettyprint">
********************************************
********************************************
***************************************************************
*******************************************************
********
</pre>

<p>Since we're using RSpec, to make this work nicely we added the above code that defines <code>each_line</code> into a file named <code>fakefs.rb</code> in the <code>spec/support</code> directory, since <code>spec_helper</code> requires supporting files in the <code>spec/support</code> directory and its subdirectories. So now all our specs automatically get the <code>each_line</code> behavior when using FakeFS.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/missing_the_each_line_method_i.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/missing_the_each_line_method_i.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Ruby</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">FakeFS</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">RSpec</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ruby</category>
            
            <pubDate>Thu, 06 May 2010 22:22:38 -0500</pubDate>
        </item>
        
        <item>
            <title>Selenium Mojo : Protoype Bindings in Selenium</title>
            <description><![CDATA[<font style="font-size: 1.25em;"><b>Introduction</b></font><br /><br />On my current project we have been involved in converting some of the hundreds of manual tests that are run by our Test Team every release into a suite of automated Selenium RC tests.<br /><br />During the course of this adventure my crew found several instances where XPath and native JavaScript were not sufficiently expressive to find elements in some of our more complicated interfaces. <br /><br />Since our web app uses the Prototype/Scriptaculous JavaScript framework we wanted to find a way to make the locating power of Prototype available within Selenium RC.<br /><br />We developed approaches for both Selenium 0.9.2 and Selenium 1.0.3 (which had better programmatic support for adding JavaScript user extensions to Selenium).<br /><br /><br /><font style="font-size: 1.25em;"><b>Selenium 0.9.2</b></font><br /><br />Selenium RC provides the capability to add "user extensions" to augment its JavaScript core. <br /><br />See <a href="http://seleniumhq.org/docs/08_user_extensions.html">http://seleniumhq.org/docs/08_user_extensions.html</a> for detailed information on how to set this up. <br /><br />We wrote the following user-extension.js file:<br /><br /><pre class="prettyprint">Selenium.prototype.setupProtoypeJS = function() {<br />&nbsp;&nbsp;&nbsp; id = selenium.browserbot.getCurrentWindow().$;<br />&nbsp;&nbsp;&nbsp; css = selenium.browserbot.getCurrentWindow().$$;<br />}</pre><br />In our code we have a base class for all our test cases. To this we added our own waitForPage() method:<br /><br /><pre class="prettyprint">public void waitForPage() {<br />&nbsp;&nbsp;&nbsp; selenium.waitForPage('60000')<br />&nbsp;&nbsp;&nbsp; proc.doCommand('setupPrototypeJS', [])<br />}</pre><br />Thus every time the page reloads (which clears the JavaScript context) we call waitForPage() and this command is re-executed. It creates two global variables (id and css) and binds them to Prototype's $ and $$ functions respectively.<br /><br /><i>Note: The reason we choose id and css instead of $ and $$ was that Groovy considers $ in Strings to be a special character and we would have had to escape it each time it was used</i>.<br /><br />The Prototype selectors can now be used in Selenium RC like this:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><i>Note: You still have to specify the dom locator type so Selenium RC will know to execute your locator string as JavaScript.&nbsp; <br /></i><br /><br /><font style="font-size: 1.25em;"><b>Selenium 1.0.3</b></font><br /><br />In more recent version of Selenium RC the project added the setExtensionJs() method. This allows you to set extension JavaScript programmatically prior to starting the selenium client:<br /><br /><pre class="prettyprint">selenium = new DefaultSelenium(...)<br />selenium.setExtensionJs('...')<br />selenium.start()</pre><br />This made it much easier to implement our Prototype bindings. The only trick was that the JavaScript seems to be executed prior to having access to a page context and is also only executed once. This required us to take a different approach.<br /><br />We created id and css as global functions instead of variables. This allowed us to defer accessing the current window until the functions were actually invoked. &nbsp; <br /><br /><pre class="prettyprint">selenium.setExtensionJs('''<br />        id = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    return selenium.browserbot.getCurrentWindow().$(value);<br /><div id=":w0" class="ii gt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; css = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return selenium.browserbot.<wbr>getCurrentWindow().$$(value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />''');</div></pre> <br /><i>Note: The above code snippet is written in Groovy which allows multiline Strings.<br /></i><br />The Prototype selectors are used in Selenium RC like before:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><br /><br />I would be interested in hearing feedback from anyone who has a chance to use this technique!<br />]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_protoype_binding.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_protoype_binding.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
            <pubDate>Sat, 24 Apr 2010 14:00:36 -0500</pubDate>
        </item>
        
        <item>
            <title>Hanging out with industry leaders...</title>
            <description><![CDATA[Thanks to Near Infinity's generous training budget, I had the opportunity last week to spend 3 days with several members of the&nbsp;<a href="http://www.objectmentor.com/">Object Mentors</a>&nbsp;group. These guys have an enormous amount of experience, especially&nbsp;<a href="http://www.objectmentor.com/omTeam/martin_r.html">"Uncle" Bob Martin</a>. So I thought I would share a few of the pearls of wisdom they dropped along the way:<div><br /><div><ul><li>"Programming is a social exercise" - I thought this was a really good point. It was mentioned in the context of pair-programming, but I think it has far-reaching implications. Software development is more than just running through a bunch of formulas and crunching out an answer. Interaction within the team and with domain experts is crucial, to not only build the software right, but build the right software.</li><li>"A refactoring is something that takes a few seconds, or a few minutes at most" - I was really impressed with the importance of automated refactorings in his discussions. I think most of the time that I spend "refactoring" is in small, manual edits, whereas most of the time that he spends is in using automated refactoring to "chunk" his edits. I definitely need to learn these keystrokes and refactorings better. Maybe I should start a "Refactoring Driven Development" movement...</li><li>"Don't put refactoring on the schedule; do it all the time" - Simple, but effective. My tendency is to want to spend all my time refactoring, but this curbs that, because it forces me to refactor while I'm delivering user stories.&nbsp;</li><li>"There are 3 essential design skills: nose, vision, and plan" - A nose for recognizing design smells, a vision for seeing a good design for your codebase, and an ability to come up with a plan to get from point A to point B.&nbsp;</li><li>"Testing trumps good design" - This bothered me at first, but I think it's a really good point. The idea &nbsp;here is not to say that design is not important. But, rather, if you are forced to choose between between a "bad" design that allows better test coverage (e.g., less encapsulation), and "good" design which is hard to test, choose testability. The reason here is that the biggest roadblock to changing your codebase is not bad design, but FEAR of breaking something. If you know you will know when you've broken something, then you can retrofit a better design later.</li><li>"There is self-worth tied up in "finishing" something" - He also drew a distinction between having something working (which some developers will call "finishing" it), and finishing it - making it not only work, but be thoroughly tested, maintainable, etc.</li><li>Presentation layer - he talked about having the thinnest possible UI layer, which talks to a presentation layer to find out everything about how it should render. Then test the UI and business logic completely separately</li><li>"You aren't doing agile development unless you are tracking your velocity and remaining story points in terms of passing, automated acceptance tests" - I balked at this at first, feeling like it was too easy to use this as a performance to beat the team over the head with. After I thought about it, though, it's really about the definition of done. We are done if all the features we said would be working are working. And how can we know this? Only by testing them. Continuously. Which means it should be automated.</li><li>Acceptance tests don't need to be end-to-end, and, in fact, shouldn't be. This is another one that made me hesitate. After all, how do you know the feature is really working unless you go all the way from the UI to the database and back? Well, in short, because you're the developer. There's more value in being able to test features fast, constantly, than in being able to truly test them all the way from one end to the other. Mock/stub out what you need to to make that happen.</li><li>FitNesse is cool. This is the second time I've played around with that tool, and the second time I've been impressed with its power and simplicity. I definitely need to play around with it some more.</li></ul></div></div>]]></description>
            <link>http://www.nearinfinity.com/blogs/andrew_wagner/hanging_out_with_industry_lead.html</link>
            <guid>http://www.nearinfinity.com/blogs/andrew_wagner/hanging_out_with_industry_lead.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Agile Development</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
            <pubDate>Fri, 26 Feb 2010 09:50:17 -0500</pubDate>
        </item>
        
        <item>
            <title>Making Cobertura Reports Show Groovy Code with Maven</title>
            <description><![CDATA[ <p>A recent project started out life as an all-Java project that used Maven as the build tool. Initially we used <a href="http://www.atlassian.com/software/clover/">Atlassian Clover</a> to measure unit test coverage. Clover is a great product for Java code, but unfortunately it only works with Java code because it works at the Java source level. (This was the case as of Spring 2009, and I haven't checked since then.) As we started migrating existing code from Java to Groovy and writing new code in Groovy, we started to lose data about unit test coverage because Clover does not understand Groovy code. To remedy this problem we switched from Clover to <a href="http://cobertura.sourceforge.net/">Cobertura</a>, which instruments at the bytecode level and thus works with Groovy code. Theoretically it would also work with any JVM-based language but I'm not sure whether or not it could handle something like Clojure or not.</p>

<p>In any case, we only cared about Groovy so Cobertura was a good choice. With the <a href="http://mojo.codehaus.org/cobertura-maven-plugin/">Cobertura Maven</a> plugin we quickly found a problem, which was that even though the code coverage was running, the reports only showed coverage for Java code, not Groovy. This blog shows you how to display coverage on Groovy code  when using Maven and the Cobertura plugin. In other words, I'll show how to get Cobertura reports to link to the real Groovy source code in Maven, so you can navigate Cobertura reports as you normally would.</p>

<p>The core problem is pretty simple, though it took me a while to figure out how to fix it. Seems to be pretty standard in Maven: I know what I want to do, but finding out how to do it is the <i>really</i> hard part. The only thing you need to do is tell Maven about the Groovy source code and where it lives. The way I did this is to use the Codehaus <a href="http://mojo.codehaus.org/build-helper-maven-plugin/">build-helper-maven-plugin</a> which has an add-source goal. The add-source goal does just what you would expect; it adds a specified directory (or directories) as a source directory in your Maven build. Here's how you use it in your Maven pom.xml file:</p>

<pre class="prettyprint">
&lt;plugin&gt;
    &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
    &lt;artifactId&gt;build-helper-maven-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;phase&gt;generate-sources&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;add-source&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;sources&gt;
                    &lt;source&gt;src/main/groovy&lt;/source&gt;
                &lt;/sources&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;
</pre>

<p>In the above code snippet, we're  using the "build-helper-maven-plugin" to add the src/main/groovy directory. That's pretty much it. Run Cobertura as normal, view the reports, and you should now see coverage on Groovy source code as well as Java.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/making_cobertura_reports_show.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/making_cobertura_reports_show.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">cobertura</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">maven</category>
            
            <pubDate>Tue, 15 Dec 2009 23:33:19 -0500</pubDate>
        </item>
        
        <item>
            <title>Finding Holes in Rcov and JRuby</title>
            <description><![CDATA[<h2>"We're missing some coverage..."</h2>

<p>While creating coverage reports for a fairly new JRuby on Rails project, we noticed that our coverage numbers weren't <em>quite</em> right: certain classes were missing from the coverage reports. Rcov doesn't know about classes unless they are required: not a problem for models, but we were missing tests for some controllers and libraries.</p>

<p>Oops.</p>

<p>To properly correct this problem, I wrote the <code>coverage_helper</code> (to live alongside the <code>test_helper</code>).  Basically, this causes all of the classes to be required so that rcov knows about them.</p>

<h4>test\coverage_helper.rb</h4>

<pre><code>require 'test/unit'
require 'test_helper'

class CoverageHelper &lt; Test::Unit::TestCase
  def test_coverage
    ['app', 'lib'].each {|path| Dir.glob("#{path}/**/*.rb") {|file| 
      require File.expand_path(file.chomp('.rb'))
    }}
    assert true
  end
end
</code></pre>

<p>Simply include this test in your rcov builds and the problem is solved.  </p>

<p>Because of how rcov counts lines and the way Ruby class loading works, you'll never see files with 0% coverage.  However, at least you <em>will</em> see all of your classes listed and those that aren't covered will have a low percentage.</p>

<h4>Is this really necessary?</h4>

<p>First, the <code>File.expand_path</code> makes sure that your files are only required once.  I hate random warning messages because constants are initialized twice (among other issues).</p>

<p>Second, no, I didn't need to make this a test, but it just seemed nicer to.  I added the  <code>assert true</code> simply because I didn't feel right about not asserting <em>something</em> in the test.  </p>

<p>Third, as long as one uses the Rails scripts to generate the skeletons for your code, this scenario <em>should</em> never happen (because Rails will create all of the appropriate tests).  However, there is the tendency not to use the generated scripts when they don't output what you want, which is what we have discovered (Rails and Legacy Database Schemas aren't a perfect fit).  Also, sometimes I just forget to use them.</p>

<h2>What if you can't run rcov?</h2>

<p>One minor glitch of running JRuby on Windows is that the <code>File.separator</code> is technically incorrect (it's '<code>/</code>' instead of '<code>\</code>').  This usually isn't an issue... except when using rcov.  Since rcov executes from the shell, the arguments requiring file names and/or directories won't work because the separator is the wrong direction from what Windows is expecting.</p>

<p>The fix is to add a couple of methods to the File class to address the problem.</p>

<h4>Windows Separator Fix</h4>

<pre><code>class File
  @@is_windows = ENV['OS'] &amp;&amp; 
    (not ENV['OS'].downcase.match(/^windows/).nil?)

  def self.fix_name(name)
    @@is_windows ? name.tr(File::SEPARATOR, File::ALT_SEPARATOR) : name
  end

  def self.fixed_join(*files)
    self.fix_name(self.join files)
  end
end
</code></pre>

<p>The reason to do the <code>ENV['OS']</code> truth check first is that in JRuby on Solaris (where our CI is), that property doesn't exist. We couldn't use the <code>RUBY_PLATFORM</code> variable either, as in JRuby it's always assigned to '<code>java</code>'.</p>

<p>I should note that I've only use these fixed separator methods when necessary (in my rcov rake task).  The 'normal' separator has worked in every other situation I've run into.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/brian_montgomery/finding_holes_in_rcov_and_jrub.html</link>
            <guid>http://www.nearinfinity.com/blogs/brian_montgomery/finding_holes_in_rcov_and_jrub.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">JRuby</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Ruby</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
            <pubDate>Tue, 27 Jan 2009 17:40:42 -0500</pubDate>
        </item>
        
        <item>
            <title>Unit Testing Google App Engine Applications</title>
            <description><![CDATA[<p>I have been working on an application to be hosted by <a href="http://code.google.com/appengine/">Google App Engine</a> (GAE).  Initially it was just an experiment, so I didn't think about automated testing.  As it morphed into a real application, I suddenly had the urge to write tests.  A quick look at the GAE documentation did not reveal a built-in testing framework.  I know about the Python unittest and doctest modules, and writing unit tests for self-contained classes is easy enough.  But I really needed integration tests, too, where I can test all of the application code as if it were deployed to GAE.  For those to work, I would have to somehow set up the testing environment to either simulate GAE or bootstrap it just enough for my entity and handler classes to operate within the GAE sandbox enforced by the <a href="http://code.google.com/appengine/docs/gettingstarted/devenvironment.html">SDK</a> and the production environment.</p>

<p>I figured that somebody must have solved this problem already, so a Google search resulted in two interesting solutions.  The <a href="http://blog.appenginefan.com/2008/06/unit-tests-for-google-app-engine-apps.html">first approach</a> involves mocking most GAE objects using a record-and-playback-style library called <a href="http://labix.org/mocker">Mocker</a> (similar to <a href="http://www.easymock.org/">EasyMock</a> for Java).  The <a href="http://appengineguy.com/2008/06/proper-unit-testing-of-app-enginedjango.html">second approach</a> bootstraps the entire GAE SDK so the tests can be run from the command-line.</p>

<p>After examining these approaches, I was still unsatisfied.  The first approach, mocking, is a sensible ways of testing in other platforms like Java, where we strive to avoid direct dependencies on the application server or database by introducing layers of abstraction that need to be mocked in tests.  The second approach, bootstrapping, is a viable solution for some platforms (Rails, Grails).  But for GAE, these approaches seem cumbersome to me.  I want to run my tests in the real environment and not have to maintain many lines of mocking code, or bootstrap code that depends on Google's internal SDK implementation.  Call me lazy, but I want writing tests for my GAE application to be as painless as possible so I can focus on writing the application and testing real functionality.</p>

<p>Then it occurred to me: how about testing from within the GAE environment instead of trying to drive the tests externally?  There is no reason to make the job harder when the GAE platform is so well-defined.  The SDK exactly simulates the production environment, and it recompiles code changes immediately without needing a server restart.  Testing for GAE becomes a no-brainer because the tests can simply be invoked by an HTTP request just like any other function of the GAE application.</p>

<p>First a URL must be mapped to a handler script in the <a href="http://code.google.com/appengine/docs/configuringanapp.html"><code>app.yml</code></a> configuration file, where all of the application's handler are defined:</p>

<pre class="prettyprint"># This should only work for testing through the SDK.
- url: /test/?
  script: gaetest/handler.py
</pre>

<p>Adding this mapping should make many developers justifiably squeamish.  After all, this will also be mapped in the production environment where users could invoke the tests, which could be very nasty.  The test script will have to self-destruct in production - more on that later.</p>

<p>When I launch the GAE SDK server and visit <code>http://localhost:8080/test</code> in my browser, I want all of my tests to run, with the results displayed in the browser window (nothing fancy, text will do).  Here's the <code>handler.py</code> script, which is located in the <code>gaetest</code> directory under the application root:</p>

<pre class="prettyprint">import google.appengine.tools # causes an exception in production, as desired
import unittest
import sys
import wsgiref.handlers
from google.appengine.ext import webapp
from tests import * # this requires a tests/__init__.py to define the test modules

class TestSuiteHandler(webapp.RequestHandler):

  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write("=======\n Tests \n=======\n\n")
    modules = [sys.modules['tests.%s' % m] for m in dir(sys.modules['tests']) if m.endswith('_test')]
    loader = unittest.TestLoader()
    suite = unittest.TestSuite()
    for module in modules:
      suite.addTest(loader.loadTestsFromModule(module))
    runner = unittest.TextTestRunner(self.response.out)
    runner.run(suite)

def main():
  application = webapp.WSGIApplication([('/test/?', TestSuiteHandler)], debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()
</pre>

<p>The handler looks for all modules in the <code>tests</code> package, which is a subdirectory under the application root.  Modules must be explicitly defined in <code>tests/__init__.py</code> as such:</p>

<pre class="prettyprint"># List all modules here.
__all__ = ['model_test', 'another_test', 'no_tests_just_helpers']
</pre>

<p>Then the handler loads all test classes (subclasses of <code>unittest.TestCase</code>) from modules that end in <code>_test</code>, and adds them to the test suite.  The tests are executed using the standard text-based test runner, and the output is rendered in the browser.</p>

<p>Notice that the first line of <code>handler.py</code> attempts to import <code>google.appengine.tools</code>.  I chose this package because I'm fairly certain that it will not be available in production, and will therefore raise an exception if the handler is executed in that environment.</p>

<p>At this point, tests will run just fine in the environment provided by the GAE SDK server.  Here's an example test class:</p>

<pre class="prettyprint">import unittest
from google.appengine.ext import db

class MyEntity(db.Model):
  name = db.StringProperty()

class MyEntityTest(unittest.TestCase):

  def test_new_entity(self):
    entity = MyEntity(name='Foo')
    self.assertEqual('Foo', entity.name)

  def test_saved_enitity(self):
    entity = MyEntity(name='Foo')
    key = entity.put()
    self.assertEqual('Foo', db.get(key).name)
</pre>

<p>Can you spot the trouble with this test?  If it I run the test over and over again as I actively develop and manually test the application, without restarting the server, then many <code>MyEntity</code> instances will pile up in my local datastore, which is a file-based stub used by the GAE SDK to simulate the production datastore.  For this trivial example, that would simply be annoying.  But in a complex suite of tests, it is undesirable to leave persistent objects in the datastore between runs.  It is also nice to have a separate test datastore so development data doesn't get in the way of asserting on objects stored by the tests.  In other platforms, such as Ruby on Rails, not only do the tests get their own datastore, but the data is rolled back after each test by running them in a transaction.</p>

<p>The GAE datastore supports very limited transactions.  Unfortunately the <a href="http://code.google.com/appengine/docs/datastore/transactions.html#What_Can_Be_Done_In_a_Transaction">restrictions</a> prevent them from being used to roll back all entities created by a test.</p>

<p>Let's revisit the <a href="http://appengineguy.com/2008/06/proper-unit-testing-of-app-enginedjango.html">second approach</a> that I had found to testing in GAE.  It turns out that this example, which I had previously dismissed, contains the solution to the above problem.  The SDK contains a number of "stub" service classes for API modules such as the datastore, users, urlfetch, and mail.  The example recreates the SDK environment by registering these stubs through an API proxy class, which is used by the rest of the SDK code to lookup these services when needed.  The datastore stub can be re-instantiated cleanly using the internal API, and the original datastore can be recovered so development entities are not lost.  Since I run the tests from within the SDK server, the rest of the service stubs do not need to be replaced.  Despite my misgivings about depending on the internal SDK implementation, the ability to reset the datastore state between tests is just too important to ignore.  </p>

<p>In order to achieve this, I need to create a special base <code>TestCase</code> that installs the test datastore in <code>setUp()</code> and recovers the development datastore in <code>tearDown()</code>.  All test classes that create entities, or that test code that creates entities, will need to inherit from the <code>AppEngineTestCase</code>, located in <code>gaetest\base.py</code>:</p>

<pre class="prettyprint">import unittest
from google.appengine.api import apiproxy_stub_map  
from google.appengine.api import datastore_file_stub

class AppEngineTestCase(unittest.TestCase):

  def setUp(self):
    # Preserve the current apiproxy for tearDown().
    self.original_apiproxy = apiproxy_stub_map.apiproxy

    # Create a new apiproxy and temporary datastore that will be used for this test.
    apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap() 
    temp_stub = datastore_file_stub.DatastoreFileStub('AppEngineTestCaseDataStore', None, None)  
    apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', temp_stub)

    # For convenience, the subclass can implement 'set_up' rather than overriding setUp()
    # and calling this base method.
    if hasattr(self, 'set_up'):
      self.set_up()

  def tearDown(self):
    # The subclass can optionally choose to implement 'tear_down'.
    if hasattr(self, 'tear_down'):
      self.tear_down()

    # Restore stubs for development.
    apiproxy_stub_map.apiproxy = self.original_apiproxy
</pre>

<p>The sample unit test class now extends the new base:</p>

<pre class="prettyprint">  import unittest
  from google.appengine.ext import db
  import gaetest.base

  from google.appengine.ext import db

  class MyEntity(db.Model):
    name = db.StringProperty()

  class MyEntityTest(gaetest.base.AppEngineTestCase):

    def set_up(self):
      # Populate test entities here along with other setup.
      entity = MyEntity(name='Bar')
      self.setup_key = entity.put()

    def tear_down(self):
      # Tear down here, but there is no need to delete test entities.
      pass

    def test_new_entity(self):
      entity = MyEntity(name='Foo')
      self.assertEqual('Foo', entity.name)

    def test_saved_enitity(self):
      entity = MyEntity(name='Foo')
      key = entity.put()
      self.assertEqual('Foo', db.get(key).name)

    def test_setup_entity(self):
      entity = db.get(self.setup_key)
      self.assertEqual('Bar', entity.name)
</pre>

<p>When the above test is run, two entities are created (with names 'Foo' from <code>test_saved_enitity()</code> and 'Bar' from <code>test_setup_entity()</code>), but will not be present in the development datastore.</p>

<p>That's all for now.  Feel free to <a href="http://www.nearinfinity.com/blogs/resources/sfarley/gae-testing.zip">download</a> the example, packaged as a GAE application.  Enjoy writing tests for Google App Engine!</p>

<p><em>Note: In the midst of writing this blog, I discovered that a very similar library, called <a href="http://code.google.com/p/gaeunit/">GAEUnit</a>, was recently added to Google Code.  Check it out.</em></p>

<p><em><strong>UPDATE:</strong> My above efforts will soon be incorporated into <a href="http://code.google.com/p/gaeunit/">GAEUnit</a>.  The original GAEUnit author, George Lei, and I are now partnering to make it the testing framework of choice for Google App Engine developers.</em></p>]]></description>
            <link>http://www.nearinfinity.com/blogs/steven_farley/unit_testing_google_app_engine.html</link>
            <guid>http://www.nearinfinity.com/blogs/steven_farley/unit_testing_google_app_engine.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">google-app-engine</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">python</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Tue, 29 Jul 2008 23:50:56 -0500</pubDate>
        </item>
        
        <item>
            <title>Verify EasyMock Behavior When Expecting Exceptions</title>
            <description><![CDATA[<p>Often when writing unit tests I use <a href="http://www.easymock.org/">EasyMock</a> to mock dependencies of the class under test. And many times I need to test that a certain type of exception is thrown during a test. Sometimes I need both, for example I am using a mock to simulate a dependency that throws an exception <i>and</i> I want my test to verify the appropriate exception was indeed thrown and that the mock was called properly. In those cases, I use a simple little trick: use a try/finally block along with a <a href="http://www.junit.org/">JUnit</a> "<code>@Test(expected = FooException.class</code>" annotation on my test method. Voila! Now you can verify mock behavior and verify the exception was thrown at the same time. This is cleaner than using a catch block and asserting the correct exception was thrown, since you rely on JUnit to verify the exception using the "expected" attribute of the @Test annotation. For example:</p>

<pre class="prettyprint">@Test(expected = ThrottleException.class)
public void testSomethingWithDependencies() {
    // Create mock
    Rocket mainBooster = createMock(Rocket.class);
	
    // Record behavior
    mainBooster.ignite();
    
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class);
    
    // Replay mock
    replay(rocket);
    
    // Create object with dependency on mainBooster
    SpaceShuttle shuttle = new SpaceShuttle(rocket);    
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    try {
        shuttle.blastOff();
    }
    finally {
        verify(rocket);
    }
}
</pre>

<p>If instead of writing tests in Java you write them in <a href="http://groovy.codehaus.org/">Groovy</a>, the above code could be a little bit Groovier, though not much. (In an earlier <a href="http://www.sleberknight.com/blog/sleberkn/entry/20080321">post</a> I showed how you can write unit tests in Groovy and still use JUnit instead of <code>GroovyTestCase</code> if you like.)</p>

<pre class="prettyprint">@Test(expected = ThrottleException)
void testSomethingWithDependencies() {
    // Create mock
    def mainBooster = createMock(Rocket)
    
    // Record behavior
    mainBooster.ignite()
    
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class)
    
    // Replay mock
    replay rocket
    
    // Create object with dependency on mainBooster
    def shuttle = new SpaceShuttle(rocket)
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    try {
        shuttle.blastOff()
    }
    finally {
        verify rocket
    }
}
</pre>

<p>Even more Groovy in this case would be to extend <code>GroovyTestCase</code> and use its <code>shouldFail</code> method, like so:</p>

<pre class="prettyprint">void testSomethingWithDependencies() {
    // Create mock
    def mainBooster = createMock(Rocket)
	
    // Record behavior
    mainBooster.ignite()
	
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class)
    
    // Replay mock
    replay rocket
    
    // Create object with dependency on mainBooster
    def shuttle = new SpaceShuttle(rocket)
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    shouldFail(ThrottleException) {
        shuttle.blastOff()
    }
    verify rocket
}
</pre>

<p>The <code>GroovyTestCase</code> version is probably the cleanest of the above three options. If you're not into Groovy, you can still use the JUnit  "<code>@Test(expected = BarException.class)</code>" together with a try/finally/verify in plain Java unit tests for a cleaner test experience.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/verify_easymock_behavior_when_expecting.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/verify_easymock_behavior_when_expecting.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">easymock</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Tue, 13 May 2008 14:51:08 -0500</pubDate>
        </item>
        
        <item>
            <title>JUnit4 Tests in Groovy</title>
            <description><![CDATA[<p>On my current (Java-based) project we now write all new unit tests in Groovy, though there are a lot of legacy Java tests still out there that we haven't had time or felt the need to convert to Groovy-based tests. There are also several base test classes, also written in Java, that provide some nice set up and tear down code for certain classes of test. I happened to be testing a web controller and realized I needed (or rather, wanted) to make use of the existing <code>AbstractViewControllerTest</code> base class, which is written in Java, uses JUnit4 annotations, and provides, among other things, code that creates and sets up a simulated authenticated user for the controller along with a bunch of other stuff like mock requests, responses, session, helper methods, etc. So, the problem was that I needed to extend <code>AbstractViewControllerTest</code> and not <code>GroovyTestCase</code>, and initially got all bent out of shape about having to choose to write the test in Java and extend the base test or write it in Groovy extending <code>GroovyTestCase</code> and having to redo the stuff already provided by the base class.</p>

<p>Thankfully about that time <a href="http://www.nearinfinity.com/blogs/page/sfarley">Steve</a> reminded me nicely that you can mix-and-match Groovy and JUnit4 annotations just fine since Groovy has now sported annotation support for a while now (since ~1.1 I think). So I can simply write the test in Groovy, extend the base test class, and use JUnit4 annotations to get exactly what I want. What's the point? Just remember that when writing tests in Groovy there is nothing that says you <i>must</i> extend <code>GroovyTestCase</code> and that you can use JUnit4 in Groovy tests. So for example you could have a Groovy test like this:</p>

<pre class="prettyprint">class MyTest extends TestBaseClass {
    @Before
    void doSetup() { ... }
	
    @Test
    void testSomething() { ... }
	
    @Test(expected = IllegalArgumentException)
    void testBadThing() { ... }
}
</pre>

<p>This way you can extend some other class if you choose, and get all the normal JUnit4 stuff. Since you are not extending <code>GroovyTestCase</code> one thing that is missing is <code>shouldFail()</code> so instead you use the "expected" parameter in your <code>@Test</code> annotation when you want to verify a specific type of exception was thrown.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/junit4_tests_in_groovy.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/junit4_tests_in_groovy.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">junit</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Fri, 21 Mar 2008 09:03:10 -0500</pubDate>
        </item>
        
        <item>
            <title>Testing JavaScript Objects with Function.prototype.call</title>
            <description><![CDATA[<p>This is a short tip that I found useful for testing complex JavaScript objects using <a href="http://www.thefrontside.net/crosscheck">crosscheck</a>. For more information on crosscheck see my article on <a href="/blogs/page/jharwig?entry=javascript_unit_testing">JavaScript Unit Testing with Crosscheck</a>. </p>

<p>Testing instance methods can be a pain if the functions use instance variables and the object is heavyweight. In my case the constructor did a lot with the DOM that I didn't want to mock. Instead of invoking the function through an instance of an object, I called it statically. </p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jason_harwig/testing_custom_javascript_libraries_with.html</link>
            <guid>http://www.nearinfinity.com/blogs/jason_harwig/testing_custom_javascript_libraries_with.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
            <pubDate>Thu, 11 Oct 2007 18:33:31 -0500</pubDate>
        </item>
        
        <item>
            <title>JavaScript Unit Testing with Crosscheck</title>
            <description><![CDATA[<p>Here we are, a couple years since Ajax was coined, JavaScript has become a language that people actually respect. The code being written now is better than ever before. Object-orientation, name-spacing, object detection, and correct scoping are prevalent now. The libraries available (prototype, jquery, yui, dojo) are very well written. What is the next step to improve code quality? If you want my opinion, it's Testing. Otherwise, <a href="http://www.digg.com">here's</a> the door. :) </p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jason_harwig/javascript_unit_testing.html</link>
            <guid>http://www.nearinfinity.com/blogs/jason_harwig/javascript_unit_testing.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
            <pubDate>Mon, 08 Oct 2007 15:08:12 -0500</pubDate>
        </item>
        
        <item>
            <title>Do You Unit Test Getters and Setters?</title>
            <description><![CDATA[<p>Since Java has no notion native syntax for declaring properties you have to write explicit getter and setter methods, or hopefully you never write them but rather you have your IDE generate them. The question is whether you should write explicit tests for these methods or not. If you measure your unit test coverage, getters and setters are normally tested during the course of all your other tests, for example if you use an ORM tool like Hibernate it will call the setters when populating objects and the getters when reading object state to persist changes. But most people don't assert every single property in the course of testing their data access tier, so the actual behavior many times is not actually being tested.</p>

<p>Since getters and setters are explicit code in your application, I think they should be tested. But no way am I going to write individual tests for every single getter and setter method. So the other day I wrote a test utility that uses reflection to test that values passed to the setter methods are the values returned by the corresponding getters. Some people think this is cheating or just playing around with test coverage numbers. :-) Tools like <a href="http://findbugs.sourceforge.net/">Findbugs</a> consider this to be a code smell since the getter may be returning a reference to a mutable object, as does Josh Bloch in <a href="http://java.sun.com/docs/books/effective/">Effective Java</a>. While true to an extent, I want to know how many Java developers really create defensive copies in getter and/or setter methods. Not many I bet. As a matter of practicality, it just doesn't matter most of the time. I've never once had a problem where a <code>Date</code>, which is a mutable object, returned by a getter was changed and caused weird issues.</p>

<p>Most Java developers know that objects returned by getters are meant for reading, and if you want to change the value, explicitly call the setter. There are exceptions of course: if a collection or map or array is returned sometimes you are expected (or required) to actually manipulate the returned mutable collection object. One of those cases is when using Hibernate as I described in an earlier <a href="http://www.nearinfinity.com/blogs/page/sleberkn?entry=let_s_play_who_owns">post</a>. In any case I think that since it is <i>possible</i> someone could manually mess up a getter or setter, they should be tested. In languages that provide explicit support for properties this is a joke, but this is Java, let's just get over that and just test it. (As the mantra goes, "test everything that could possibly break.")</p>

<p>Ok, some code. The following is all we have to do to test basic getter/setter behavior of an object:</p>

<pre class="prettyprint">@Test
public void testProperties() {
    assertBasicGetterSetterBehavior(new MyBean());
}
</pre>

<p>This tests all the getter/setter pairs in the <code>MyBean</code> class. The <code>assertBasicGetterSetterBehavior</code> is statically imported from a class we created named <code>PropertyAsserter</code>, so we can just call it. This is the simplest usage in which we use the Java beans package classes like <code>Introspector</code> and <code>PropertyDescriptor</code> to find all the read/write properties and test the behavior, automatically creating argument objects for setter methods.</p>

<p>The core method is this one:</p> 

<pre class="prettyprint">/**
 * See {@link #assertBasicGetterSetterBehavior(Object,String)} method. Only difference is that here we accept an
 * explicit argument for the setter method.
 *
 * @param target   the object on which to invoke the getter and setter
 * @param property the property name, e.g. "firstName"
 * @param argument the property value, i.e. the value the setter will be invoked with
 */
public static void assertBasicGetterSetterBehavior(Object target, String property, Object argument) {
    try {
        PropertyDescriptor descriptor = new PropertyDescriptor(property, target.getClass());
        Object arg = argument;
        if (arg == null) {
            Class type = descriptor.getPropertyType();
            if (DEFAULT_TYPES.contains(type)) {
                arg = DEFAULT_ARGUMENTS.get(DEFAULT_TYPES.indexOf(type));
            }
            else {
                arg = ReflectionUtils.invokeDefaultConstructorEvenIfPrivate(type);
            }
        }

        Method writeMethod = descriptor.getWriteMethod();
        Method readMethod = descriptor.getReadMethod();

        writeMethod.invoke(target, arg);
        Object propertyValue = readMethod.invoke(target);
        assertSame(property + " getter/setter failed test", arg, propertyValue);
    }
    catch (IntrospectionException e) {
        String msg = "Error creating PropertyDescriptor for property [" + property +
                "]. Do you have a getter and a setter?";
        log.error(msg, e);
        fail(msg);
    }
    catch (IllegalAccessException e) {
        String msg = "Error accessing property. Are the getter and setter both accessible?";
        log.error(msg, e);
        fail(msg);
    }
    catch (InvocationTargetException e) {
        String msg = "Error invoking method on target";
        fail(msg);
        log.error(msg, e);
    }
}
</pre>

<p>This method accepts a target object, the name of the property to test, and optionally an argument. If the argument is one a of a list of default types, things like a Set or a List, we'll just use a default object like an empty Set or List as the argument. Otherwise we'll use the default constructor, which means one must exist. Then we invoke the setter with the supplied argument or one we created, and assert that the object returned by the getter is the exact same object, e.g. using <code>==</code> for comparison. (Making this assertion is what makes tools like Findbugs unhappy, which is why I disable the rule that checks this "problem.") As you can see, we have a nice little subversive method named <code>invokeDefaultConstructorEvenIfPrivate</code> in our <code>ReflectionUtils</code> class that allows you to call private constructors. In Java you need this kind of thing for unit testing so you can keep private things private, as opposed to elevating to default access just for unit tests. But what about the one-liner in our test example above? The following method is the one we saw earlier:</p>

<pre class="prettyprint">/**
 * See {@link #assertBasicGetterSetterBehavior(Object,String)} method. Big difference here is that we try to
 * automatically introspect the target object, finding read/write properties, and automatically testing the getter
 * and setter. Note specifically that read-only properties are ignored, as there is no way for us to know how to set
 * the value (since there isn't a public setter).
 * &lt;p/>
 * Note also that array properties are ignored.
 *
 * @param target the object on which to invoke the getter and setter
 */
public static void assertBasicGetterSetterBehavior(Object target) {
    try {
        BeanInfo beanInfo = Introspector.getBeanInfo(target.getClass());
        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor descriptor : descriptors) {
            if (descriptor.getWriteMethod() == null) {
                continue;
            }
            if (descriptor.getPropertyType().isArray()) {
                continue;
            }
            assertBasicGetterSetterBehavior(target, descriptor.getDisplayName());
        }
    }
    catch (IntrospectionException e) {
        fail("Failed while introspecting target " + target.getClass());
    }
}
</pre>

<p>This is pretty simple, albeit verbose. We use the nifty <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/Introspector.html">java.beans.Introspector</a> class to find the "properties," get the property descriptors and then call another overloaded <code>assertBasicGetterSetterBehavior</code> method that will call our original method with a <code>null</code> argument which means we'll create one automatically. Using this technique it is simple to automatically test generic getters and setters by adding one test method containing one line of code. We have a bunch of other overloaded methods in <code>PropertyAsserter</code> so you could choose to test only some of your properties automatically, for example if the getter and/or setter have side effects like validation and you need to explicitly test those cases.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/do_you_unit_test_getters.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/do_you_unit_test_getters.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Thu, 31 May 2007 11:06:04 -0500</pubDate>
        </item>
        
    </channel>
</rss>

