<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/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>Robby on Rails: Tag testing</title>
    <link>http://www.robbyonrails.com/articles/tag/testing</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>Spec Your Views</title>
      <description>&lt;p&gt;I meant to work on this post&amp;#8230; oh about 7 months ago.&lt;/p&gt;


	&lt;p&gt;Way back in January (7 months ago), Jamis Buck posted an article titled, &lt;a href="http://weblog.jamisbuck.org/2007/1/29/testing-your-views"&gt;Testing your views&lt;/a&gt;, which gave a few tips on using Test::Unit to, as the title suggests, test your views.&lt;/p&gt;


	&lt;p&gt;While, I&amp;#8217;m not going to rewrite everything that Jamis wrote, I&amp;#8217;d like to show you how to test these views with RSpec. (you might take a moment to quickly read his post&amp;#8230;)&lt;/p&gt;


	&lt;p&gt;In this example, I&amp;#8217;m going to show you how we&amp;#8217;re able to write specs for the following &lt;span class="caps"&gt;RHTML&lt;/span&gt;, which  you&amp;#8217;ll notice matches the code that he wrote tests for.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  &amp;lt;% if @user.administrator? %&amp;gt;
    Hi &amp;lt;%= @user.name %&amp;gt;! You appear to be an administrator.
    &amp;lt;%= link_to "Click here", admin_url, :id =&amp;gt; "admin_link" %&amp;gt;
    to see the admin stuff!
  &amp;lt;% end %&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Jamis writes, &lt;em&gt;&amp;#8220;The only really significant thing you ought to be testing here is that the admin link only shows up for administrators. &amp;#8220;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;So, let&amp;#8217;s do just that, but with RSpec.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not sure how Jamis is handling his view tests, but we&amp;#8217;re going to approach our view specs, much like we approach our controller specs, with the use of mocks and stubs, because we really don&amp;#8217;t need to spec any of our models at this level in the application.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Write specifications for your models&amp;#8230; in your model specs &lt;strong&gt;not&lt;/strong&gt; in your controller or view specs.&lt;/p&gt;


	&lt;p&gt;The first thing that we&amp;#8217;re going to do is setup a custom spec helper, because for something like an mocked user, will probably get reused in other areas of the user interface. Spec helpers are essentially modules that you can include in your RSpec descriptions (the block that starts with &lt;code&gt;describe&lt;/code&gt;) and reuse.&lt;/p&gt;


	&lt;p&gt;In this spec helper, I&amp;#8217;m going to include two methods, to mock the User model and stub out any of the methods that are necessary for spec&amp;#8217;n this view.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
module MockUserHelper
  def mock_normal_user
    user = mock(User)
    user.stub!(:administrator?).and_return(false)   # &amp;lt;--- NOT an admin
    user.stub!(:name).and_return('David Chelimsky')
    return user
  end

  def mock_admin_user
    user = mock(User)
    user.stub!(:administrator?).and_return(true)    # &amp;lt;--- IS an admin
    user.stub!(:name).and_return('Aslak Hellesoy')
    return user
  end
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the &lt;code&gt;mock_normal_user&lt;/code&gt; method, we&amp;#8217;re constructing a mock object and stubbing out the methods that we see are being called in the &lt;span class="caps"&gt;RHTML&lt;/span&gt; code. In &lt;code&gt;mock_admin_user&lt;/code&gt;, we&amp;#8217;re basically doing the same thing, but just stubbing the &lt;code&gt;administrator?&lt;/code&gt; method to return &lt;code&gt;true&lt;/code&gt; for this mock user.&lt;/p&gt;


	&lt;p&gt;By stubbing these methods, we&amp;#8217;ll be able to send a non-ActiveRecord object to the view and have it render without knowing the difference. For example, the &lt;code&gt;if @user.administrator?&lt;/code&gt; condition will return true or false, depending on how we stubbed it.&lt;/p&gt;


	&lt;p&gt;For more information on mocks and stubs, &lt;a href="http://rspec.rubyforge.org/documentation/mocks/index.html"&gt;read here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Now that we have our spec helper, let&amp;#8217;s go ahead and dive into a few specifications for the view.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
describe "index page" do
  include MockUserHelper

  it "should render an admin link for an admin user" do
    assigns[:user] = mock_admin_user
    render 'index'
    response.should have_tag('a#admin_link')
  end

  it "should not render an admin link for a normal, non-admin user" do
    assigns[:user] = mock_normal_user
    render 'index'
    response.should_not have_tag('a#admin_link')
  end
