<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SmartLogic Solutions Blog &#187; Testing</title>
	<atom:link href="http://blog.smartlogicsolutions.com/category/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smartlogicsolutions.com</link>
	<description>News and updates from the people at SmartLogic Solutions</description>
	<lastBuildDate>Tue, 30 Nov 2010 21:39:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Testing AJAX with Test::Unit</title>
		<link>http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/</link>
		<comments>http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 19:58:17 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=979</guid>
		<description><![CDATA[If you want real end-to-end testing of a page with functioning AJAX, use Selenium. But I was interested in doing just a bit of JS speccing to make sure that the AJAX routes I called worked and that the data that came back fit the JS that I had written. So, I figured with a [...]]]></description>
			<content:encoded><![CDATA[<p>If you want real end-to-end testing of a page with functioning AJAX, use Selenium. But I was interested in doing just a bit of JS speccing to make sure that the AJAX routes I called worked and that the data that came back fit the JS that I had written.</p>
<p>So, I figured with a little <a href="http://github.com/jnicklas/capybara">capybara</a> and a little <a href="http://github.com/cowboyd/therubyracer">therubyracer</a>, I could test my javascript with real route calls. Let&#8217;s check it out.<br />
<span id="more-979"></span></p>
<p>The Javascript I want to test:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> dataObject <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> getRemoteData <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/remote_path.json'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    dataObject <span style="color: #339933;">=</span> $.<span style="color: #660066;">parseJSON</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We will pretend that hitting /remote_path.json returns the following response in JSON:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">&quot;my_information&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;my response data&quot;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>I want to test:</p>
<ol>
<li>That /remote_path.json is accessible and returns information</li>
<li>That dataObject is populated with a Javascript Object containing the params I pass down</li>
</ol>
<p>Here is my commented testing code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  test <span style="color:#996600;">'get some information via ajax'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#008000; font-style:italic;"># Create a new JS Context. :with =&gt; self means that</span>
    <span style="color:#008000; font-style:italic;"># the global namespace is the current context</span>
    js = <span style="color:#6666ff; font-weight:bold;">V8::Context</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:with</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Load up our JS file</span>
    js.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>Rails.<span style="color:#9900CC;">root</span>, <span style="color:#996600;">'public'</span>, <span style="color:#996600;">'javascripts'</span>, <span style="color:#996600;">'application.js'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Define a mock method for getting JSON data</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> getJSON<span style="color:#006600; font-weight:bold;">&#40;</span>url, callback<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># When the JS wants some data, get it for real w/ capybara</span>
      visit url
      <span style="color:#008000; font-style:italic;"># And call the JS function passed in (ruby =&gt; js)</span>
      callback.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>page.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    js.<span style="color:#CC0066; font-weight:bold;">eval</span> <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#006600; font-weight:bold;">/*</span> Mock out jQuery <span style="color:#006600; font-weight:bold;">*/</span>
      var $ = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>;
&nbsp;
      <span style="color:#006600; font-weight:bold;">/*</span> Setup the mock <span style="color:#9966CC; font-weight:bold;">in</span> the right place <span style="color:#006600; font-weight:bold;">&#40;</span>JS <span style="color:#006600; font-weight:bold;">=&gt;</span> ruby<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*/</span>
      $.<span style="color:#9900CC;">getJSON</span> = getJSON; 
&nbsp;
      <span style="color:#006600; font-weight:bold;">/*</span> Mock out jquery parseJSON to call ruby JSON.<span style="color:#9900CC;">parse</span>
         Since the args are the same, it is plug <span style="color:#9966CC; font-weight:bold;">and</span> play!
         <span style="color:#006600; font-weight:bold;">&#40;</span>JS <span style="color:#006600; font-weight:bold;">=&gt;</span> ruby<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*/</span>
      $.<span style="color:#9900CC;">parseJSON</span> = JSON.<span style="color:#9900CC;">parse</span>;
&nbsp;
      <span style="color:#006600; font-weight:bold;">/*</span> Trigger our JS <span style="color:#006600; font-weight:bold;">*/</span>
      getRemoteData<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;
&nbsp;
      <span style="color:#006600; font-weight:bold;">/*</span> Assert what we expect <span style="color:#006600; font-weight:bold;">&#40;</span>JS <span style="color:#006600; font-weight:bold;">=&gt;</span> ruby<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*/</span>
      assert_equal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span>, dataObject.<span style="color:#9900CC;">access_key</span><span style="color:#006600; font-weight:bold;">&#41;</span>;
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This is not an example of an incredibly useful test, but I found the ability to bind back and forth easily between ruby and javascript to be <strong>mind-blowingly incredible</strong>. I mean, look at that last line, where I call assert and pass a javascript object to it!</p>
<p>Huge thanks to <strong><a href="http://github.com/cowboyd">Charles Lowell (cowboyd)</a></strong> for his hard work on <a href="http://github.com/cowboyd/therubyracer">therubyracer</a>.</p>
<p>Enjoy the weekend! </p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/26/testpilot-rails-integration-testing-pattern/" rel="bookmark" class="crp_title">TestPilot &#8211; Rails Integration Testing Pattern</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/20/google-ajax-libraries-on-rails/" rel="bookmark" class="crp_title">Google AJAX Libraries on Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/08/using-active-x-and-javascript-to-scan-from-your-web-app/" rel="bookmark" class="crp_title">using active x and javascript to scan from your web app</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/15/using-swfobject-to-seamlessly-upgrade-to-flash-player-10/" rel="bookmark" class="crp_title">Using SWFObject to Seamlessly Upgrade to Flash Player 10</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Timecop 0.3.4 Released</title>
		<link>http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 21:39:06 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TATFT]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[rubygem]]></category>
		<category><![CDATA[tatft]]></category>
		<category><![CDATA[timecop]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=794</guid>
		<description><![CDATA[Timecop 0.3.4 has just been released. To install simply run: gem install timecop. Timecop is a RubyGem providing &#8220;time travel&#8221; and &#8220;time freezing&#8221; capabilities, making it dead simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call. Documentation is hosted at RubyForge. The source code [...]]]></description>
			<content:encoded><![CDATA[<p>Timecop 0.3.4 has just been released.  To install simply run: <code>gem install timecop</code>.</p>
<p>Timecop is a RubyGem providing &#8220;time travel&#8221; and &#8220;time freezing&#8221; capabilities, making it dead simple to test time-dependent code.  It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call.</p>
<p>Documentation is hosted at <a href="http://johntrupiano.rubyforge.org/timecop/">RubyForge</a>.  The source code is hosted at <a href="http://github.com/jtrupiano/timecop">GitHub</a>.</p>
<p>Updates include:</p>
<p><span id="more-794"></span></p>
<p><strong>Maintenance</strong></p>
<ul>
<li>Fix various timezone-related issues.  Notably, when traveling to a DateTime<br />
    instance specified in a non-local timezone, convert provided DateTime<br />
    instance to a local instance and return that from DateTime.now.<br />
    Code contributed by Michaël Witrant [<a href="http://github.com/piglop">piglop</a>]
</li>
<li>Fix bug that would not allow Timecop to be used when Ruby&#8217;s &#8216;date&#8217;<br />
    library had not been previously loaded.<br />
    Code contributed by Tuomas Kareinen [<a href="http://github.com/tuomas">tuomas</a>]
</li>
<li>Fix bug when traveling to a DateTime across a DST boundary that<br />
    resulted in DateTime&#8217;s being off by an hour.
</li>
<li>Migrate argument parsing into Timecop::TimeStackItem to reduce the<br />
    responsibility of the Timecop class.
</li>
</ul>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/" rel="bookmark" class="crp_title">Timecop 0.3.0 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/" rel="bookmark" class="crp_title">Timecop 0.2.0 Released: Freeze and Rebase Time in Ruby</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/05/13/rack-rewrite-1-0-0-released/" rel="bookmark" class="crp_title">Rack::Rewrite 1.0.0 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/01/06/rack-rewrite-0-2-1-released/" rel="bookmark" class="crp_title">Rack::Rewrite 0.2.1 Released</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Timecop 0.3.0 Released</title>
		<link>http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 03:27:34 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TATFT]]></category>
		<category><![CDATA[rubygem]]></category>
		<category><![CDATA[tatft]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[timecop]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=704</guid>
		<description><![CDATA[Timecop 0.3.0 has just been released. To install simply run: gem install timecop. Timecop is a RubyGem providing &#8220;time travel&#8221; and &#8220;time freezing&#8221; capabilities, making it dead simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call. Documentation is on RubyForge. The source code is [...]]]></description>
			<content:encoded><![CDATA[<p>Timecop 0.3.0 has just been released.  To install simply run: <code>gem install timecop</code>.</p>
<p>Timecop is a RubyGem providing &#8220;time travel&#8221; and &#8220;time freezing&#8221; capabilities, making it dead simple to test time-dependent code.  It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call.</p>
<p>Documentation is on <a href="http://johntrupiano.rubyforge.org/timecop/">RubyForge</a>.  The source code is hosted at <a href="http://github.com/jtrupiano/timecop">GitHub</a>.</p>
<p>Updates include:</p>
<p><strong>API</strong></p>
<ul>
<li>Completely remove Timecop#unset_all (deprecated by Timecop#return in 0.2.0)</li>
<li>Return Time.now from #freeze, #travel and #return  &#8212; code contributed by Keith Bennett (<a href="http://github.com/keithrbennett">keithrbennett</a>)</li>
</ul>
<p><strong>Maintenance</strong></p>
<ul>
<li>Fix bug that left Time#mock_time set in some instances</li>
<li>Upped build dependency to jeweler ~> 1.2.1</li>
<li>Don&#8217;t pollute top-level namespace with classes/constants</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li>Clearer examples in the README, better description in the gemspec</li>
<li>Improve RDoc</li>
</ul>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/" rel="bookmark" class="crp_title">Timecop 0.3.4 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/" rel="bookmark" class="crp_title">Timecop 0.2.0 Released: Freeze and Rebase Time in Ruby</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/01/06/rack-rewrite-0-2-1-released/" rel="bookmark" class="crp_title">Rack::Rewrite 0.2.1 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/05/13/rack-rewrite-1-0-0-released/" rel="bookmark" class="crp_title">Rack::Rewrite 1.0.0 Released</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Sanitize Email to Preview HTML Emails Locally</title>
		<link>http://blog.smartlogicsolutions.com/2009/04/30/using-sanitize-email-to-preview-html-emails-locally/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/04/30/using-sanitize-email-to-preview-html-emails-locally/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 13:26:04 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[ActionMailer]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=605</guid>
		<description><![CDATA[John Trupiano has a great post to get you started with sanitize_email for Ruby on Rails. I wanted to preview my HTML emails without having to fill up my online email inboxes with tons of email (and then I&#8217;d have to make filters too). I also didn&#8217;t want to manage actually sending real email. So, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.smartlogicsolutions.com/wiki/John_Trupiano">John Trupiano</a> has <a href="http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/">a great post</a> to get you started with <a href="http://github.com/jtrupiano/sanitize_email/tree/master">sanitize_email</a> for Ruby on Rails.</p>
<p>I wanted to preview my HTML emails without having to fill up my online email inboxes with tons of email (and then I&#8217;d have to make filters too). I also didn&#8217;t want to manage actually sending real email. So, I set up my machine for local delivery. Read on for instructions.<br />
<span id="more-605"></span><br />
I am running Ubuntu 9.04, however these instructions should be fine at least back to 8.04.</p>
<h3>Step 1 &#8211; Install Postfix</h3>
<p><code>sudo aptitude install postfix</code></p>
<p>During the install, choose &#8220;Local Delivery Only&#8221;</p>
<h3>Step 2 &#8211; Configure Evolution for Receiving Locally</h3>
<p>Open up Evolution &#8220;Applications->Internet->Evolution Mail&#8221;</p>
<p>Set up a new account and choose local delivery. When it asks you for a path, put in:</p>
<p><code>/var/mail/&lt;username&gt;</code></p>
<p>Note that this path may not exist if you&#8217;ve never received mail.</p>
<h3>Step 3 &#8211; Configure Sanitize Email</h3>
<p>In your rails test environment.rb put:</p>
<p><code>config.action_mailer.delivery_method = :sendmail</code></p>
<p>Then, in the initializer where you set up sanitize email:</p>
<p><code>ActionMailer::Base.sanitized_recipients = ["<username>@<hostname>"]<br />
ActionMailer::Base.local_environments = %w( test )</code></p>
<p>If you need to know your username or hostname, just open up a terminal. The command &#8220;whoami&#8221; will give you your username, and &#8220;hostname&#8221; will give you the hostname.</p>
<h3>Step 4 &#8211; Run your tests</h3>
<p>Now, run your rails tests. You <em>should</em> have a test for every email you send, and that should trigger them to be sent locally. You may have to tell Evolution to Send/Receive. Keep in mind your tests will probably fail because they will expect email to be in test mode.</p>
<h3>Step 5 &#8211; Set it back</h3>
<p>Remember, when you&#8217;re done previewing your email, reset config.action_mailer.delivery_method!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/" rel="bookmark" class="crp_title">Reintroducing sanitize_email | Work with Production Email without Fear</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/02/better-setup-for-environments-in-rails/" rel="bookmark" class="crp_title">Better setup for environments in Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/" rel="bookmark" class="crp_title">Setting Up Ubuntu 9.10 for Ruby On Rails Development</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/26/integrity-ci-on-passenger-222-with-ruby-enterprise-edition-on-ubuntu-804/" rel="bookmark" class="crp_title">Integrity CI on Passenger 2.2.2 with Ruby Enterprise Edition on Ubuntu 8.04</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/" rel="bookmark" class="crp_title">Benchmark Ruby Code with R, rsruby and better-benchmark</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/04/30/using-sanitize-email-to-preview-html-emails-locally/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Slow Actions in Rails Projects</title>
		<link>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 20:08:34 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[Benchmarking]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=565</guid>
		<description><![CDATA[MySQL&#8217;s slow query log is a very handy tool to detect which SQL queries are running slowly in a production app. So what about rails applications? Often, test data only contains a small amount of data. Over time more users use the site and generate more data. A page that usually renders in 100ms could [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html">MySQL&#8217;s slow query log</a> is a very handy tool to detect which SQL queries are running slowly in a production app.</p>
<p>So what about rails applications? Often, test data only contains a small amount of data. Over time more users use the site and generate more data. A page that usually renders in 100ms could be taking 3-5 seconds, or more!</p>
<p>I present, <a href="http://github.com/ngauthier/slow-actions/tree/master">SlowActions</a>. The goal was to analyze a standard log file to detect actions that render slowly. It had to be easy to use and also not require modification of rails&#8217; logging mechanism. Observe:</p>
<pre>  $> slow-actions --actions development.log
             Cost    Average Max
  - UsersController : game_history (22 entries, 0% Error)
    Total:   11275.447 3642.437 12728.0
    Render:  7.20300 2.32700 17.2450
    DB:      10.5020 3.39200 10.0000

  - QuestionsController : refresh_index_table (89 entries, 0% Error)
    Total:   908.494 202.348 307.000
    Render:  0.00000 0.00000 0.00000
    DB:      32.5880 7.25800 10.0000
</pre>
<p>More info after the break &#8230;.<br />
<span id="more-565"></span></p>
<p>So, what are we looking at? These are the top two (because I cut off the rest) results for looking at all the log entries times sorted by their Cost. The first line is the Controller followed by the Action. In parenthesis is the number of entries in the log file and the percent of those entries that had an error.</p>
<p>The second line is the total time from request to the data being sent to the user. There is a column for Cost, Avg, and Max. Max is the maximum time this action ever took. Avg is the average amount of time the action took (not counting errors). Cost = Avg * Math.Log(# entries).</p>
<p>The Cost can be thought of as that action&#8217;s share of the slowness of the site. An action that is only run once a month and takes 5 seconds is not as bad as an action run 200 times per day that takes 1 second. The Log helps smooth things out a bit.</p>
<p>There are a bunch of filters that you can put on the command:</p>
<pre>$> slow-actions (--actions | --controllers | --sessions) log_file [log_file ...]
    You may also specify:
      --min-cost=FLOAT
      --min-avg=FLOAT
      --min-max=FLOAT
      --start-date=YYYY-MM-DD
      --end-date=YYYY-MM-DD
</pre>
<p>You can choose to output the actions and/or controllers (in a tree format) and/or the session ids (to see which users have it the worst, this is great to find out what is causing a slow action). You can also specify multiple log files, in case you rotate your logs.</p>
<p>You can choose a cutoff cost/avg/max, which means that you could make nice short little emails to yourself every night from your app.</p>
<p>You can also specify a date range, because after you fix a bug, you want to see what kind of effect it had.</p>
<p>I took care to put in some basic RDoc to help people use slow-actions in their own tests or tasks. For example, you could run this in irb:</p>
<pre>require 'rubygems'
require 'slow_actions'
@sa = SlowActions.new
@sa.parse_file('/path/to/my/log')
puts @sa.print_actions</pre>
<p>Have I convinced you? Then get <a href="http://github.com/ngauthier/slow-actions/tree/master">SlowActions</a> off GitHub and download it and run it on your app, you&#8217;ll be surprised!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/05/04/find-the-unique-sessions-for-a-rails-application/" rel="bookmark" class="crp_title">Find the Unique Sessions for a Rails Application</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/problems-with-restful_authentication-plugin-and-internet-explorer-cookies/" rel="bookmark" class="crp_title">Problems with restful_authentication Plugin and Internet Explorer Cookies</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/12/watch-multiple-logs-in-a-single-terminal/" rel="bookmark" class="crp_title">Watch Multiple Logs in a Single Terminal</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/09/07/nicks-highlights-from-ruby-hoedown/" rel="bookmark" class="crp_title">Nick&#8217;s Highlights from Ruby Hoedown</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/06/deploying-rails-apps-with-capistrano-without-root-or-sudo-privileges/" rel="bookmark" class="crp_title">Deploying Rails Apps with Capistrano without root or sudo Privileges</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TATFT: Test Private Methods in C++</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/16/tatft-test-private-methods-in-c/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/16/tatft-test-private-methods-in-c/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 00:46:43 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[TATFT]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=521</guid>
		<description><![CDATA[It&#8217;s very rare that I do any C++ programming these days. However, one of my oldest customers continues to utilize a C++-based optimization/statistics framework that we helped them build many years ago. The project has a wonderful purpose, and we owe quite a bit to some of the first people to trust us (thank you [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s very rare that I do any C++ programming these days.  However, one of my oldest customers continues to utilize a C++-based optimization/statistics framework that we helped them build many years ago.  The project has a <a href="http://jama.ama-assn.org/cgi/content/abstract/293/15/1883">wonderful purpose</a>, and we owe quite a bit to some of the first people to trust us (thank you Sommer and Dorry!).</p>
<p>As a Ruby programmer, I&#8217;ve come to love test-driven programming.  As such, I&#8217;ve made an effort recently to build a test-based workflow into this existing codebase (not always the easiest thing to do, applying a test-base to a large existing codebase).  Today I found myself in dire need of being able to test private functions in C++.  As a testament to the poor state of testing in other programming languages, many message boards/threads simply told me that I was testing the wrong thing (you should test the public API, not the private implementation).  Well, needless to say, this left me a bit uncomfortable.  The fact is, the majority of my code is tucked into private methods, and I&#8217;d be left with huge long-running end-to-end tests if I strictly followed this heuristic.</p>
<p>However, I came across one golden nugget, one of the most clever hacks I&#8217;ve seen in some time.  By utilizing pre-processor directives, we can temporarily override the meaning of private and protected in C++ code, essentially aliasing it to public.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"> <span style="color: #339900;">#define protected public</span>
 <span style="color: #339900;">#define private   public</span>
 <span style="color: #339900;">#include &quot;TheClassHeaderUnderTest.h&quot;</span>
 <span style="color: #339900;">#undef protected</span>
 <span style="color: #339900;">#undef private</span></pre></div></div>

<p>See what this is doing?  We wrap the class that we&#8217;ll be testing in pre-processor directives to interpret protected and private as an alias for public, essentially loading that class (when including the header file) as entirely public.  This allows me to access everything!  Private methods, private variables, you name it.  And now, just like in Ruby, it&#8217;s no holds barred, allowing me to poke and prod my objects without being wrapped on the wrist by the compiler.</p>
<p>Even better, these directives simply wrap your includes in your test files.  In other words, I don&#8217;t have to change my implementation to achieve this.</p>
<p>A clever hack, no matter the language or technology, is a clever hack.  And I absolutely love this hack.</p>
<p><strong>Credit</strong>: I discovered this technique as a comment on <a href="http://c2.com/cgi/wiki?ExtremeProgrammingTestingPrivateMethods">this wiki</a>.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/07/16/creating-custom-layout-in-flex-4-gumbo/" rel="bookmark" class="crp_title">Creating a Custom Layout Class in Flex 4</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/19/creating-custom-flex-4-skinnable-component/" rel="bookmark" class="crp_title">Creating Your First Custom SkinnableComponent in Flex 4</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/27/serialization-errorbug-when-using-bytearray-readobject-iexternalizable-class/" rel="bookmark" class="crp_title">Serialization Error/Bug When Using a ByteArray and readObject in an IExternalizable Class?</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/" rel="bookmark" class="crp_title">Testing AJAX with Test::Unit</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/16/tatft-test-private-methods-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Properly Setting HTTP_REFERER in a Rails Integration Test for a File Upload</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 00:38:01 +0000</pubDate>
		<dc:creator>Greg Jastrab</dc:creator>
				<category><![CDATA[Greg Jastrab]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=495</guid>
		<description><![CDATA[This one had me frustrated for the past hour. I&#8217;ve been writing integration tests for a Rails project and got stuck on an error when I was trying to test that a file upload worked successfully and asserted a redirection was occuring correctly, but ran into the following error: Expected response to be a &#60;:redirect&#62;, [...]]]></description>
			<content:encoded><![CDATA[<p>This one had me frustrated for the past hour.  I&#8217;ve been writing integration tests for a Rails project and got stuck on an error when I was trying to test that a file upload worked successfully and asserted a redirection was occuring correctly, but ran into the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Expected response to be a <span style="color:#006600; font-weight:bold;">&lt;</span>:redirect<span style="color:#006600; font-weight:bold;">&gt;</span>, but was <span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">500</span><span style="color:#006600; font-weight:bold;">&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#996600;">&quot;No HTTP_REFERER was set in the request to this action, so
redirect_to :back could not be called successfully. If this
is a test, make sure to specify
request.env[<span style="color:#000099;">\&quot;</span>HTTP_REFERER<span style="color:#000099;">\&quot;</span>].&quot;</span><span style="color:#006600; font-weight:bold;">&gt;</span></pre></div></div>

<p>What a lovely error message to send me on a goose chase trying to set HTTP_REFERER directly on the @request as instructed.</p>
<h4>Did Not Work</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@request</span>.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;HTTP_REFERER&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'/'</span>
post upload_path, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:file</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fixture_file_upload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;worddoc.docx&quot;</span>, <span style="color:#996600;">&quot;application/msword&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:multipart <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
assert_redirected_to <span style="color:#996600;">'/'</span>, <span style="color:#996600;">'index'</span></pre></div></div>

<p>This continued to spit out the same error.  I finally stumbled across <a href="http://redsquirrel.com/cgi-bin/dave/2006/08/index.html">a post back from 2006</a> that held the answer.  The HTTP_REFERER is not set the same way in an integration test:</p>
<h4>Success!</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">post upload_path, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:file</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fixture_file_upload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;worddoc.docx&quot;</span>, <span style="color:#996600;">&quot;application/msword&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:multipart <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:referer</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/'</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
assert_redirected_to <span style="color:#996600;">'/'</span>, <span style="color:#996600;">'index'</span></pre></div></div>

<p>Hope that saves anyone else some time if you encounter this error.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2007/06/12/struts-11-problems-with-logiciterate-tags-and-cannot-find-bean-xxx-under-any-scope/" rel="bookmark" class="crp_title">Struts 1.1: Problems with logic:iterate tags and &#8220;Cannot find bean XXX under any scope&#8221;</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/08/using-active-x-and-javascript-to-scan-from-your-web-app/" rel="bookmark" class="crp_title">using active x and javascript to scan from your web app</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/23/dont-abuse-the-session/" rel="bookmark" class="crp_title">Don&#8217;t Abuse the Session</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/26/testpilot-rails-integration-testing-pattern/" rel="bookmark" class="crp_title">TestPilot &#8211; Rails Integration Testing Pattern</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/15/automating-flex-compilation-using-ant/" rel="bookmark" class="crp_title">Automating Flex Compilation Using ANT</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Timecop 0.2.0 Released: Freeze and Rebase Time in Ruby</title>
		<link>http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/#comments</comments>
		<pubDate>Wed, 24 Dec 2008 06:14:35 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TATFT]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[jtrupiano]]></category>
		<category><![CDATA[rubygem]]></category>
		<category><![CDATA[tatft]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[timecop]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=445</guid>
		<description><![CDATA[I just released version 0.2.0 of Timecop this evening (morning). The primary feature added was the distinction between &#8220;freezing&#8221; and &#8220;rebasing&#8221; time. In 0.1.0, Timecop.travel would actually freeze time. This is no longer the case. Rather, a time offset will be calculated, and a running clock is simulated by always offsetting the time returned by [...]]]></description>
			<content:encoded><![CDATA[<p>I just released version 0.2.0 of <a href="http://github.com/jtrupiano/timecop">Timecop</a> this evening (morning).</p>
<p>The primary feature added was the distinction between &#8220;freezing&#8221; and &#8220;rebasing&#8221; time.  In 0.1.0, <code>Timecop.travel</code> would actually freeze time.  This is no longer the case.  Rather, a time offset will be calculated, and a running clock is simulated by always offsetting the time returned by Time.now (and friends) by the original offset.</p>
<p>(Note that time can still be frozen with <code>Timecop.freeze</code>.)</p>
<p><span id="more-445"></span></p>
<p>To update a previous version:</p>
<pre><code>sudo gem update timecop</code></pre>
<p>To install for the first time: </p>
<pre><code>sudo gem install timecop</code></pre>
<p>The new feature set allows us to avoid the following common pitfalls that were present in 0.1.0. </p>
<ol>
<li>In rails, if you had set up a time mock in the development environment, then every time you invoked <code>script/generate migration</code> (and others), the generator would read your mocked instance of Time.now, and use that date for the migration name.</li>
<li>Any benchmarking/timing code executed within the yielded block would always return times of 0 seconds.  This was due to time being frozen.</li>
</ol>
<p>The other major change to the API was the deprecating of Timecop.unset_all in favor or Timecop.return.</p>
<p>This update also vastly <a href="http://johntrupiano.rubyforge.org/timecop">improves the rdoc</a>, making the public API much more accessible.  The Timecop class has particularly thorough documentation.</p>
<p>For a more complete description of the gem, please refer to the <a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/">introductory blog post</a>.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/" rel="bookmark" class="crp_title">Timecop 0.3.0 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/" rel="bookmark" class="crp_title">Timecop 0.3.4 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/05/13/directory-conventions-for-rack-middleware-rubygems/" rel="bookmark" class="crp_title">Directory Conventions for Rack Middleware RubyGems</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/12/18/puremvcgen-011-released-now-works-on-windows/" rel="bookmark" class="crp_title">PureMVCGen 0.1.1 Released &#8211; Now Works on Windows</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Timecop: Freeze Time in Ruby for Better Testing</title>
		<link>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 15:07:44 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tatft]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[timecop]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=360</guid>
		<description><![CDATA[The API mentioned in this blog post is specific to v0.1.0. The latest version is v0.2.0. See the blog post announcement, the documentation, or the github home page. This past weekend I released v0.1.0 of the Timecop gem. Timecop makes it dead simple to travel through or freeze time for the sake of creating a [...]]]></description>
			<content:encoded><![CDATA[<div style="background-color: #e0e0e0; border-color: #999999; padding: 6px;">
The API mentioned in this blog post is specific to v0.1.0.  The latest version is v0.2.0.  See the <a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/">blog post announcement</a>, the <a href="http://johntrupiano.rubyforge.org/timecop">documentation</a>, or the <a href="http://github.com/jtrupiano/timecop">github home page</a>.
</div>
<p>This past weekend I released v0.1.0 of the <a href="http://github.com/jtrupiano/timecop">Timecop</a> gem.  Timecop makes it dead simple to travel through or freeze time for the sake of creating a predictable and ultimately testable scenario.</p>
<p>The gem is derived from a plugin I wrote a while back to achieve more or less the same functionality for an extremely time-sensitive application.  My goals for the gem included:</p>
<ol>
<li><strong>Drop-in-ability</strong>: The primary goal is to allow your app to continue to use Time.now, Date.today and DateTime.now as normal within your application.  No overloading of functions with optional arguments (a la today=Date.today) just so you can write test cases.</li>
<li><strong>Environment independence</strong>: I wanted the gem to work (a) w/ rails (ActiveSupport actually), (b) w/ plain ruby when the &#8216;date&#8217; library has been loaded, and (c) w/ plain ruby when the &#8216;date&#8217; library had not been loaded.</li>
<li><strong>Library independence</strong>: I could have utilized mocha to achieve the mocking functionality found under the hood, but because I wanted this to work with plain vanilla ruby, libraries like mocha are out.</li>
<li><strong>Short-term time travel</strong>: I wanted to expose the ability to temporarily change the concept of &#8220;now.&#8221;  This is particularly helpful when writing tests where time needs to pass.</li>
<li><strong>Long-range time travel</strong>: I wanted to expose the ability to change the concept of &#8220;now&#8221; for an indeterminate period of time.  This is particularly helpful when setting up a rails test environment along with the test data.</li>
<li><strong>Nested time travel</strong>: I wanted to provide the ability to nest traveling, allowing the state to be kept within each block (we&#8217;ll see an example later).</li>
</ol>
<p>The gem is hosted on RubyForge and can be installed by simply running:</p>
<pre>sudo gem install timecop</pre>
<p><span id="more-360"></span></p>
<h2>Using Timecop</h2>
<p>The most basic example is to utilize this within a test.  Consider the following test case:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'timecop'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'test/unit'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> MyTestCase <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span></span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_mortgage_due_in_30_days
    john = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    john.<span style="color:#9900CC;">sign_mortgage</span>!
    assert !john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">30</span>.<span style="color:#9900CC;">days</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      assert john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>What&#8217;s nice about this API is that the #travel function will take several different object types.  You can pass a Time instance, a Date instance, a DateTime instance, or individual time parameters (the same arguments Time.local()) takes.  Also, if you&#8217;re a big fan of the <a href="http://chronic.rubyforge.org/">chronic</a> gem, then you can easily combine these two:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span>Chronic.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'this tuesday 5:00'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># test-fu</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For some applications, you may find it useful to completely re-base the concept of &#8220;now&#8221; for your test environment.  Whenever time-sensitivity is a major priority for your application (e.g. an ordering and delivery system, or any system that encapsulates the concept of &#8220;availability&#8221; at a particularly fine-grained level) , you may find it useful to &#8220;root&#8221; your test data at a particular point in time, allowing you to write very specific tests that don&#8217;t fall victim to the unstoppable march of real time.</p>
<p>To achieve a static date for your entire test environment, you can simply drop the following into config/environments/test.rb (or config/test/environment.rb if you use <a href="http://github.com/jtrupiano/environmentalist">environmentalist</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Setting &quot;now&quot; to May 15, 2008 10:00:00 AM</span>
Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">5</span>, <span style="color:#006666;">15</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">0</span>, <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>This will cause your whole application to run at a static time.  As mentioned previously, this is particularly important for creating static test cases.  You may think that you can achieve this by always using relative times, but this proves much more difficult than initially perceived.  For example, let&#8217;s consider the following scenario, which is an extension of the mortgage example beforehand.  Let&#8217;s say the business rule is that a mortgage payment is due every month on the same date as the lease is signed, except for when that day falls on a weekend, in which case the payment would be due the following Monday.  As such, it&#8217;s extremely crucial for us to write a test case where we know the date in the next month falls on a weekend, and a separate test case where the date in the next month falls on a weekday.  As such, there are certain months where the following test (not using Timecop) would fail:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'test/unit'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> MyTestCase <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span></span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_mortgage_due_in_30_days
    john = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    john.<span style="color:#9900CC;">sign_mortgage</span>!
    assert !john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    assert john.<span style="color:#9900CC;">mortgage_payment_due</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Chronic.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;1 month from now&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Furthermore, you&#8217;ll notice I had to pass a date to the mortgage_payment_due? function, essentially requiring me to change the signature of that function to take an optional date argument.  Basically, in order to test my application, I&#8217;ve had to go ahead and change my actual code!  Something clearly smells here.  Another option would be to use mocha to mock Time.now.  However, mocha has its own limitations with its inability to unmock.  Lastly, specifically mocking Time.now would leave us high and dry if our implementation decided to start using DateTime.now for comparison in lieu of Time.now.</p>
<p>Another feature that I want to illustrate is the ability to nest #travel commands.  The following assertions will all pass:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">   <span style="color:#008000; font-style:italic;"># this test is taken directly from the test/test_timecop.rb</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_recursive_travel
    t = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
      assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      t2 = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        assert_equal t2, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    assert_nil <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:mock_time</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lastly, Timecop handles the scenario where exceptions are raised within the blocks passed to the #travel function.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># this test is taken directly from the test/test_timecop.rb</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_exception_thrown_in_travel_block_properly_resets_time
    t = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span>t<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
        <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;blah exception&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span>
      assert_not_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      assert_nil <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:mock_time</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Timecop is useful both in small and large consumption.  Just as mocha can be helpful to give you a quick mock here and there, Timecop can help guide you very easily through testing the few time-sensitive parts of your application.  And for those unique applications where everything is time-sensitive, Timecop gives you a very simple way to stabilize your concept of now.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/" rel="bookmark" class="crp_title">Timecop 0.3.0 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/" rel="bookmark" class="crp_title">Timecop 0.3.4 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/" rel="bookmark" class="crp_title">Timecop 0.2.0 Released: Freeze and Rebase Time in Ruby</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/" rel="bookmark" class="crp_title">Testing AJAX with Test::Unit</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/07/i-cant-upgrade-rubygems-from-111-to-120-on-ubuntu/" rel="bookmark" class="crp_title">I can&#8217;t upgrade RubyGems from 1.1.1 to 1.2.0 on Ubuntu</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Benchmark Ruby Code with R, rsruby and better-benchmark</title>
		<link>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 16:53:38 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[Benchmarking]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[mac osx]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[rsruby]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=275</guid>
		<description><![CDATA[I&#8217;ve found myself on a benchmarking kick these last couple of weeks. Sometime last week, I dug up the better-benchmark library written by Pistos. Pistos&#8217; library is basically just a wrapper for the rsruby gem, which is more or less an interface to R (similar to what rmagick is to ImageMagick). Combining these tools together, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found myself on a benchmarking kick these last couple of weeks.  Sometime last week, I dug up the <a href="http://github.com/Pistos/better-benchmark/tree/master">better-benchmark</a> library written by <a href="http://github.com/Pistos">Pistos</a>.  Pistos&#8217; library is basically just a wrapper for the <a href="http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/">rsruby gem</a>, which is more or less an interface to <a href="http://www.r-project.org/">R</a> (similar to what <a href="http://rmagick.rubyforge.org/">rmagick</a> is to <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a>).</p>
<p>Combining these tools together, we can do some pretty nifty code performance analysis in very few lines of code, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'better-benchmark'</span>
&nbsp;
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  save_the_world<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  save_the_world_and_save_the_girl<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result</pre></div></div>

<p>I have <a href="http://github.com/jtrupiano/better-benchmark/tree/master">forked better-benchmark</a> and wrapped the library up into a <a href="http://www.rubygems.org/">RubyGem</a>.  </p>
<p><span id="more-275"></span></p>
<p>Currently, the gem is available from github:</p>
<pre>
$> sudo gem install jtrupiano-better-benchmark
</pre>
<p>Based on preliminary discussions with Pistos, he intends to merge my changes back into his branch.  I&#8217;ll update this post with the relevant details when that has been completed.</p>
<p>So, let&#8217;s get started by preparing your box for better-benchmark!</p>
<h2>Installing R</h2>
<h3>On Mac OSX</h3>
<p>This one&#8217;s simple.  AT&#038;T Research provides us with a <a href="http://r.research.att.com/">DMG</a>.</p>
<h3>On Ubuntu 8.0.4</h3>
<p>I first built this just fine on a Mac.  But, I decided that I wanted a dedicated VM where I could run some fairly intense benchmarks.  You&#8217;ll need to ensure you have the following apt packages installed:</p>
<p>* build-essential<br />
* g77 (fortran compiler)<br />
* x11-common</p>
<p>There may be a few others that are required, but I started on a pre-built box more or less ready to host rails apps, and so there may be a few other necessities I missed.  The following steps will install R from source on Ubuntu (I was unable to get the necessary R headers installed using apt-get or apititude), and prepare you for installing the rsruby gem.</p>
<pre>
$> sudo apt-get install build-essential g77 x11-common
$> cd /opt
$> wget http://lib.stat.cmu.edu/R/CRAN/src/base/R-2/R-2.7.2.tar.gz
$> tar xzf R-2.7.2.tar.gz
$> cd R-2.7.2
# --enable-R-shlib is important...it signals the installer to build and make available libR.so
$> ./configure --enable-R-shlib
$> make
$> sudo make install
</pre>
<h2>Installing rsruby</h2>
<p>Assuming you installed R fine, rsruby should be easily installed using gem.  If you have trouble, see the <a href="http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/">installation instructions</a> on the project&#8217;s README.</p>
<p>Note that you&#8217;ll need to set the R_HOME environment variable prior to installing the gem.  On Mac, R_HOME=/Library/Frameworks/R.framework/Resources.  On Ubuntu (when installed from source), R_HOME=/usr/local/lib/R.  I find it helpful to just drop this into /etc/environment (on Ubuntu) so that this variable is set upon login.</p>
<pre>
$> export R_HOME=/path/to/R/for/your/OS
$> sudo gem install rsruby -- --with-R-dir=$R_HOME
</pre>
<h2>Installing better-benchmark</h2>
<p>Currently, you can get this directly off of my fork on github.</p>
<pre>
$> gem sources -a http://gems.github.com/
$> sudo gem install jtrupiano-better-benchmark
</pre>
<h2>Great, I have it, now what do I do with it??</h2>
<p>So now we&#8217;re ready to benchmark something.  The most important thing to understand when benchmarking is that you need to clearly identify what is part of the benchmark, and what is not.  Let&#8217;s take a look at a real-world example.  We&#8217;ll go through the following steps:</p>
<ol>
<li><strong>Hypothesize: </strong>define exactly what you&#8217;re looking to test, and take special care to describe what you are NOT testing.</li>
<li><strong>Plan: </strong>write out step by step how you will accomplish your benchmark</li>
<li><strong>Refine: </strong>identify which steps belong in the benchmark, and which are really setup/teardown aspects of the benchmark, and thus shouldn&#8217;t be included in the test.</li>
<li><strong>Test: </strong>run the benchmarks</li>
<li><strong>Rinse/Repeat: </strong>(as necessary) tweak your test parameters, tweak the tests, re-test </li>
</ol>
<h2>Real world example</h2>
<p>I was building a set of services that needed to download tens to hundreds of thousands of feeds regularly and perform some post-processing.  I pulled in the <a href="http://feed-normalizer.rubyforge.org/">feed-normalizer</a> gem.  My implementation plan called for me to write separate services, one for &#8220;pulling down&#8221; the feed, and one for &#8220;processing&#8221; the feed.  </p>
<p>My first approach entailed storing the feeds on the hard-drive as YAML (using the to_yaml function).  After running into <a href="http://blog.smartlogicsolutions.com/2008/09/04/ruby-patch-to-fix-broken-yamldump-for-multi-line-strings-stringto_yaml/">some obscure problems with YAML and multi-line strings</a>, I started to explore alternative persistence formats.  One that caught my attention was using the Marshall standard library to store the content as bytecode.  This brings me to my hypothesis:</p>
<p><strong>1) Hypothesis: </strong>Converting FeedNormalizer::Feed objects to bytecode using the Marshal library is faster than converting those same obejcts to YAML using the YAML library.</p>
<p>I also like to list out my goals at this stage:</p>
<ol>
<li>We only want to test the #dump conversion (object &#8211;> string) and the #read conversion (string &#8211;> object).  We do not want to test the write to disk and the read from disk portions.</li>
<li>We specifically want to test FeedNormalizer::Feed objects, since that&#8217;s what we&#8217;re using in our code.</li>
<li>Let&#8217;s benchmark YAML / Marshal #dump and #read methods specifically on FeedNormalizer::Feed objects</li>
</ol>
<p><strong>2) Plan: </strong> </p>
<ol>
<li>We have already grabbed roughly 100 feed downloads, and they are sitting as raw xml in test/raw_rss.</li>
<li>We&#8217;ll read them in, then benchmark YAML.dump vs. Marshal.dump</li>
<li>Then we&#8217;ll independently benchmark YAML.read vs. Marshal.read</li>
</ol>
<p><strong>3) Refine: </strong><br />
Here&#8217;s where we need to ensure that unnecessary processing doesn&#8217;t make its way into our benchmarks.  For instance, in order to benchmark Marshal#dump against YAML#dump, we&#8217;ll need to load up all of the FeedNormalizer::Feed objects (by reading them from disk and instantiating them) prior to starting the benchmark.</p>
<p><strong>4) Test: </strong><br />
It&#8217;s a ruby script, so go ahead and run it.  The set of options provided by better-benchmark are easily discernible from the <a href="http://github.com/jtrupiano/better-benchmark/tree/master/lib/better-benchmark/better-benchmark.rb">source file</a>.</p>
<p><strong>5) Rinse/Repeat: </strong><br />
Same story as always.</p>
<h2>Real Script Example</h2>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#008000; font-style:italic;"># Author: John Trupiano</span>
<span style="color:#008000; font-style:italic;"># 2008-09-28</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># In order to run this benchmark, you need to have the better-benchmark library installed (http://github.com/Pistos/better-benchmark/tree/master)</span>
<span style="color:#008000; font-style:italic;"># better-benchmark depends on the rsruby gem (http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/)</span>
<span style="color:#008000; font-style:italic;"># rsruby depends on an installation of the computing package R (http://mirrors.ibiblio.org/pub/mirrors/CRAN/)</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># For details on setting up R, rsruby, and better-benchmark, see this blog post: http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># This is intended to be run from RAILS_ROOT, e.g.</span>
<span style="color:#008000; font-style:italic;"># /path/to/rails/root $&gt; ruby test/benchmark/yaml_bytecode_test.rb</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'openssl'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'yaml'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'feed-normalizer'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'lib/rss_parser'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'better-benchmark'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># GOALS </span>
<span style="color:#008000; font-style:italic;"># 1) We only want to test the #dump conversion (object --&gt; string) and the #read conversion (string --&gt; object).  We do not want to test the write to disk and the read from disk portions.</span>
<span style="color:#008000; font-style:italic;"># 2) We specifically want to test FeedNormalizer::Feed objects, since that's what we're using in our code.</span>
<span style="color:#008000; font-style:italic;"># 3) Let's benchmark YAML / Marshal #dump and #read methods specifically on FeedNormalizer objects</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># PLAN</span>
<span style="color:#008000; font-style:italic;"># 1) We've grabbed roughly 100 feed downloads sitting in test/raw_rss.</span>
<span style="color:#008000; font-style:italic;"># 2) We'll read them in, then benchmark YAML.dump vs. Marshal.dump</span>
<span style="color:#008000; font-style:italic;"># 3) Then we'll independently benchmark YAML.read vs. Marshal.read</span>
&nbsp;
fn_feeds = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
root_dir = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;test&quot;</span>, <span style="color:#996600;">&quot;raw_rss&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
feed_ids = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span>..<span style="color:#006666;">62</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_a</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">64</span>..<span style="color:#006666;">108</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_a</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># build a global hash fn_feeds that contains the FeedNormalizer::Feed entries</span>
feed_ids.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id<span style="color:#006600; font-weight:bold;">|</span>
  infile = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>root_dir, feed_id.<span style="color:#9900CC;">to_s</span>, feed_id.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'_dump.rss'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  fn_feeds<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = RssParser.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>infile, <span style="color:#ff3333; font-weight:bold;">:file</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#### BENCHMARK 1 ####</span>
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">25</span>,
  <span style="color:#ff3333; font-weight:bold;">:verbose</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result
&nbsp;
&nbsp;
<span style="color:#008000; font-style:italic;"># now, let's create separate collections storing the dumps</span>
yaml_dumps = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
marshal_dumps = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
fn_feeds.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, feed<span style="color:#006600; font-weight:bold;">|</span>
  yaml_dumps<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
  marshal_dumps<span style="color:#006600; font-weight:bold;">&#91;</span>feed_id<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>feed<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#### BENCHMARK 2 ####</span>
result = <span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">compare_realtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:iterations</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">25</span>,
  <span style="color:#ff3333; font-weight:bold;">:verbose</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  yaml_dumps.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, yaml<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>yaml<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>iteration<span style="color:#006600; font-weight:bold;">|</span>
  marshal_dumps.<span style="color:#9900CC;">each_pair</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>feed_id, marshal<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">Marshal</span>.<span style="color:#9900CC;">dump</span><span style="color:#006600; font-weight:bold;">&#40;</span>marshal<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">report_on</span> result</pre></div></div>

<p>And for good measure, let&#8217;s take a look at the results.</p>
<pre>
john-trupianos-macbook-pro:trunk john$ ruby test/benchmark/yaml_bytecode_test.rb
.........................
Set 1 mean: 2.095 s
Set 1 std dev: 0.071
Set 2 mean: 0.123 s
Set 2 std dev: 0.019
p.value: 1.58214572048972e-14
W: 625.0
The difference (-94.1%) IS statistically significant.
.........................
Set 1 mean: 0.191 s
Set 1 std dev: 0.015
Set 2 mean: 0.022 s
Set 2 std dev: 0.012
p.value: 1.58214572048972e-14
W: 625.0
</pre>
<p>As R plainly tells us, the difference is statistically significant (those who remember their p-values from stats class raise your hands) for both benchmarks (note that I did run two separate benchmarks in this example, one for dumping and one for reading).  That said, considering I don&#8217;t have a need for this data to be human readable on my filesystem, I can safely conclude that using the Marshal library in lieu of the YAML library will give me a performance boost on both the read/dump methods.  Now, whether or not this boost is negligible in the scope of the greater system, well that&#8217;s a question for a separate benchmark.</p>
<p>(What I mean by this last part is that this #dump/#read portion of my whole system may be tiny.  If it only represents 0.5% of the processing time, then the improvement my example shows may be more or less negligible in the context of the whole system.  These are the types of questions you need to ask yourself when benchmarking.)</p>
<p>Primary take-home point:  <strong>know what you&#8217;re benchmarking, and benchmark what you don&#8217;t know</strong>.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/09/04/ruby-patch-to-fix-broken-yamldump-for-multi-line-strings-stringto_yaml/" rel="bookmark" class="crp_title">Ruby: Patch to fix broken YAML.dump for multi-line strings (String#to_yaml)</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/" rel="bookmark" class="crp_title">Setting Up Ubuntu 9.10 for Ruby On Rails Development</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/07/i-cant-upgrade-rubygems-from-111-to-120-on-ubuntu/" rel="bookmark" class="crp_title">I can&#8217;t upgrade RubyGems from 1.1.1 to 1.2.0 on Ubuntu</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/01/14/aptinstaller-032-released/" rel="bookmark" class="crp_title">Aptinstaller 0.3.2 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/06/04/mount-options-to-improve-ext4-file-system-performance/" rel="bookmark" class="crp_title">Mount options to improve ext4 file system performance</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/10/08/benchmark-ruby-code-with-r-rsruby-and-better-benchmark/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

