<?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: Rails-style testing</title>
    <link>http://www.mathewabonyi.com/articles/2006/08/14/activetest-rails-style-testing</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>struggling to dig life</description>
    <item>
      <title>ActiveTest: Rails-style testing</title>
      <description>&lt;p style="text-align:justify;"&gt;In pursuit of my &lt;a href="http://www.mathewabonyi.com/articles/2006/08/12/testing-what-needs-improvement"&gt;previous post&lt;/a&gt;, I&amp;#8217;ve followed up with an alpha mock-up of my ideas on how Rails testing can be made less tedious. Here&amp;#8217;s the first version readme:&lt;/p&gt;


	&lt;h3&gt;Cautionary Word&lt;/h3&gt;


&lt;pre&gt;
USE AT YOUR OWN PERIL.
ACTIVETEST IS NOT FINISHED.
IT HAS BUGS.
IT IS MISSING A LOT OF FEATURES.
&lt;/pre&gt;

	&lt;h3&gt;Balls to Caution. How do I install?&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_shell "&gt;  $ ./script/plugin source http://mabs29.googlecode.com/svn/trunk/plugins
  $ ./script/plugin install active_test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Foreword&lt;/h3&gt;


	&lt;p style="text-align:justify;"&gt;You will see a lot of similarities between ActiveTest and its paronymic relative, ActiveRecord.
I think it best to explain here. Other implementations which are attempting, with various
success, to extend the functionality of Test::Unit and make it more Rails friendly have their
own unique ways of setting up and developing. The price of their uniqueness is that they move
away from the traditional thinking of a Rails developer. They introduce more complications of
design and elements to be aware of, meaning more time to understand how something can be done.
I do not want to think about the nuances of a test suite and model. The closer they are to each
other in design and usage, the easier it is to test them rapidly.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;So, without being overly creative, but instead using the conventions of Rails development in the
development of Rails itself, I think, basically, ripping off ActiveRecord&amp;#8217;s design (which is a
perfectly good one for this purpose) is not such a bad idea. It eases the pain of learning how
to use ActiveTest and it brings the mentality of Rails closer to tests. This is the whole point
of ActiveTest: Rails-like testing.&lt;/p&gt;


	&lt;h3&gt;Description&lt;/h3&gt;


	&lt;p style="text-align:justify;"&gt;ActiveTest is an attempt &amp;#8211; yet another &amp;#8211; at making Test::Unit fit into the mould of Rails, a la
ActiveRecord and ActionController. It uses a Base class from which are extended a number of
Subjects, each subject including a specific set of Asserts. Each Asserts module can extend the
instance methods of a test suite, such as &amp;#8216;assert_is_a_hippo&amp;#8217;, as well as the class methods.
It is the class method idea which allows you to create ActiveRecord/ActionController style macros.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;Read on for more specifics.&lt;/p&gt;


	&lt;h3&gt;Subjects&lt;/h3&gt;


	&lt;p style="text-align:justify;"&gt;Subjects are the types of tests you will run, like Controller, Model, Helper, View,
Stress and Integration. Virgin Subjects can be created by extending the ActiveTest::Subject
class itself, exactly how one creates new models inheriting from ActiveRecord::Base. You can,
if you wish to have a completely blank slate, inherit directly from ActiveTest::Base too.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;The best way to think of subjects is that they are pre-made ActiveRecord models. Everyone has
a controller, view, helper, or record, so we can make certain assumptions which ActiveRecord
cannot. We are not differing from the ActiveRecord metaphors. We are just filling in some blanks
for convenience. If you don&amp;#8217;t like the convenience, just extend ActiveTest::Base. You&amp;#8217;ll get all
the fancy stuff of Test::Unit::TestCase, no less and certainly no more.&lt;/p&gt;


	&lt;p style="text-align:justify;"&gt;You can create custom subjects like so:&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;ActiveTest::FlyingRhino&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;Subject&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;&lt;strong&gt;Alpha Note: At present, there is no advantage to doing this.&lt;/strong&gt;&lt;/p&gt;


	&lt;h3&gt;Assertions&lt;/h3&gt;


	&lt;p style="text-align:justify;"&gt;ActiveTest allows you to create &amp;#8216;assertion packages&amp;#8217;. Think &amp;#8216;Acts As &amp;#8230;&amp;#8217;. If you want a new
assertion suite for a particular Subject, all you need to do is create a plugin with this init.rb:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="constant"&gt;ActiveTest&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;PickASubject&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;class_eval&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;include&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;Asserts&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;YourAssertions&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;And in your plugin/lib:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;ActiveTest&lt;/span&gt;
    &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Asserts&lt;/span&gt;
      &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;YourAssertion&lt;/span&gt;

        &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.included&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;base&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
          &lt;span class="ident"&gt;base&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;ClassMethods&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;ClassMethods&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;instance_method&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;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p style="text-align:justify;"&gt;That all looks very familiar, doesn&amp;#8217;t it?&lt;/p&gt;


	&lt;h3&gt;Examples&lt;/h3&gt;


	&lt;p style="text-align:justify;"&gt;Currently, there&amp;#8217;s just a Controller subject. An active test would (will) 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;SessionControllerTest&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;Controller&lt;/span&gt;

    &lt;span class="ident"&gt;setup_controller&lt;/span&gt; &lt;span class="symbol"&gt;:login_as&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:quentin&lt;/span&gt;

    &lt;span class="ident"&gt;test_require_login_for&lt;/span&gt; &lt;span class="symbol"&gt;:new&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:create&lt;/span&gt;&lt;span class="punct"&gt;,&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;:update&lt;/span&gt;

    &lt;span class="ident"&gt;test_require_permission_for&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:method&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:delete&lt;/span&gt;

    &lt;span class="ident"&gt;test_index_should_index_items&lt;/span&gt;

    &lt;span class="ident"&gt;test_show_should_show_item&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_edit_should_edit_item&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_update_should_update_item&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_destroy_should_destroy_item&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_new_should_new_item&lt;/span&gt;

    &lt;span class="ident"&gt;test_create_should_create_item&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_special_case_for_this_controller&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;protected&lt;/span&gt;
    &lt;span class="comment"&gt;# overwrite the default create_item, which expects parameters from dynamic class methods&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_item&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="constant"&gt;nil&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="keyword"&gt;super&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:create&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:session&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:login&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;anotherguy&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;})&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;The class methods create a bunch of tests for you which do precisely what it says: requires login.
By default, the Controller subject has the Authentication and Authorisation modules, which assume
you are using some variant of Acts As Authenticated.&lt;/p&gt;</description>
      <pubDate>Mon, 14 Aug 2006 23:49:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:956774ee-d84b-46d8-ba0b-752389b869a4</guid>
      <author>Mathew Abonyi</author>
      <link>http://www.mathewabonyi.com/articles/2006/08/14/activetest-rails-style-testing</link>
      <category>Rails</category>
      <trackback:ping>http://www.mathewabonyi.com/articles/trackback/22</trackback:ping>
    </item>
  </channel>
</rss>