end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; This code example is only longer than the one shown by Jamis because he didn&amp;#8217;t include how he setup all his user sessions/objects. ;-)&lt;/p&gt;


	&lt;p&gt;When these specs are run, we can see the following results.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://myskitch.com/robbyrussell/rspec_results-20070801-233809.jpg" alt="" /&gt;&lt;br /&gt;&lt;small&gt;Pretty output courtesy of RSpec + TextMate bundle&lt;/small&gt;&lt;/p&gt;


	&lt;p&gt;Great, we&amp;#8217;ve been able to write specifications for our Rails views without a lot of pain. Stay tuned for more posts on this topic as I continue writing about how Designers and Developers can work together, in harmony. (&lt;a href="http://www.robbyonrails.com/articles/2007/08/01/designers-developers-and-the-x_-factor"&gt;see my last post on this topic&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;For more information on adopting RSpec, please visit the &lt;a href="http://rspec.rubyforge.org"&gt;RSpec project homepage&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Thu, 02 Aug 2007 02:00:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c21e25cf-1a4a-4b9f-a628-89fc00945829</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/08/02/spec-your-views</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>testing</category>
      <category>driven</category>
      <category>bdd</category>
      <category>rspec</category>
      <category>behavior</category>
      <category>mocks</category>
      <category>designers</category>
      <category>rhtml</category>
      <category>html</category>
      <category>specs</category>
    </item>
    <item>
      <title>Embracing Failure, part 1</title>
      <description>&lt;p&gt;I&amp;#8217;m currently reading &lt;a href="http://www.amazon.com/Engineer-Human-Failure-Successful-Design/dp/0679734163"&gt;To Engineer is Human&lt;/a&gt;, by Henry Petroski and found the following applicable to software development and managing client and customer expectations.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;As much as it is human to make mistakes, it is also human to want to avoid them. Murphy&amp;#8217;s Law, holding that anything that can go wrong will, is not a law of nature but a joke. All the light bulbs that last until we tire of the lamp, all the shoelaces that outlast their shoes, all the automobiles that give trouble-free service until they are traded in have the last laugh on Murphy. Just as he will not outlive his law, so nothing manufactured can be or is expected to last forever. Once we recognize this elementary fact, the possibility of a machine or a building being as near to perfect for its designed lifetime as its creators may strive to be for theirs is not only a realistic goal but also a reasonable expectation for consumers. It is only when we set ourselves such an unrealistic goal as buying a shoelace that will never break, inventing a perpetual motion machine, or building a vehicle that will never break down that we appear to be fools and not rational beings.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I&amp;#8217;m sure that most of us are guilty of having high expectations for products that we purchased. (why does my ipod screen scratch so easily when in my pocket?) We also set high expectations for the code that we develop, which is why we (hopefully) continue to refine our process. We&amp;#8217;re bound to time and budget constraints, which often prevent us from testing every imaginable edge case. Given our constraints, problems are almost always going to arise. It&amp;#8217;s no wonder that we see Test-Driven Development as an important part of a healthy development process. We want to catch our failures as early as possible.&lt;/p&gt;


	&lt;p&gt;Our clients often have high expectations and it&amp;#8217;s almost always very reasonable. That&amp;#8217;s not to say that some clients will not have highly irrational expectations. It&amp;#8217;s our job to manage these expectations as best as possible.&lt;/p&gt;


	&lt;p&gt;Do we mislead our clients by convincing them that our &lt;span class="caps"&gt;TDD&lt;/span&gt;/BDD process is going to prevent any bugs from creeping from the woodwork after the development cycle is finished?&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;&amp;#8220;I thought that we paid you to fully test the code?&amp;#8221;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Really&amp;#8230; is that even possible? Can we predict (and test) every possible interaction within an application? Highly unlikely.&lt;/p&gt;


	&lt;p&gt;What we &lt;em&gt;can&lt;/em&gt; do is plan for and embrace failure. We can help our clients understand that almost every application needs to be &lt;em&gt;maintained&lt;/em&gt; after it&amp;#8217;s initial development cycle. Bugs are inevitable and there needs to be a &lt;a href="http://daringfireball.net/linked/2007/march#wed-14-adobedevcycle"&gt;clear process for handling them&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Perhaps I&amp;#8217;m abusing the bug fixing process by calling it a failure&amp;#8230; but I&amp;#8217;ve also found that yes&amp;#8230; many bugs are due to failure. Whether that be a failure to &lt;a href="http://behavior-driven.org/"&gt;specify application behavior&lt;/a&gt;, a failure to understand the project goals, a &lt;a href="http://www.robbyonrails.com/articles/2006/09/27/project-enlightenment-with-d3"&gt;failure in communication&lt;/a&gt;, ...or maybe a failure in our software architecture. We&amp;#8217;re constantly failing.. and it&amp;#8217;s okay!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;IT&amp;#8217;S &lt;span class="caps"&gt;OKAY TO FAIL&lt;/span&gt;!&lt;/strong&gt; (some of the time&amp;#8230;)&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;No one &lt;em&gt;wants&lt;/em&gt; to learn by mistakes, but we cannot learn enough from successes to go beyond the state of the art. Contrary to their popular characterization as intellectual conservatives, engineers are really among the avant-garde. They are constantly seeking to employ new concepts to reduce the weigh and thus the cost of their structures, and they are constantly striving to do more with less so the resulting structure represents an efficient use of materials. The engineer always believes he is trying something without error, but the truth of the matter is that each new structure can be a new trial. In the meantime the layman, whose spokesman is often a poet or writer, can be threatened by both the failures &lt;em&gt;and&lt;/em&gt; the successes. Such is the nature not only of science and engineering, but of all human endeavors.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;As we&amp;#8217;re creating these virtual structures&amp;#8230; are we really taking the time to reflect on our failures? This is why some teams adopt practices like iteration retrospectives and post-mortems.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll end this with a few questions, which I hope that you&amp;#8217;ll share your experiences about&amp;#8230;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;In what ways is your team embracing the failures of your development projects?&lt;/li&gt;
		&lt;li&gt;How do you help manage your clients expectations&amp;#8230; so that they too can plan for and embrace failure? Isn&amp;#8217;t their new business venture on the web&amp;#8230; likely to experience some failure?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;We have so much to learn&amp;#8230;&lt;/p&gt;
