<?xml version='1.0' encoding='utf-8' ?>
<rss version='2.0' xmlns:dc='http://purl.org/dc/elements/1.1/'>
  <channel>
    <title>Wolfmans Howlings: Fixtures VS Factories, or how I do fixtures</title>
    <link>http://blog.wolfman.com/articles/2009/2/6/fixtures-vs-factories-or-how-i-do-fixtures</link>
    <description>A programmers Blog about Ruby, Rails and a few other issue</description>
    <language>en-us</language>
    <ttl>40</ttl>
    <item>
      <title>Fixtures VS Factories, or how I do fixtures</title>
      <description>
        &lt;p&gt;There is a raging debate in many forums about how to do fixture-like
        things. Basically how do you populate a database with test data so you
        can run your Specs/Tests/Features.&lt;/p&gt;
        
        &lt;p&gt;There are several libraries out there to do this like FactoryGirl,
        FixtureReplacement, Machinist, Fixjour etc etc. If you use Rails and
        ActiveRecord pick the one you like and be happy ;)&lt;/p&gt;
        
        &lt;p&gt;However I am focusing on how to do this for Integration tests that
        test the entire stack, using Cucumber/Webrat in Merb and using the Sequel
        ORM. I also use these techniques to test Java based web services
        directly over HTTP.&lt;/p&gt;
        
        &lt;p&gt;I can't use the above mentioned libraries as they rely on
        ActiveRecord, and I don't use that ORM in my Merb Apps (and obviously
        not in my Java apps).&lt;/p&gt;
        
        &lt;p&gt;I also don't have a preference for fixtures over factories, in
        fact I like bits of both paradigms.&lt;/p&gt;
        
        &lt;p&gt;My problem with fixtures is that they are really hard to maintain, and
        can be slow to load the entire database test set if run for every
        Scenario. My problem with factories is they use the Models defined in
        ActiveRecord to setup the test data set, which can be very slow as
        well. What I like about Factories is keeping the data setup close to
        the actual tests, and ease of use and maintenance. What I like about
        Fixtures is directly loading the database, and bypassing the models
        and associations.&lt;/p&gt;
        
        &lt;p&gt;I have solved the problem many times, and in different ways for each
        project I do. For my Java projects I have written a typical fixture
        loader in Java reading from a standard YAML file, so this is no
        different from Rails fixtures, just written in Java. I also wrote a
        Sequel based ruby script which loaded the database with test data, and
        needed to be manually run every time my integration tests were run.
        This was acceptable as it was a final test against a remote staging
        server before deployment to production. I needed to be able to load
        the staging database over an SSH pipe and test over an SSH pipe.&lt;/p&gt;
        
        &lt;p&gt;For my Merb/Sequel based
        &lt;a href=&quot;http://github.com/wolfmanjm/wolfmanblog/tree/master&quot;&gt;wolfmanblog&lt;/a&gt;
        project I use a hybrid solution which so far seems to work well for
        me, as it keeps the test data really close to the testing code, it is
        relatively fast as it loads the database directly rather than through
        the models, and is maintainable as it is close to the testing code.&lt;/p&gt;
        
        &lt;p&gt;Using &lt;a href=&quot;http://wiki.github.com/aslakhellesoy/cucumber&quot;&gt;Cucumber&lt;/a&gt; for
        the integration tests, and loading the test data in Givens with steps
        specifically setup to load data, and writing a Class that talks
        directly to the database via &lt;a href=&quot;http://sequel.rubyforge.org/&quot;&gt;Sequel&lt;/a&gt;
        seems to work very nicely for me.&lt;/p&gt;
        
        &lt;p&gt;Basically I write a little helper in a DBHelper Class, that loads
        specific types of data for a given test or set of tests, these helpers
        are called from the steps called by the Givens. i use a pretty high
        level abstract in the givens rather than defining low level data, so
        I say &lt;em&gt;Given a valid user&lt;/em&gt; or &lt;em&gt;Given there are 20 Articles&lt;/em&gt;, I let the
        step specify the actual data written, because the step also has the
        &lt;em&gt;Then&lt;/em&gt; clauses so I can keep the data in one place so if the user name
        is testuser1, I can test for testuser1 in the same place further down
        the file in the &lt;em&gt;Then&lt;/em&gt; clause for testing the results. A good example
        is in &lt;code&gt;wolfmanblog/features/posts/&lt;/code&gt;...&lt;/p&gt;
        
        &lt;pre&gt;&lt;code&gt;   # index.feature
           Scenario: GET /
             Given 8 posts exist
             When I go to /
             Then the request should succeed
             And I should see post 1
             And I should see post 2
             And I should see post 3
             And I should see post 4
             And I should not see post 5
        &lt;/code&gt;&lt;/pre&gt;
        
        &lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# steps/post_steps.rb&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;
        
        &lt;span class=&quot;comment&quot;&gt;# creates n posts&lt;/span&gt;
        &lt;span class=&quot;constant&quot;&gt;Given&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;/^(\&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;+)&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;posts&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;exist&lt;/span&gt;&lt;span class=&quot;global&quot;&gt;$/&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@dbhelper&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;truncate&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:posts&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;to_i&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@dbhelper&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;add_post&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:id&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;post &lt;span class=&quot;expr&quot;&gt;#{i}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;,&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;body of post &lt;span class=&quot;expr&quot;&gt;#{i}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;)&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;comment&quot;&gt;# tests if a specific post is visible&lt;/span&gt;
        &lt;span class=&quot;constant&quot;&gt;Then&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;see&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;(\&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;+)&lt;/span&gt;&lt;span class=&quot;global&quot;&gt;$/&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@response&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;have_xpath&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;//h2/a[@href='/posts/&lt;span class=&quot;expr&quot;&gt;#{n}&lt;/span&gt;']['post &lt;span class=&quot;expr&quot;&gt;#{n}&lt;/span&gt;']&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;)&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@response&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;have_selector&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;p:contains('body of post &lt;span class=&quot;expr&quot;&gt;#{n}&lt;/span&gt;')&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;)&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;constant&quot;&gt;Then&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;see&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;(\&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;+)&lt;/span&gt;&lt;span class=&quot;global&quot;&gt;$/&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@response&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;have_xpath&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;//h2/a[@href='/posts/&lt;span class=&quot;expr&quot;&gt;#{n}&lt;/span&gt;']&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;)&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;/pre&gt;
        
        &lt;p&gt;The dbhelper is defined in &lt;code&gt;./features/support/db_helper.rb&lt;/code&gt; and
        &lt;code&gt;@dbhelper&lt;/code&gt; is set in &lt;code&gt;./features/support/env.rb&lt;/code&gt;.&lt;/p&gt;
        
        &lt;p&gt;Notice I truncate the database before loading the new data, and I set
        the id of the record so I can test later on. I do this rather than use
        transactions as I like to be able to look in the database later for
        debugging purposes.  Also note I use Postgresql which supports
        &lt;code&gt;TRUNCATE .. CASCADE&lt;/code&gt; which makes it easier to clean up when you have
        foreign key constraints all over the place as I do.&lt;/p&gt;
        
        &lt;p&gt;The DBHelper class...&lt;/p&gt;
        
        &lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# Helper class to manipulate database directly&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;class &lt;/span&gt;&lt;span class=&quot;class&quot;&gt;DBHelper&lt;/span&gt;
          &lt;span class=&quot;ident&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:db&lt;/span&gt;
        
          &lt;span class=&quot;comment&quot;&gt;# setup database access&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;method&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;nil?&lt;/span&gt;
              &lt;span class=&quot;attribute&quot;&gt;@@target&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;['&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;testtarget&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;'].&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;['&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;testtarget&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;']&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
              &lt;span class=&quot;attribute&quot;&gt;@@target&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;target&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
            &lt;span class=&quot;ident&quot;&gt;dburl&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;@@target&lt;/span&gt;
              &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt;
                &lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;postgres://morris:test@localhost:5432/sample1_test&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;&lt;/span&gt;
              &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;Bad target&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;dburl&lt;/span&gt;
            &lt;span class=&quot;ident&quot;&gt;dblog&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;global&quot;&gt;$stdout&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;ident&quot;&gt;dblog&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;INFO&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;WARN&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;dblog&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
          &lt;span class=&quot;keyword&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;method&quot;&gt;close&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;disconnect&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
          &lt;span class=&quot;keyword&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;method&quot;&gt;truncate&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&amp;quot;&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;TRUNCATE &lt;span class=&quot;expr&quot;&gt;#{table.to_s}&lt;/span&gt; CASCADE&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&amp;quot;)&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
          &lt;span class=&quot;keyword&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;method&quot;&gt;add_user&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;salt&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:crypted_password&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:salt&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;salt&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
          &lt;span class=&quot;keyword&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;method&quot;&gt;add_post&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;attribute&quot;&gt;@db&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:posts&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;symbol&quot;&gt;:created_at&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;iso8601&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;symbol&quot;&gt;:updated_at&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;iso8601&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;comment&quot;&gt;# in ./features/support/env.rb&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;# runs before each Scenario&lt;/span&gt;
        &lt;span class=&quot;constant&quot;&gt;Before&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@dbhelper&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;DBHelper&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;('&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;',&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;span class=&quot;constant&quot;&gt;After&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;attribute&quot;&gt;@dbhelper&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;close&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
        
        &lt;/pre&gt;
        
        &lt;p&gt;I open a new connection to the database in this case, but I could use
        the one used by Merb using &lt;code&gt;@db= Sequel::DATABASES.first&lt;/code&gt;.&lt;/p&gt;
        
        &lt;p&gt;I try to keep the helpers in this file as generic as possible so they
        can be used in different Givens, but sometimes you have to be very
        specific. Try to encapsulate all database knowledge in this file.&lt;/p&gt;
        
        &lt;p&gt;To summarize...&lt;/p&gt;
        
        &lt;ul&gt;
        &lt;li&gt;I put very high level setup commands in the features Given.&lt;/li&gt;
        &lt;li&gt;I put the detailed contents in the associated step.&lt;/li&gt;
        &lt;li&gt;I actually load the database in the helper.&lt;/li&gt;
        &lt;li&gt;I keep the Then tests close to the Given that sets up the data&lt;/li&gt;
        &lt;/ul&gt;
        
        &lt;p&gt;&lt;a href=&quot;http://technorati.com/tag/merb+fixtures&quot; rel=&quot;tag&quot;&gt;&lt;/a&gt;
        &lt;a href=&quot;http://technorati.com/tag/sequel+fixtures&quot; rel=&quot;tag&quot;&gt;&lt;/a&gt;
        &lt;a href=&quot;http://technorati.com/tag/cucumber+fixtures&quot; rel=&quot;tag&quot;&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      <author>Jim Morris</author>
      <pubDate>Fri, 06 Feb 2009 20:40:55 -0800</pubDate>
      <link>http://blog.wolfman.com/articles/2009/2/6/fixtures-vs-factories-or-how-i-do-fixtures</link>
      <guid isPermaLink='false'>urn:uuid:241254dc-1c30-4f62-96a0-54890a6f1981</guid>
    </item>
    <item>
      <title>"Fixtures VS Factories, or how I do fixtures" by Phlip</title>
      <description>
        I have a few tips about tests that resist fixture drift - of whatever type - in this post here: http://broadcast.oreilly.com/2009/02/merb-mind-maps.html
        
        And tx for this blog - I used it in that post!
      </description>
      <pubDate>Sun, 15 Feb 2009 16:55:07 -0800</pubDate>
      <link>http://blog.wolfman.com/posts/42#comment-243</link>
      <guid isPermaLink='false'>urn:uuid:71781094-0108-4747-b548-f1f2f3918f68</guid>
    </item>
  </channel>
</rss>
