<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Wood for the Trees: ActiveTest: Examination, Part I: Removing Transparency</title>
    <link>http://www.mathewabonyi.com/articles/2006/12/31/activetest-examination-part-i-removing-transparency</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>struggling to dig life</description>
    <item>
      <title>ActiveTest: Examination, Part I: Removing Transparency</title>
      <description>&lt;p style="text-align:justify;"&gt;The first abstraction I made was to change &lt;code&gt;assert_get_success&lt;/code&gt; and its equivalents (&lt;code&gt;get_failure&lt;/code&gt;, &lt;code&gt;post_success&lt;/code&gt;, etc.) into an abstract idea of common test cases. Obviously every application is going to be treated differently, but to make a suite of tools to remove the most common tests seemed like a useful thing to extract&amp;#8212;it&amp;#8217;s &lt;span class="caps"&gt;DRY&lt;/span&gt;.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;Consequently, I had the following in &lt;code&gt;Test::Unit::TestCase&lt;/code&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_should_index_items&lt;/span&gt;
      &lt;span class="ident"&gt;define_method&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:test_should_index_items&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;assert_get_success&lt;/span&gt; &lt;span class="symbol"&gt;:index&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p style="text-align:justify;"&gt;I then abstracted it a little:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_should_get_with_success&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;action&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="symbol"&gt;:index&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;parameters&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{})&lt;/span&gt;
      &lt;span class="ident"&gt;define_method&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;test_should_&lt;span class="expr"&gt;#{action}&lt;/span&gt;_item&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;assert_get_success&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;parameters&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p style="text-align:justify;"&gt;This is basic DRYing up. However, I have at this point already lost sight of the simplest benefit of writing out test cases with &lt;code&gt;Test::Unit&lt;/code&gt;: &lt;strong&gt;documentation&lt;/strong&gt;. If someone else uses this, the only thing they know is that their &lt;span class="caps"&gt;GET&lt;/span&gt; succeeds&amp;#8230; but in what way? I began documenting what each method does and extracting more and more complex cases which may be &amp;#8216;common&amp;#8217;. Documenting these methods hid the general fault, which was making the entire testing process opaque to the user. Tests started to look like this:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TestSomething&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveTest&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;test_should_get_with_success&lt;/span&gt; &lt;span class="symbol"&gt;:index&lt;/span&gt;
  &lt;span class="ident"&gt;test_should_get_with_success&lt;/span&gt; &lt;span class="symbol"&gt;:show&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
  &lt;span class="ident"&gt;test_should_get_with_success&lt;/span&gt; &lt;span class="symbol"&gt;:new&lt;/span&gt;
  &lt;span class="ident"&gt;test_should_get_with_success&lt;/span&gt; &lt;span class="symbol"&gt;:edit&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p style="text-align:justify;"&gt;So my first mistake was removing transparency without thinking about what I was beginning to lose. This is quite project-specific. In most cases, making methods opaque and useful is a good thing, but in the case of ActiveTest, it needs to be flexible &lt;strong&gt;and&lt;/strong&gt; transparent. It is hard to beat a series of asserts.[1]&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;This mistake is probably my least offensive, because some, including myself, may like this feature just to remove all those irritating &lt;code&gt;test_should_index_items&lt;/code&gt;, especially when you are writing new controllers left and right.&lt;/p&gt;


	&lt;h4&gt;What Was I Thinking?&lt;/h4&gt;


	&lt;p style="text-align:justify;"&gt;I thought that the documenting aspect of testing was purely outlining what everything should do, rather than describing what everything should do. My original idea was to make it easier to document and test at the same time by outlining the cases in each suite. Just in terms of line ratios, I now had a 5-line method which let me write a test case in 1 line. Not bad. It quickly paid for itself because it catered to &lt;code&gt;:index&lt;/code&gt;, &lt;code&gt;:new:&lt;/code&gt;, &lt;code&gt;:show&lt;/code&gt; and &lt;code&gt;:edit&lt;/code&gt;. However, I lost all the expressiveness of showing what is being tested.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;&lt;strong&gt;Coming Up Next: Abstracting Without Basis&amp;#8230;&lt;/strong&gt;&lt;/p&gt;


	&lt;h4&gt;Footnotes&lt;/h4&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; It can be done. In fact, the next generation of Active Test, while rather different, frees up the tester to think completely about the behaviour of his code. I will trade in the brevity of test cases for the flexibility of defining them (for anything, whether Rails application, plugin, gem or 60-line file).&lt;/p&gt;</description>
      <pubDate>Sun, 31 Dec 2006 22:34:58 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5d8d7084-a21d-4b8e-9795-497e5d35fd09</guid>
      <author>Mathew Abonyi</author>
      <link>http://www.mathewabonyi.com/articles/2006/12/31/activetest-examination-part-i-removing-transparency</link>
      <category>Discoveries</category>
      <category>Ruby</category>
      <category>Rails</category>
      <category>Plugins</category>
      <trackback:ping>http://www.mathewabonyi.com/articles/trackback/35</trackback:ping>
    </item>
  </channel>
</rss>