</description>
      <pubDate>Tue, 10 Apr 2007 16:38:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b216559d-75b1-443f-a42b-65a8feefe92d</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/04/10/embracing-failure-part-1</link>
      <category>Business</category>
      <category>Programming</category>
      <category>d3</category>
      <category>book</category>
      <category>tdd</category>
      <category>development</category>
      <category>testing</category>
      <category>agile</category>
      <category>design</category>
      <category>clients</category>
      <category>communication</category>
      <category>bdd</category>
      <category>failure</category>
      <category>expectations</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Be Careful that you don't Stub your Big Toe</title>
      <description>&lt;p&gt;In a project that I&amp;#8217;m currently working on, we&amp;#8217;re handling recurring payments for subscribers. I&amp;#8217;ve decided to play with a different payment service &lt;span class="caps"&gt;API&lt;/span&gt; on this project (&lt;a href="http://www.trustcommerce.com/"&gt;TrustCommerce&lt;/a&gt;), which supposedly has one of the easier systems to handle recurring payments as well as one-time charges to the same credit cards. They store all the credit card data so that our delivered product to the client is &lt;a href="http://usa.visa.com/merchants/risk_management/cisp.html"&gt;&lt;span class="caps"&gt;CISP&lt;/span&gt;-compliant&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I came across the &lt;a href="http://www.agilewebdevelopment.com/plugins/trustcommerce_subscription"&gt;TrustCommerce Subscription&lt;/a&gt; plugin for Rails, which does just everything that I need to do in this first product release&amp;#8230; as well as things that aren&amp;#8217;t requirements just yet.&lt;/p&gt;


	&lt;p&gt;Well, I got my test account from TrustCommerce and was working on some RSpecs to test my new subscription and noticed that it was failing. After some snooping around the error responses, I realized that&amp;#8230; test accounts don&amp;#8217;t give you the ability to test the &lt;a href="http://www.trustcommerce.com/citadel.php"&gt;Citadel&lt;/a&gt; features of TrustCommerce. It&amp;#8217;ll be another week or so before finish getting our account setup, so what am I to do? I really want to finish writing these specs and move on to the other portions that are dependent upon this working.&lt;/p&gt;


	&lt;p&gt;Suppose that you were going to perform something like this in an AR callback.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class BillingDetail &amp;lt; ActiveRecord::Base

  # validations    

  before_create :store_credit_card_data_with_trust_commerce

  private 

    def store_credit_card_data_with_trust_commerce
      # some of this is still test data... prettyu much copied from the README
      # TODO: refactor... but keep me out of controllers!
      response = TrustCommerceGateway::Subscription.create(
          :cc =&amp;gt;  self.credit_card_number, 
          :exp =&amp;gt; '0412', 
          :name =&amp;gt; self.customer_name,
          :amount =&amp;gt; 1,
          :cycle =&amp;gt; '1y',
          :demo =&amp;gt; 'y'
        )

      if response['status'] == 'approved'
          self.billing_id = response['billingid']
        else
        # handle failure
        end
    end
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;h2&gt;Enter Mock Objects&lt;/h2&gt;


	&lt;p&gt;Since I am unable to succesfully use the &lt;code&gt;TrustCommerceGateway::Subscription.create&lt;/code&gt; method until I get our real account, I needed a simple way to emulate the interaction with the web service.&lt;/p&gt;


	&lt;p&gt;This can be done by using a Mock object, which RSpec provides for you.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
TrustCommerceGateway::Subscription.stub!(:create).and_return( {expected response} )
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Let&amp;#8217;s look at the following spec file (much of it removed to protect the innocent).&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
module ValidBillingDetail
  def valid_attributes
    { # a hash of valid key/values for this model }
  end

  def approved_trust_commerce_subscription
    { 'status' =&amp;gt; 'approved', 'billingid' =&amp;gt; '1093423' } 
  end
end

context "A new billing detail" do
  include ValidBillingDetail

  setup do
    TrustCommerceGateway::Subscription.stub!(:create).and_return( approved_trust_commerce_subscription )
  end

  # bunch of other specs

  specify "should store new billing info with 3rd party API and store the billingid" do
    @billing_detail = BillingDetail.create( valid_attributes )
    @billing_detail.billing_id.should_not_be nil
  end
end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You&amp;#8217;ll notice a few things. First, you&amp;#8217;ll see that I&amp;#8217;ve stubbed the &lt;code&gt;create&lt;/code&gt; method and when it is called in the method in my model, it&amp;#8217;ll return the hash that I&amp;#8217;ve specified.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;TrustCommerceGateway::Subscription.stub!(:create).and_return( approved_trust_commerce_subscription )&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the spec, you will see that I am checking that that the &lt;code&gt;.billing_id.should_not_be nil&lt;/code&gt;. If you look back in the method in the model above, you will notice that an approved subscription returns a &lt;code&gt;billing_id&lt;/code&gt;, which is set when the transaction is successful.&lt;/p&gt;


	&lt;p&gt;This is working out great for me and because the documentation is fairly easy to follow, I&amp;#8217;m going to be able to mock much of the behavior that I&amp;#8217;ll be using in the application, without needing to even connect to their &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;re using RSpec, I highly encourage you to read more about &lt;a href="http://rspec.rubyforge.org/documentation/mocks/mocks.html"&gt;mocks objects&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Tue, 13 Feb 2007 01:09:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:6e9733fb-1d6b-42a8-a0ad-29948aacd45c</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/02/13/be-careful-that-you-dont-stub-your-big-toe</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>rspec</category>
      <category>bdd</category>
      <category>mocks</category>
      <category>stubs</category>
      <category>trustcommerce</category>
      <category>plugins</category>
      <category>testing</category>
    </item>
    <item>
      <title>Testing Cookies in Ruby on Rails</title>
      <description>&lt;p&gt;Over the weekend, &lt;a href="http://blog.brightredglow.com/"&gt;Brian Ford&lt;/a&gt; released a useful plugin for testing your &lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt; applications called, &lt;a href="http://blog.brightredglow.com/articles/2006/08/27/assert_cookie-for-ooey-gooey-fun"&gt;assert_cookie&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Brian likes his cookies&amp;#8230;&lt;/h2&gt;


&lt;center&gt;
&lt;img src="http://www.robbyonrails.com/files/cookie-monster.jpg" alt="" /&gt; 
&lt;/center&gt;

	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;&amp;#8220;I love cookies. There are, of course, tons of varieties and I’m no connoisseur but I love the soft chocolate chip right out of the oven, hot and gooey. But, if you’re like me, you don’t want your Rails code to be gooey.&amp;#8221;&lt;/em&gt; -Brian Ford&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;To use &lt;strong&gt;assert_cookie&lt;/strong&gt;, follow these steps.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Install via, &lt;code&gt;script/plugin install http://svn.planetargon.org/rails/plugins/assert_cookie&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Fill your tests with some cookies&lt;/li&gt;
		&lt;li&gt;Test your cookies!&lt;/li&gt;
	&lt;/ol&gt;


Here are a few examples that Brian posted.
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="ident"&gt;assert_cookie&lt;/span&gt; &lt;span class="symbol"&gt;:pass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; 
      &lt;span class="symbol"&gt;:value&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;UUID&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;valid?&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;assert_cookie&lt;/span&gt; &lt;span class="symbol"&gt;:yellow&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:value&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;sunny&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;days&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;
  &lt;span class="ident"&gt;assert_cookie&lt;/span&gt; &lt;span class="symbol"&gt;:delight&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:value&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;yum&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;assert_cookie&lt;/span&gt; &lt;span class="symbol"&gt;:secret&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:path&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;path&lt;/span&gt; &lt;span class="punct"&gt;=~&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;secret&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;},&lt;/span&gt; 
      &lt;span class="symbol"&gt;:secure&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;For more information on other plugins and tools that &lt;a href="http://www.planetargon.com"&gt;&lt;span class="caps"&gt;PLANET ARGON&lt;/span&gt;&lt;/a&gt; is releasing under open source licenses, visit &lt;a href="http://www.planetargon.org"&gt;www.planetargon.org&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Also, be sure to &lt;a href="http://feeds.feedburner.com/defeulerxcosxisinxend"&gt;subscribe to Brian Ford&amp;#8217;s feed&lt;/a&gt; as he says he&amp;#8217;ll be announcing more plugins and tips soon. :-)&lt;/p&gt;


	&lt;p&gt;Have Fun!&lt;/p&gt;
</description>
      <pubDate>Mon, 28 Aug 2006 08:27:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ba154b0e-9877-434d-9fd1-b60ea4a43f93</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/08/28/testing-cookies-in-ruby-on-rails</link>
      <category>cookies</category>
      <category>testing</category>
      <category>plugins</category>
      <category>planetargon</category>
      <category>brian</category>
      <category>rails</category>
      <category>monster</category>
    </item>
    <item>
      <title>Continuous Integration == Communication</title>
      <description>&lt;p&gt;Martin Fowler has updated his &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;Continuous Integration&lt;/a&gt; article.&lt;/p&gt;


	&lt;p&gt;One of the points that I appreciated reading about in this article was that when you&amp;#8217;re working in a team, the ability to keep consistent communication. This is vital to the success of the project, just like all forms of quality communication is important during the lifespan of a project.&lt;/p&gt;


&lt;blockquote&gt;
&lt;em&gt;&amp;#8220;Continuous Integration is all about communication, so you want to ensure that everyone can easily see the state of the system and the changes that have been made to it.&amp;#8221;&lt;/em&gt;
&lt;/blockquote&gt;

	&lt;p&gt;Another point reminded me of something I recently posted about&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;, which was that you should always keep your project releasable&amp;#8230; &lt;em&gt;at all times&lt;/em&gt;.&lt;/p&gt;


&lt;blockquote&gt;
&lt;em&gt;&amp;#8220;To help make this work, anyone involved with a software project should be able to get the latest executable and be able to run it: for demonstrations, exploratory testing, or just to see what changed this week.&lt;/em&gt;&amp;#8221; 
&lt;/blockquote&gt;

	&lt;p&gt;&lt;strong&gt;Test. Before. You. Commit.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Fowler also mentions &lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt; in regards to automating deployment practices yourself. :-)&lt;/p&gt;


	&lt;p&gt;In any event, &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;read the article&lt;/a&gt;.&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;a href="http://www.robbyonrails.com/articles/2006/04/21/agile-development-begins-within"&gt;Agile development begins within&amp;#8230;&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 02 May 2006 10:24:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:584c0b36-8ae5-4ef6-a378-45fc4d456351</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/05/02/continuous-integration-communication</link>
      <category>Ruby on Rails</category>
      <category>Programming</category>
      <category>testing</category>
      <category>development</category>
      <category>agile</category>
    </item>
    <item>
      <title>Rails, Logger, and those pesky Tests</title>
      <description>&lt;p&gt;First of all, I would like to thank all of you who took a moment to &lt;a href="http://www.robbyonrails.com/articles/2006/01/09/request-for-rails-debugging-tools"&gt;gather around the campfire with me&lt;/a&gt; and share &lt;a href="http://www.robbyonrails.com/articles/2006/01/09/request-for-rails-debugging-tools#comments"&gt;your stuff&lt;/a&gt;. That was much appreciated.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://www.planetargon.com/files/~robby/cowboy_kids.jpg" style="float: right;" &gt;&lt;/p&gt;


	&lt;p&gt;So, I started playing with the idea of logging in unit and functional tests and I quickly realized that calling &lt;code&gt;logger.info&lt;/code&gt; wasn&amp;#8217;t an option. What&amp;#8217;s the deal-e-o? Before I gather up my posse and conspire a train hijacking, I decided that I would see how quickly I could solve my problem before I called you all out to the Rio Rails Grande for an old-fashioned shoot out. Ya know, the kind that results in a Bon Jovi song and a little blood.&lt;/p&gt;


You&amp;#8217;re all in luck because:
	&lt;ul&gt;
	&lt;li&gt;A) my holster was eaten by my dog
and&lt;/li&gt;
		&lt;li&gt;B) I found a quick solution to clean up this &lt;code&gt;logger&lt;/code&gt; situation.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Okay&amp;#8230; are you ready?&lt;/p&gt;


	&lt;p&gt;I know&amp;#8230; this is &lt;strong&gt;totally groundbreaking&lt;/strong&gt;!!!&lt;/p&gt;


	&lt;p&gt;Open up &lt;code&gt;test/test_helper.rb&lt;/code&gt; and add the method&amp;#8230; &lt;code&gt;logger&lt;/code&gt;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# other stuff at the top of the file... just &lt;/span&gt;
&lt;span class="comment"&gt;# look down below at def logger&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Test::Unit::TestCase&lt;/span&gt;
  &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;use_transactional_fixtures&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;use_instantiated_fixtures&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;

  &lt;span class="comment"&gt;# here... look here! right below this&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;logger&lt;/span&gt;
    &lt;span class="constant"&gt;RAILS_DEFAULT_LOGGER&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&gt;Save that and pick up your pistol&amp;#8230;&lt;/p&gt;


	&lt;p&gt;The next step is to call the logger method in your unit and functional tests.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_the_obvious&lt;/span&gt;
  &lt;span class="ident"&gt;logger&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;info&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;asserting that 1 is 1&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;assert&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&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&gt;I &lt;a href="http://rails.techno-weenie.net/tip/2005/11/20/log_within_tests"&gt;posted this&lt;/a&gt; on &lt;a href="http://rails.techno-weenie.net"&gt;Rails Weenie&lt;/a&gt; as well.&lt;/p&gt;
</description>
      <pubDate>Wed, 25 Jan 2006 16:06:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3e1240ab-de42-4ef0-b436-7de4a28f1efe</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/01/25/rails-logger-and-those-pesky-tests</link>
      <category>rails</category>
      <category>testing</category>
    </item>
    <item>
      <title>Don't Mock Me said the Dummy Object</title>
      <description>&lt;p&gt;Martin Fowler posted a short entry on his bliki titled, &lt;a href="http://martinfowler.com/bliki/TestDouble.html"&gt;TestDouble&lt;/a&gt; where he mentioned &lt;a href="http://tap.testautomationpatterns.com:8080/Book%20Outline.html"&gt;Gerard Meszaros&amp;#8217; book&lt;/a&gt;  which is a collection of patterns for Xunit frameworks. Martin then describes how Gerard has encountered a lot of confusion over similar names for testing objects (stubs, mocks, fakes, dummies,...) in different frameworks and has provided a nice description of each to help you differentiate between them.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://martinfowler.com/bliki/TestDouble.html"&gt;Read more&amp;#8230;&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 18 Jan 2006 09:11:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:138f2b0c4d3f06771e88480d6022d5cc</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/01/18/dont-mock-me-said-the-dummy-object</link>
      <category>testing</category>
      <category>martinfowler</category>
    </item>
  </channel>
</rss>
