<?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>Eyefodder &#187; Test Driven Development</title>
	<atom:link href="http://eyefodder.com/category/engineering/test-driven-development/feed" rel="self" type="application/rss+xml" />
	<link>http://eyefodder.com</link>
	<description></description>
	<lastBuildDate>Sat, 26 Aug 2017 21:12:17 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Code Coverage — a simple Rails example</title>
		<link>http://eyefodder.com/2014/09/code-coverage-setup-rails.html</link>
		<comments>http://eyefodder.com/2014/09/code-coverage-setup-rails.html#comments</comments>
		<pubDate>Thu, 18 Sep 2014 13:13:40 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Agile Software Development]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Quality Software]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Craftsmanship]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://eyefodder.com/?p=208</guid>
		<description><![CDATA[<p>My tests are my safety net. With them I can refactor with confidence, knowing that I&#8217;m keeping the functionality I intended. With them, I can grow my codebase, knowing that I&#8217;m not introducing regression errors. How do I have confidence that my safety net is good enough? One metric I can use to help with this [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/code-coverage-setup-rails.html">Code Coverage — a simple Rails example</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>My tests are my safety net. With them I can refactor with confidence, knowing that I&#8217;m keeping the functionality I intended. With them, I can grow my codebase, knowing that I&#8217;m not introducing regression errors. How do I have confidence that my safety net is good enough? One metric I can use to help with this is code coverage. It answers the question “When I run my tests, how much of my application code executed?”. It&#8217;s a somewhat crude metric—telling me how broad the net is not how strong—but it’s a good place to start. Fortunately, setting it up on a rails project is pretty simple.</p>
<div id="attachment_217" style="width: 550px" class="wp-caption alignnone"><a href="http://upload.wikimedia.org/wikipedia/commons/3/35/Group_of_Circus_Performers_WDL10692.png"><img class="size-large wp-image-217" src="http://eyefodder.com/wp-content/uploads/2014/09/Group_of_Circus_Performers_WDL10692-1024x747.png" alt="circus perfomers in a safety net" width="540" height="393" /></a><p class="wp-caption-text">See how happy people are when they have a safety net?</p></div>
<p><span id="more-208"></span></p>
<h2>Getting Started</h2>
<p>I&#8217;ve made a simple example app that shows code coverage in action. Check out the source code from the <code>code_coverage</code> branch of my <a href="https://github.com/eyefodder/spex" target="_blank">spex</a> repository:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">

git clone -b code_coverage --single-branch https://github.com/eyefodder/spex.git

</pre>
<p>Now go to the <code>ops</code> directory and run <code>vagrant up</code> To get the virtual machine running. Next, let&#8217;s hop into the virtual machine and run the test suite:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
vagrant ssh
...some output...
vagrant@spex:~$ cd /app
vagrant@spex:~$ rspec

</pre>
<p>Now, check out the reports folder. You&#8217;ll see that there is a <code>coverage/rcov</code> folder. Open the index file in the browser and you see an easy to digest code coverage report:<br />
<a href="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.08.41-AM.png"><img class="alignnone size-large wp-image-219" src="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.08.41-AM-1024x617.png" alt="code coverage report" width="540" height="325" /></a><br />
Pretty nifty huh? You can click on the rows in the table to see each class in more detail, and find out exactly which lines aren&#8217;t being executed:<br />
<a href="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.15.28-AM.png"><img class="alignnone size-large wp-image-221" src="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.15.28-AM-1024x826.png" alt="code coverage metrics for a single file" width="540" height="435" /></a><br />
Let&#8217;s take a look at how this was all set up&#8230;</p>
<h2>Code Coverage Gems</h2>
<p>First up, we need to add a couple of gems to the <code>Gemfile</code>:</p>
<pre class="brush: ruby; first-line: 59; title: ; notranslate">
  # code_coverage
  gem 'simplecov', :require =&gt; false
  gem 'simplecov-rcov', :require =&gt; false
</pre>
<p>Once we&#8217;ve run a <code>bundle install</code>, our next step is to configure our test suite to generate coverage reports.</p>
<h2>Configuring Code Coverage</h2>
<p>This, again is a pretty simple affair. We need to launch SimpleCov before any application code has run, so we have this code at the top of the <code>spec/spec_helper.rb</code></p>
<pre class="brush: ruby; title: ; notranslate">
if ENV['GENERATE_COVERAGE_REPORTS'] == 'true'
  require 'simplecov'
  require 'simplecov-rcov'
  SimpleCov.start 'rails' do
    coverage_dir ENV['CI_COVERAGE_REPORTS']
  end
  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
end
</pre>
<p>There&#8217;s a few things happening here. We have a couple of environment variables that tell us if we should create reports: <code>GENERATE_COVERAGE_REPORTS</code> and if we do, where we should put them: <code>CI_COVERAGE_REPORTS</code>. If you&#8217;ve followed my earlier post on getting <a title="Getting Growl notifications from your Virtual Machine" href="http://eyefodder.com/2014/09/growl-guard-virtual-machine.html">Guard to send Growl</a> notifications, you will know to find these in <code>ops/dotfiles/guest_bash_profile</code> which is a profile automatically generated when we launch the virtual machine with <code>vagrant up</code>. If not, well, now you do!<br />
The next thing you&#8217;ll notice is the <code>SimpleCov.start 'rails'</code> call on line 4. This configures SimpleCov to have a profile that is good for most Rails applications. For example, the <code>spec</code> and <code>config</code> folders are excluded from coverage stats. You can read more about profiles <a href="https://github.com/colszowka/simplecov#profiles">here</a>.<br />
Finally, we tell SimpleCov that we want to format our results with the <code>SimpleCov::Formatter::RcovFormatter</code>. When we get to running our build as part of a <a href="http://en.wikipedia.org/wiki/Continuous_integration">continuous integration</a> process with <a href="http://jenkins-ci.org/">Jenkins</a>, we can use this format to parse results to be viewed in the dashboard.</p>
<h2>Viewing Code Coverage Reports generated on a Guest VM</h2>
<p>The last thing we have to deal with is the fact that the reports are generated on the guest virtual machine. In our <a title="Using Puppet and Vagrant to make a one-click development environment" href="http://eyefodder.com/2014/08/one-click-development-environment.html">existing setup</a>, we use <code>rsync</code> to push code changes from the host to the virtual machine. But this only works one way, and if we add content within the virtual machine you won&#8217;t see them on the host. We solve this with these lines in the <code>Vagrantfile</code></p>
<pre class="brush: ruby; first-line: 21; title: ; notranslate">
  config.vm.synced_folder '../reports', '/reports'
  config.vm.synced_folder &quot;../&quot;, &quot;/app&quot;, type: &quot;rsync&quot;, rsync__exclude: [&quot;.git/&quot;, &quot;ops/*&quot;, &quot;reports/&quot;, &quot;tmp/&quot;, &quot;log/&quot;, &quot;.#*&quot;]
</pre>
<p>What this does is exclude the <code>reports</code> from the main <code>rsync</code> and instead setup a new (regular) shared folder that will map <code>reports</code> to <code>/reports</code> on the virtual machine (note this is a root level folder, not in the <code>/app</code> folder on the guest. This is why we have used an environment variable to tell SimpleCov where to output reports.</p>
<h2>Beware the emperor&#8217;s new code coverage</h2>
<p><a href="http://commons.wikimedia.org/wiki/File:Page_45_illustration_in_fairy_tales_of_Andersen_(Stratton).png"><img class="alignnone size-large wp-image-222" src="http://eyefodder.com/wp-content/uploads/2014/09/emperors_new_clothes-754x1024.png" alt="emperors_new_clothes" width="540" height="733" /></a></p>
<p>One thing to bear in mind is that code coverage really is a very crude metric. There are different types of coverage metrics, and SimpleCov only provides &#8216;C0&#8242; coverage: lines of code that executed. Other types include <a href="http://www.bignerdranch.com/blog/code-coverage-and-ruby-1-9/" target="_blank">branch and path</a> coverage, but as far as I know, there aren&#8217;t any tools for these in Ruby. Let me show you an example of where this falls down:</p>
<p><a href="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.15.28-AM.png"><img class="alignnone size-large wp-image-221" src="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-17-at-10.15.28-AM-1024x826.png" alt="code coverage metrics for a single file" width="540" height="435" /></a></p>
<p>If you look at this report, we can see that the <code>some_method_with_conditionals</code> gets called, but only the <code>say_yes</code> path (lines 12 and 13) executes, and we never confirm that &#8216;no&#8217; gets sent if we pass <code>false</code> to the method. So far, so good, until we look at <code>some_method_with_ternary</code>. This is basically the same method refactored to be more compact, and with the same tests run against it. Yet we are told it is totally covered. So is the metric even still useful?</p>
<p>I still think code coverage is a valuable metric, if only to show you where there are holes in your test suite. If you go in with this knowledge and understanding the limitations, then you will be better equipped to maintain the quality of your app over time.</p>
<h2>Code Coverage is a temporal metric</h2>
<p>The last thing I want to mention about code coverage is that it&#8217;s useful to understand how your coverage changes over time. Particularly if you are managing a team of developers, it provides a quick warning if developers are slipping on their test writing. If you have a Continuous Integration machine, you can track these sort of metrics over time, which can really help you get a sense of where things are headed.<br />
In my next post I&#8217;ll show how to set up your very own CI machine with just a few clicks&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/code-coverage-setup-rails.html">Code Coverage — a simple Rails example</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2014/09/code-coverage-setup-rails.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Growl notifications from your Virtual Machine</title>
		<link>http://eyefodder.com/2014/09/growl-guard-virtual-machine.html</link>
		<comments>http://eyefodder.com/2014/09/growl-guard-virtual-machine.html#comments</comments>
		<pubDate>Sun, 07 Sep 2014 19:07:17 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Agile Software Development]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Quality Software]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Craftsmanship]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://eyefodder.com/?p=197</guid>
		<description><![CDATA[<p>As I develop I have Guard running in the background, executing my tests when things change. But I often don&#8217;t have the Terminal window front and centre, so I like to have Growl notifications for my test results. Setting up Growl to push notifications from the Virtual Machine to the host is a little tricky, so here&#8217;s a [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/growl-guard-virtual-machine.html">Getting Growl notifications from your Virtual Machine</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>As I develop I have <a title="Getting Started with Guard and RSpec" href="http://eyefodder.com/2014/09/guard-and-rspec.html">Guard running in the background</a>, executing my tests when things change. But I often don&#8217;t have the Terminal window front and centre, so I like to have Growl notifications for my test results. Setting up Growl to push notifications from the Virtual Machine to the host is a little tricky, so here&#8217;s a simple example to show how to do it.</p>
<div id="attachment_199" style="width: 544px" class="wp-caption alignnone"><a href="http://en.wikipedia.org/wiki/Old_Ephraim"><img class="size-full wp-image-199" src="http://eyefodder.com/wp-content/uploads/2014/09/Ursus_arctos_Dessin_ours_brun_grand.jpg" alt="Growl isn't as hairy as 'Old Ephraim' but is probably more useful" width="534" height="336" /></a><p class="wp-caption-text">Growl isn&#8217;t as hairy as &#8216;old Ephraim&#8217; but is probably more useful</p></div>
<p><span id="more-197"></span></p>
<h2>Getting Started</h2>
<p>To get started and see Growl notifications, we need to do a little more than normal. Let&#8217;s start by checking out the source code:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">

git clone -b guard_growl --single-branch https://github.com/eyefodder/spex.git

</pre>
<h3>Prepping Growl</h3>
<p>Download <a href="http://growl.info/" target="_blank">Growl</a> if you don&#8217;t already have it. Once it&#8217;s installed, open up the preferences pane and click on the &#8216;network&#8217; panel. Check the box marked &#8216;Listen for incoming notifications&#8217; and enter a password:<br />
<a href="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-06-at-11.06.13-AM.png"><img class="alignnone size-large wp-image-201" src="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-06-at-11.06.13-AM-1024x1006.png" alt="Screen Shot 2014-09-06 at 11.06.13 AM" width="540" height="530" /></a></p>
<h3>Prepping Vagrant</h3>
<p>The next thing we need to do is install a plugin for Vagrant that will allow us to execute a script <em>on the host machine</em> when we boot our virtual machine. I&#8217;ll explain what that is below the fold, but for now, make sure that you have Vagrant 1.6.4 or above (hint, type <code>vagrant -v</code> to find out) and update if necessary. Next, install the <a href="https://github.com/emyl/vagrant-triggers" target="_blank">Vagrant Triggers</a> plugin by entering this on the command line:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
$ vagrant plugin install vagrant-triggers
</pre>
<h3>Bringing the virtual machine up</h3>
<p>Next, run <code>vagrant up</code> as usual. When it runs, it creates a file <code>ops/dotfiles/guest_bash_profile</code>:</p>
<pre class="brush: bash; title: ; notranslate">
# Edit the following values with your own values

# Growl password set in Growl &gt; Preferences &gt; Network
export GROWL_PASSWORD=enter_growl_password

# The following entries are automatically generated
# Do not edit unless you know what you are doing!
# They are regenerated each time the virtual machine is rebooted
export HOST_IP=10.0.1.28

</pre>
<p>Go ahead and enter your Growl password. Now we&#8217;re good to go. run <code>vagrant rsync-auto</code> to keep things in sync and in another window, then <code>vagrant ssh</code> into the machine.</p>
<h3>Hey presto! Growl notifications</h3>
<p>So let&#8217;s get up and running! When you are ssh&#8217;d into the host machine, fire up Guard with <code>cd /app &amp;&amp; bundle exec guard -p</code>. Make a change to your code and when the tests run you should see a notification:<br />
<a href="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-06-at-11.52.50-AM.png"><img class="alignnone size-large wp-image-202" src="http://eyefodder.com/wp-content/uploads/2014/09/Screen-Shot-2014-09-06-at-11.52.50-AM-1024x414.png" alt="Growl Notification" width="540" height="218" /></a><br />
You&#8217;re good to go now, but read on if you&#8217;d like to understand how all this stuff works&#8230;</p>
<h2>How it works</h2>
<p>There are a lot of moving parts to get this thing going. I&#8217;m going to work from the Guardfile back, and then the Vagrantfile forwards. I guess we&#8217;ll meet somewhere in the middle so bear with me.</p>
<h3>Guardfile changes</h3>
<p>If you look in the Guardfile you will see a few new lines of code at the top:</p>
<pre class="brush: ruby; first-line: 15; title: ; notranslate">
host_ip = ENV['HOST_IP']
growl_pass = ENV['GROWL_PASSWORD']
PLACEHOLDER_GROWL_PASS='enter_growl_password'

if host_ip.blank? || growl_pass.blank? || (growl_pass==PLACEHOLDER_GROWL_PASS)
  puts 'host notifcations off: you must set HOST_IP and GROWL_PASSWORD in ops/dotfiles/guest_bash_profile'
  notification :off
else
  notification :gntp, :sticky =&gt; false, :host =&gt; ENV['HOST_IP'], :password =&gt; ENV['GROWL_PASSWORD']
end
</pre>
<p>Line 23 tells Guard to use GNTP for notifications (assuming HOST_IP and GROWL_PASSWORD have been set). It&#8217;s basically a means for sending Growl notifications over a network. You&#8217;ll need to add the GNTP gem, so we&#8217;ve added this to our Gemfile:</p>
<pre class="brush: ruby; first-line: 49; title: ; notranslate">
  # guard_growl
  gem 'ruby_gntp'
</pre>
<p>We can see that this system relies on a couple of environment variables being set. We got a clue that these get set in <code>ops/dotfiles/guest_bash_profile</code>, let&#8217;s see how that file gets created, and how we get that linked into the guest Virtual Machine.</p>
<h3>Creating the guest bash profile</h3>
<p>For this setup to work, we need two environment variables set: GROWL_PASSWORD and HOST_IP. The script that creates the file is <code>ops/setup_guest_bash_profile</code>. This script does a few things, so let&#8217;s step through it:</p>
<h4>Create a profile file if it doesn&#8217;t exist</h4>
<p>The first thing we want to do is create a profile file if one doesn&#8217;t exist already:</p>
<pre class="brush: bash; first-line: 42; title: ; notranslate">
# make a profile file if it doesn't exist
bash_file=dotfiles/guest_bash_profile
touch $bash_file
</pre>
<p>Next, we want to add some comments to the file. As we will run this script <em>every time the machine boots up</em> we only really want to add these comments if they don&#8217;t already exist. The <code>add_comments_once</code> function does this by checking for a match, and only adding the comment if it isn&#8217;t already in the file:</p>
<pre class="brush: bash; first-line: 7; title: ; notranslate">
add_comment_once(){
  comment=$1
  grep -q &quot;$comment&quot; $bash_file
  if [ $? -ne 0 ]
  then
    echo &quot;# $comment&quot; &gt;&gt; $bash_file
  fi
}
</pre>
<h4>Adding a bash entry for users to change</h4>
<p>Next thing we want to do is add environment variables for users to change. But as this code is run multiple times, we actually have three scenarios:</p>
<ul>
<li>An entry doesn&#8217;t yet exist in the file: create it</li>
<li>An entry exists but hasn&#8217;t been changed from the default: tell user to change it</li>
<li>A user has entered their own value: don&#8217;t do a thing!</li>
</ul>
<p>The <code>add_bash_entry</code> function achieves this:</p>
<pre class="brush: bash; first-line: 16; title: ; notranslate">
add_bash_entry(){
  token=$1
  default=$2
  change_message=&quot;You need to enter your $1 in $bash_file&quot;
  entry_comment=$3

  grep -q $token= $bash_file
  if [ $? -eq 0  ]
  then
    grep -q $default $bash_file
    if [ $? -eq 0 ]
    then
      # entry exists, but it's set to default value from this script
      echo $change_message
    fi
  else
    # variable entry doesn't exist
    echo $change_message
    echo $entry_comment
    echo &quot;&quot; &gt;&gt; $bash_file
    echo &quot;# $entry_comment&quot; &gt;&gt; $bash_file
    echo &quot;export $token=$default&quot; &gt;&gt; $bash_file
    echo &quot; &quot; &gt;&gt; $bash_file
  fi
}
</pre>
<p>The function gets three arguments: the token <code>GROWL_PASSWORD</code>, the default value <code>enter_growl_password</code>, and a message to explain to the user what to do. If the token is found (lines 22 &amp; 23) then it looks for the default value (lines 25 &amp; 26) and prints a change message if it&#8217;s there. If the token isn&#8217;t found (lines 32-38) then we write that into the file.</p>
<h4>Adding the HOST_IP as a system generated value</h4>
<p>The next thing we want to do is add the host system&#8217;s IP address to the file so that Growl knows where to send notifications:</p>
<pre class="brush: bash; first-line: 65; title: ; notranslate">
sed -i '' '/HOST_IP/d' $bash_file
# grab current host IP
ipaddr=`ifconfig | grep &quot;inet &quot; | grep -v 127.0.0.1 | cut -d ' ' -f2`
# and write to file
echo &quot;export HOST_IP=$ipaddr&quot; &gt;&gt; $bash_file
</pre>
<p>This script deletes any existing lines with <code>HOST_IP</code> in them (line 65), then uses a little bash trickery to find the current host ip. I found out how to do it from this <a href="http://www.askdavetaylor.com/how_do_i_figure_out_my_ip_address_on_a_mac/" target="_blank">post</a>, although I needed to change the delimiter from <code>\ </code> to <code>' '</code> (that&#8217;s from an escaped space character to a space in quotes. Finally we write this out to our <code>guest_bash_profile</code> file. The next step is getting this script to run when we want it.</p>
<h3>Running the profile setup script when Vagrant starts</h3>
<p>Thanks to the <a href="https://github.com/emyl/vagrant-triggers" target="_blank">Vagrant Triggers</a> plugin, this is a really simple affair. We just add the following to our Vagrantfile:</p>
<pre class="brush: ruby; first-line: 37; title: ; notranslate">
  config.trigger.before [:up, :reload], :stdout =&gt; true do
    run &quot;sh ./setup_guest_bash_profile.sh&quot;
  end
</pre>
<p>This will run our script every time we call <code>vagrant up</code> or <code>vagrant reload</code>, ensuring that our host ip address is always up to date in the file. The <em>last</em> piece of the puzzle is to make sure we use this file to actually set environment variables on the guest machine.</p>
<h3>Linking the guest bash profile to the guest virtual machine</h3>
<p>This is a relatively simple two-part process. First thing we do is share the <code>ops/dotfiles</code> directory on the virtual machine:</p>
<pre class="brush: ruby; first-line: 20; title: ; notranslate">
  config.vm.synced_folder 'dotfiles', '/dotfiles'
</pre>
<p>Secondly, we want that file symlinked in the guest machine to <code>~/.bash_profile</code>. I created a new Puppet class to achieve this. Check out <code>ops/puppet/modules/spex/dotfile_symlink.pp</code>:</p>
<pre class="brush: ruby; first-line: 4; title: ; notranslate">
class spex::dotfile_symlink{
  file { '/home/vagrant/.bash_profile':
    ensure =&gt; link,
    target =&gt; '/dotfiles/guest_bash_profile'
  }
}
</pre>
<p>Super simple here. We tell puppet to <code>ensure</code> that <code>/home/vagrant/.bash_profile</code> is a symlink to <code>/dotfiles/guest_bash_profile</code>. In <code>ops/puppet/manifests/default.pp</code> we simply include the class with the others:</p>
<pre class="brush: ruby; first-line: 6; title: ; notranslate">
include spex::base_packages
include spex::postgres_setup
include spex::ruby_setup
include spex::dotfile_symlink
</pre>
<p>Now we have everything wired up and ready to go!</p>
<h3>Conclusion</h3>
<p>This wraps up my example for getting Growl notifications from Guard into the host machine. Although there are a bunch of steps to jump through, once it&#8217;s working I hope you&#8217;ll find it a pretty robust solution.</p>
<p>The goal in all of this is to shorten feedback loops when you develop. This process should give you some confidence that when your code changes the right tests run. The power of this is greatest when you are confident that your tests cover enough of your application such that you will know when you break things. Our next step is to look into the breadth of your tests and setting up code coverage metrics for your app&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/growl-guard-virtual-machine.html">Getting Growl notifications from your Virtual Machine</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2014/09/growl-guard-virtual-machine.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Spring with RSpec and Guard to speed up testing</title>
		<link>http://eyefodder.com/2014/09/using-spring-with-rspec-and-guard.html</link>
		<comments>http://eyefodder.com/2014/09/using-spring-with-rspec-and-guard.html#comments</comments>
		<pubDate>Thu, 04 Sep 2014 23:50:58 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Agile Software Development]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Craftsmanship]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://eyefodder.com/?p=180</guid>
		<description><![CDATA[<p>In my last post I showed you how to setup Guard and RSpec so you can automatically run tests when things change. Now lets get things cooking on gas by using the Spring application preloader. This will mean that your app&#160;framework will only have to load once, and tests will be super zippy. Setting up [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/using-spring-with-rspec-and-guard.html">Using Spring with RSpec and Guard to speed up testing</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In my last post I showed you how to setup <a title="Getting Started with Guard and RSpec" href="http://eyefodder.com/2014/09/guard-and-rspec.html">Guard and RSpec</a> so you can automatically run tests when things change. Now lets get things cooking on gas by using the Spring application preloader. This will mean that your app&nbsp;framework will only have to load once, and tests will be super zippy. Setting up Spring with RSpec is simple and has a huge effect on test running speeds.</p>
<p><div style="width: 360px" class="wp-caption alignnone"><a href="http://www.vh1.com/celebrity/2011-09-29/the-10-greatest-movie-shoes-of-all-time/"><img class="" src="http://www.vh1.com/celebrity/bwe/images/2011/09/Inspector-Gadget-Spring-Shoes-1317315905.jpg" alt="" width="350" height="232" /></a><p class="wp-caption-text">Things are zippier on Spring(s)</p></div><br />
<span id="more-180"></span></p>
<h2>Getting the sample code for Spring with RSpec</h2>
<p>As with all of the examples, I&#8217;ve setup the simplest possible example to show setting up Spring with RSpec. Go ahead and checkout the code here:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">

git clone -b rspec_guard_spring --single-branch https://github.com/eyefodder/spex.git

</pre>
<p>Once you have checked out the code, jump into the <code>ops</code> directory and <code>vagrant up</code>to bring the VM up. When it&#8217;s up and running, get synching running by entering <code>vagrant rsync-auto</code> and then in a new terminal window enter the following:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
vagrant ssh
cd /app
bundle exec guard -p
</pre>
<p>And that is basically it! Now when you run your tests, you will be taking advantage of Spring! Read on to see how to get this working&#8230;</p>
<h2>How we got it working</h2>
<p>So to get this working we did a few things. First off, we added the spring commands for rspec with the <a href="https://github.com/jonleighton/spring-commands-rspec" target="_blank">spring-commands-rspec</a> gem:</p>
<pre class="brush: ruby; first-line: 46; title: ; notranslate">
  # rspec_guard_spring
  gem 'spring-commands-rspec'
</pre>
<p>Next, we let spring create the binstub for us (in the example we already did this, so you will see the outputted file at <code>bin/rspec</code>:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
pbh$ spring binstub --all
* bin/rake: spring already present
* bin/rspec: generated with spring
* bin/rails: spring already present
</pre>
<p>Lastly, we need to update the command that Guard uses to run RSpec in the <code>Guardfile</code>:</p>
<pre class="brush: ruby; first-line: 14; title: ; notranslate">
guard :rspec, cmd: 'bin/rspec' do
  ...
end
</pre>
<h2>The &#8216;gem pristine&#8230;&#8217; warning</h2>
<p>When your specs run you will probably see an error that talks about running <code>gem pristine --all</code> to speed up loading:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
Warning: Running `gem pristine --all` to regenerate your installed gemspecs (and deleting then reinstalling your bundle if you use bundle --path) will improve the startup performance of Spring.
</pre>
<p>I did a little digging on this and found the gems that are causing the issue using the code posted in this <a href="http://http://stackoverflow.com/questions/19726167/how-do-i-get-rid-of-spring-warning-running-gem-pristine-all" target="_blank">answer</a>:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
vagrant@spex:/app$ ruby -e 'p Gem::Specification.stubs.reject(&amp;:stubbed?).reject(&amp;:default_gem?).map(&amp;:name)'
[&quot;bigdecimal&quot;, &quot;io-console&quot;, &quot;json&quot;, &quot;minitest&quot;, &quot;psych&quot;, &quot;rake&quot;, &quot;rdoc&quot;, &quot;test-unit&quot;]
</pre>
<p>A little more <a href="https://github.com/rails/spring/issues/320#issuecomment-50658111" target="_blank">digging</a> told me that these gems are probably system Ruby packages that appear as gems thanks to the <code>rubygems-integration</code>. Long story short, you have to live with with this warning message for now. Although startup performance might be affected, overall performance each time you run RSpec should still be great! Now you have Spring with RSpec running, our next post will show you how to set up notifications with Growl so you don&#8217;t have to keep your terminal window visible while you code.</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/using-spring-with-rspec-and-guard.html">Using Spring with RSpec and Guard to speed up testing</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2014/09/using-spring-with-rspec-and-guard.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with Guard and RSpec</title>
		<link>http://eyefodder.com/2014/09/guard-and-rspec.html</link>
		<comments>http://eyefodder.com/2014/09/guard-and-rspec.html#comments</comments>
		<pubDate>Thu, 04 Sep 2014 22:23:40 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Agile Software Development]]></category>
		<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Quality Software]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Craftsmanship]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://eyefodder.com/?p=177</guid>
		<description><![CDATA[<p>As I build out an application I want to ensure it&#8217;s behaving as I intend it. RSpec is a great framework for testing Ruby code, and is the tool I use most for my testing. But tests are pretty useless if you don&#8217;t run them, and rather than manually run tests when I change things, [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/guard-and-rspec.html">Getting Started with Guard and RSpec</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>As I build out an application I want to ensure it&#8217;s behaving as I intend it. <a href="http://rspec.info/" target="_blank">RSpec</a> is a great framework for testing Ruby code, and is the tool I use most for my testing. But tests are pretty useless if you don&#8217;t run them, and rather than manually run tests when I change things, I use <a href="http://guardgem.org/" target="_blank">Guard</a> and RSpec together. Here&#8217;s the simplest possible example for setting it up.</p>
<div id="attachment_186" style="width: 550px" class="wp-caption alignnone"><a href="http://en.wikipedia.org/wiki/Yeomen_Warders"><img class="size-large wp-image-186" src="http://eyefodder.com/wp-content/uploads/2014/09/beefeater-757x1024.jpg" alt="&quot;Detroit Publishing Co. - A Yeoman of the Guard (N.B. actually a Yeoman Warder), full restoration&quot; by Adam Cuerden, Detroit Publishing Company - http://www.loc.gov/pictures/item/2002696943/. Licensed under Public domain via Wikimedia Commons - http://commons.wikimedia.org/wiki/File:Detroit_Publishing_Co._-_A_Yeoman_of_the_Guard_(N.B._actually_a_Yeoman_Warder),_full_restoration.jpg#mediaviewer/File:Detroit_Publishing_Co._-_A_Yeoman_of_the_Guard_(N.B._actually_a_Yeoman_Warder),_full_restoration.jpg" width="540" height="730" /></a><p class="wp-caption-text">Guard and RSpec : rather fancy</p></div>
<p><span id="more-177"></span><a href="http://guardgem.org/" target="_blank">Guard</a> is a command line tool that responds to filesystem change events. You can use it to do all sorts of stuff using one of the <a href="https://github.com/guard" target="_blank">many plugins</a> that have been built for it. In our simple example we are going to use it to trigger rspec tests when we change code in our app.</p>
<h2>Getting Started</h2>
<p>For this we are going to grab an example from the Spex repository where I keep all my code examples. Clone the branch from github:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">

git clone -b rspec_guard --single-branch https://github.com/eyefodder/spex.git

</pre>
<h2>Confirming the tests run</h2>
<p>When you have the code cloned, jump into the <code>ops</code> directory and execute <code>vagrant up</code> to bring up the virtual machine that will run our example. As instructed, run <code>vagrant rsync-auto</code>; this will ensure that if you make changes to the code, they will get synced in the virtual machine (which is where Guard will be running). Now, open a new Terminal window, <code>vagrant ssh</code> into the machine and type the following:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
cd /app
rspec
</pre>
<p>By doing this, we should see our tests run and get the following output:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
vagrant@spex:~$ cd /app
vagrant@spex:/app$ rspec
Run options: include {:focus=&gt;true}

All examples were filtered out; ignoring {:focus=&gt;true}
....

Finished in 0.29975 seconds (files took 1.65 seconds to load)
4 examples, 0 failures

Top 4 slowest examples (0.2972 seconds, 99.1% of total time):
  Static Pages root page has the expected title
    0.27993 seconds ./spec/integration/static_pages_spec.rb:9
  ApplicationHelper #some_method_to_test returns 'result'
    0.00696 seconds ./spec/helpers.lication_helper_spec.rb:4
  Static Pages root page has a link to my blog
    0.00691 seconds ./spec/integration/static_pages_spec.rb:13
  Static Routing root path routes to the static#home path
    0.0034 seconds ./spec/routing/static_routing_spec.rb:5

Top 3 slowest example groups:
  Static Pages
    0.14342 seconds average (0.28684 seconds / 2 examples) ./spec/integration/static_pages_spec.rb:2
  ApplicationHelper
    0.00696 seconds average (0.00696 seconds / 1 example) ./spec/helpers/application_helper_spec.rb:2
  Static Routing
    0.0034 seconds average (0.0034 seconds / 1 example) ./spec/routing/static_routing_spec.rb:2

Randomized with seed 13496
</pre>
<p>So what happens if we break something? Go ahead and change the code in <code>app/helpers/application_helper.rb</code>:</p>
<pre class="brush: ruby; first-line: 2; title: ; notranslate">
  def some_method_to_test
    'resultd'
  end
</pre>
<p>Now when we run <code>rspec</code> again we see that four tests have run and one failed as expected. But really, given we just changed one file, did we have to run all the tests? And did we have to manually re-run the tests? The answers to these is no; Guard and Rspec together are pretty awesome&#8230;</p>
<h2>Guard and Rspec together</h2>
<p>To get things up and running, type in the following:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
bundle exec guard -p
</pre>
<p>You should see something like this:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
vagrant@spex:/app$ bundle exec guard -p
21:18:32 - INFO - Guard is using NotifySend to send notifications.
21:18:32 - INFO - Guard is using TerminalTitle to send notifications.
21:18:32 - INFO - Guard::RSpec is running
21:18:32 - INFO - Guard is now watching at '/app'
[1] guard(main)&gt; 
</pre>
<p>If you hit the <code>Enter</code> key, you&#8217;ll see all your tests run again. This is pretty awesome right? Now you can save yourself having to type <code>rspec</code>. But wait, that&#8217;s not all. Go ahead and change your <code>application_helper.rb</code> file back the way it was. Now you should see something like this:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
21:22:13 - INFO - Running: spec/helpers/application_helper_spec.rb
Run options: include {:focus=&gt;true}

All examples were filtered out; ignoring {:focus=&gt;true}
.

Finished in 0.0103 seconds (files took 1.99 seconds to load)
1 example, 0 failures

Top 1 slowest examples (0.00878 seconds, 85.2% of total time):
  ApplicationHelper #some_method_to_test returns 'result'
    0.00878 seconds ./spec/helpers.lication_helper_spec.rb:4

Randomized with seed 15725


[1] guard(main)&gt; 
</pre>
<p>Pretty sweet huh? Basically, anytime a file changes Guard figures out what test or tests we need to run. This helps to keep my test suite running lean and fast; aiding rather than slowing down development. Let&#8217;s take a look at what we have added in our example to make things work.</p>
<h2>How this was setup</h2>
<p>First off we added two gems to the <code>Gemfile</code>:</p>
<pre class="brush: ruby; first-line: 42; title: ; notranslate">
group :development do
  # rspec_guard
  gem 'guard-rspec', require: false
end

group :development, :test do
  # rspec_guard
  gem 'rspec-rails', '~&gt; 3.0.0'
end
</pre>
<p>Next, we have written some specs which you will find in the <code>spec</code> folder. I&#8217;m not going to go into detail on the tests I&#8217;ve written, but they should be pretty legible and cover just enough to demonstrate what we need to about Guard. Check out <code>spec/helpers/application_helper.rb</code>, <code>spec/integration/static_pages_spec.rb</code>, and <code>spec/routing/static_routing_spec.rb</code>. The <code>spec/rails_helper.rb</code> and <code>spec/spec_helper.rb</code> files are the ones generated by the <code>rspec-rails</code> gem when we run <code>rails generate rspec:install</code>.</p>
<h3>The Guardfile</h3>
<p>The real magic of getting Guard and RSpec working together comes from the <code>Guardfile</code> which is used to tell Guard what to watch for, and then what to do with it. I&#8217;ve modified the file generated by <code>guard init rspec</code> to demonstrate some common usage patterns based on the way I test. Watch statements follow simple regular expressions to determine when to fire. As you build up your app, you will want to keep this file updated as you may need to introduce new patterns. Let&#8217;s take a look through some examples in the file:</p>
<h4>Run any spec that changes</h4>
<p>Any file that is in the <code>spec</code> folder and ends with &#8216;_spec.rb&#8217; will get run if it changes:</p>
<pre class="brush: ruby; first-line: 15; title: ; notranslate">
  # run a spec file if it changes
  watch(%r{^spec/.+_spec\.rb$})
</pre>
<h4>Re-run the spec if the helper files change</h4>
<p><code>spec_helper.rb</code> and <code>rails_helper.rb</code> are files that RSpec uses to setup your specs. So if they change for any reason, it would affect all the tests.</p>
<pre class="brush: ruby; first-line: 19; title: ; notranslate">
  # re-run if spec helper or rails helper changes
  watch('spec/spec_helper.rb')  { &quot;spec&quot; }
  watch('spec/rails_helper.rb')  { &quot;spec&quot; }
</pre>
<h4>Run the matching spec if something changes in the app folder</h4>
<p>As a good catch all, if a file changes in the <code>app</code> folder we want to run the corresponding spec:</p>
<pre class="brush: ruby; first-line: 25; title: ; notranslate">
  # run a file matching same path with _spec at the end
  # eg /app/models/foo.rb will run /spec/models/foo_spec.rb
  watch(%r{^app/(.+)\.rb$}) { |m| &quot;spec/#{m[1]}_spec.rb&quot; }
</pre>
<h4>Re-run the suite if support files change</h4>
<p>I put RSpec <a href="https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples" target="_blank">shared examples</a> and <a href="https://www.relishapp.com/rspec/rspec-expectations/v/3-0/docs/custom-matchers/define-matcher" target="_blank">custom matchers</a> into the <code>support</code> folder, so if anything in here changes I&#8217;ll need to re-run the full suite:</p>
<pre class="brush: ruby; first-line: 33; title: ; notranslate">
  watch(%r{^spec/support/(.+)\.rb$})  { &quot;spec&quot; }
</pre>
<h4>Integration tests for views and controllers</h4>
<p>I have found it simpler to test my views and controllers by creating integration tests that mimic user behaviour (although the tests you see aren&#8217;t great examples of that, we&#8217;ll be building out better ones in a future example on using <a href="https://github.com/jnicklas/capybara" target="_blank">Capybara</a>). For this to work, I have a naming structure such that specs related to the <code>foo</code> controller (or views) live in <code>spec/integration/foo_pages_spec.rb</code>. If a controller is pluralized, that is handled well too, so that <code>app/controllers/things_controller.rb</code> will trigger <code>spec/integration/thing_pages_spec.rb</code>:</p>
<pre class="brush: ruby; first-line: 53; title: ; notranslate">
  watch(/^app\/controllers\/(.+)_controller.rb/) do |m|
    [&quot;spec/integration/#{m[1].singularize}_pages_spec.rb&quot;,
     &quot;spec/routing/#{m[1]}_routing_spec.rb&quot;]
  end
</pre>
<p>And if a view file changes, we run the corresponding integration test using this: </p>
<pre class="brush: ruby; first-line: 44; title: ; notranslate">
  # if something within a view folder changes, run that spec
  # eg app/views/static/anyfile runs /spec/integration/static_pages_spec.rb
  watch(%r{^app/views/(.+)/}) do |m|
      &quot;spec/integration/#{m[1].singularize}_pages_spec.rb&quot;
  end
</pre>
<p>If any of the overall layouts change, it could affect any of our integration tests, so we should re-run them all:</p>
<pre class="brush: ruby; first-line: 42; title: ; notranslate">
  watch(%r{^app/views/layouts/(.*)}) { 'spec/integration' }
</pre>
<h4>Abstract classes</h4>
<p>Lastly, you will inevitably end up having abstract classes in your app. If these change you probably want to run all the specs for classes that inherit from it. I only included an example for the <code>application_controller.rb</code> changing but you can extrapolate from here:</p>
<pre class="brush: ruby; first-line: 39; title: ; notranslate">
  watch('app/controllers/application_controller.rb')  { &quot;spec/integration&quot; }
</pre>
<h3>A word on Guard with polling</h3>
<p>The more astute amongst you will notice that Guard is started up with a <code>-p</code> option. This option forces Guard to poll for changes rather than listen for filesystem change notifications. The reason is that with our setup using rsync to synchronize changes in the virtual machine causes Guard to not always respond to changes. Basically an <a href="https://github.com/guard/guard/issues/495" target="_blank">earlier issue</a> with Guard-Rspec was solved by having rspec only run when it sees a file as modified rather than added. However, with rsync it seems that the <a href="https://github.com/guard/listen" target="_blank">listen</a> gem sometimes think the file has been added rather than modified. I&#8217;m trying to <a href="https://groups.google.com/forum/#!topic/guard-dev/-tx6yncq1wA" target="_blank">figure out a resolution</a> for this, but in the meantime, polling it is! </p>
<h3>But wait, there&#8217;s more!</h3>
<p>This super-simple example should help you get up and running with Guard and RSpec. With the setup here you would find that every time the specs run the Rails application has to load up. This makes every test run take at least a few seconds. In earlier versions of Rails I used to use <a href="https://coderwall.com/p/jxrhag" target="_blank">Spork</a> to pre-load the framework, but now Rails comes with <a href="https://github.com/rails/spring" target="_blank">Spring</a> which is much easier to setup. In my next post I&#8217;ll walk you through it; until then happy testing!</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2014/09/guard-and-rspec.html">Getting Started with Guard and RSpec</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2014/09/guard-and-rspec.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Have you been hurt by code reuse? Learn from De Niro</title>
		<link>http://eyefodder.com/2011/07/have-you-been-hurt-by-code-reuse-learn-from-de-niro.html</link>
		<comments>http://eyefodder.com/2011/07/have-you-been-hurt-by-code-reuse-learn-from-de-niro.html#comments</comments>
		<pubDate>Wed, 06 Jul 2011 23:34:32 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Quality Software]]></category>
		<category><![CDATA[Software Craftsmanship]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://www.eyefodder.com/?p=132</guid>
		<description><![CDATA[<p>Ever used someone else&#8217;s code; a library or sample app online? Ever got to a point where it&#8217;s been so mind-bendingly painful that you rue the day you ever found the stupid &#8216;library&#8217; in the first place? If not then chances are you&#8217;re not a developer, you&#8217;re this guy, or you&#8217;re delusional. Spurred by a [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2011/07/have-you-been-hurt-by-code-reuse-learn-from-de-niro.html">Have you been hurt by code reuse? Learn from De Niro</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Ever used someone else&#8217;s code; a library or sample app online? Ever got to a point where it&#8217;s been so mind-bendingly painful that you rue the day you ever found the stupid &#8216;library&#8217; in the first place? If not then chances are you&#8217;re not a developer, you&#8217;re <a href="http://www.orato.com/self-help/luckiest-man-the-world">this guy</a>, or you&#8217;re delusional. Spurred by a <a href="http://twitter.com/#!/mateobarraza/status/86150174744911872">conversation with Mateo</a>, my friend and former development buddy about this, I started to think a little deeper about what the problem is with code reuse. We expect a well-made production quality piece of work, and before long we realize that we are stuck with something that is sucking time away rather than letting us develop the hard stuff faster. So when should you reuse code? Here are some thoughts on when you should proceed with abandon, and when you might want to be more cautious&#8230;<br />
<div style="width: 384px" class="wp-caption aligncenter"><a href="http://www.mustrad.org.uk/pictures/brown.htm"><img alt="" src="http://www.mustrad.org.uk/graphics/james_b.jpg" title="We think we are getting this" width="374" height="503" /></a><p class="wp-caption-text">We think we are getting this...</p></div><br />
<div style="width: 405px" class="wp-caption aligncenter"><a href="http://www.mustrad.org.uk/pictures/italian1.htm"><img alt="" src="http://www.mustrad.org.uk/graphics/italian1.jpg" title="...but often end up stuck with this" width="395" height="620" /></a><p class="wp-caption-text">...but often end up stuck with this</p></div></p>
<p><span id="more-132"></span></p>
<p>As Mateo mentioned, we are pretty much trained to reuse code wherever we can (and that includes our own—more on that later). The assumption is that just because it&#8217;s on google code or GitHub it&#8217;s good to go. If you&#8217;re not careful you will spend more time working through someone else&#8217;s library than you would coding from scratch. In practice the decision to reuse or not is a very delicate balancing act that you can easily get wrong. Here are some things to consider when you are faced with the choice:</p>
<h2>Good times to consider reuse</h2>
<h3>It&#8217;s generally accepted to be best in class</h3>
<p>No-one is going to regret choosing to use <a href="http://jquery.org/about/">JQuery</a> as a base framework for their javascript app. If you know the library is a de-facto standard for the problem you&#8217;re trying to solve you should be in good shape.</p>
<h3>You don&#8217;t know much about the problem / algorithm</h3>
<p>I&#8217;m not a statistics guy, and when I decided to code up an <a href="http://www.eyefodder.com/how-long-will-your-project-take-software-estimation-app">application</a> that uses some simple estimates to get a more realistic prediction of development time I needed to calculate the shape of a <a href="http://www.wolframalpha.com/input/?i=beta+distribution">beta distribution chart</a>. Rather than do it myself, I found a <a href="http://www.jstat.org/">library</a> that saved me having to learn how to code a bunch of statistical formula.</p>
<h3>There is an a active community around the code</h3>
<p>If there are O&#8217;reilly books on the subject, if there are questions (and answers) about the code on <a href="http://stackoverflow.com/">stack overflow</a>, then you can probably feel a little more comfortable that when you get stuck, your questions will get answered.</p>
<h3>It&#8217;s not the main problem you&#8217;re trying to solve</h3>
<p>Again, in the example of the software estimation app I built, the main problem I was after solving was showing people how you can quickly get a sense of the length of your project, not hardcore statistical analysis on data. I knew I didn&#8217;t need to do too much with the statistical analysis, and if it all went wrong, I could back out and use simpler, back of the napkin estimates</p>
<h2>When to be wary</h2>
<h3>The code isn&#8217;t being maintained</h3>
<p>If the code is marked at version 0.1 and was last updated three years ago, just be aware that the owner has probably moved on to other things and if you find problems, you might end up having to fix someone else&#8217;s issues.</p>
<h3>You know a lot about the problem domain and could put something together quickly</h3>
<p>If I know a problem domain really really well, then I can probably write my own stuff in the time it takes me to learn how someone else has approached the problem. Essentially I can do it quicker than &#8216;most any learning curve.</p>
<h3>The code doesn&#8217;t have supporting tests</h3>
<p>At the risk of sounding like an <a href="http://www.youtube.com/watch?v=l1wKO3rID9g">agile hitler</a>, if code doesn&#8217;t have a decent, usable test harness written against it, I have very little faith in it&#8217;s utility. It will mean that I have to proceed more slowly and cautiously and likely not understand half the intent of the code.</p>
<h3>It&#8217;s your own stuff</h3>
<p>So you wrote some stuff on your last project that applies to what you&#8217;re doing now? Good on you; should save a tonne of time, right? Think again—just because you wrote it doesn&#8217;t mean it&#8217;s any better than someone else&#8217;s work. This one deserves a little more explanation below</p>
<h3>It&#8217;s going to be really difficult to back out of later</h3>
<p>If the library you&#8217;re going to use is going to form the backbone of your application or the way its structured, then you need to be careful about the decision you&#8217;re making. Things like an <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller#Implementations_of_MVC_as_web-based_frameworks">architectural framework</a> deserve careful though because the cost of changing your mind can get prohibitively high.</p>
<h2>On re-using your own code</h2>
<p>There are a couple of reasons why we need to be wary of our own work. First off, we tend to take a revisionist view on things; we assume that the work we did in the past is completely applicable to the problem we have at hand today. And I don&#8217;t know about you but I&#8217;ve become a better coder over time, so my old code is not as good or clean as the code I write today. Any time you reuse work, you need to weigh your own code with the same rigour as you would someone else&#8217;s. Don&#8217;t get me wrong, I&#8217;m really not advocating re-writing your own code for every project; what I&#8217;m suggesting is that if you are going to reuse your own code, make sure it&#8217;s fit for purpose, well-tested and as good as you can make it.</p>
<h2>So, what can De Niro teach me about reuse?</h2>
<p>The decision about whether to reuse or not is a tough one. You need to invest some time evaluating the library, and at some point make a judgement call on how steep the learning curve is versus just going it alone. The smart thing to do when you decide to reuse code is to make it easy to back out of the decision. As <a href="http://www.youtube.com/watch?v=85eeu2XF4QY&amp;feature=related">De Niro says in Heat</a>:</p>
<blockquote><p>Have no attachments; allow nothing to be in your life that you cannot walk out on in thirty seconds flat if you feel the heat around the corner</p></blockquote>
<p>&nbsp;</p>
<p>What I mean by this is that if you are going to use a library or someone else&#8217;s code, make sure you have it well isolated in your application. Try to only interact with it in one place, and make sure you have solidly tested that integration point. That way, if you later decide to back out of your decision, you can cleanly, surgically remove the library and replace it with your own work (or vice versa). Lowering the cost of changing your mind is the thing that can make the difference between a happy marriage and a bitter, bitter divorce that bankrupts you in the process.</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2011/07/have-you-been-hurt-by-code-reuse-learn-from-de-niro.html">Have you been hurt by code reuse? Learn from De Niro</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2011/07/have-you-been-hurt-by-code-reuse-learn-from-de-niro.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlexUnit eclipse plugin alpha</title>
		<link>http://eyefodder.com/2007/08/flexunit_eclipse_plugin_alpha.html</link>
		<comments>http://eyefodder.com/2007/08/flexunit_eclipse_plugin_alpha.html#comments</comments>
		<pubDate>Thu, 30 Aug 2007 07:26:37 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Agile Software Development]]></category>
		<category><![CDATA[Flash & Actionscript]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://localhost:8888/?p=30</guid>
		<description><![CDATA[<p>I&#8217;ve been kind of quiet recently for three reasons: Its summer Work has been insanely busy I&#8217;ve been beavering away on a new plugin for eclipse The plugin is designed with one key goal in mind: shortening the develop-test feedback loop. It integrates eclipse and the flexunit framework to make our lives as developers easier. [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2007/08/flexunit_eclipse_plugin_alpha.html">FlexUnit eclipse plugin alpha</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been kind of quiet recently for three reasons:</p>
<ul>
<li>Its summer</li>
<li>Work has been insanely busy</li>
<li>I&#8217;ve been beavering away on a new plugin for eclipse</li>
</ul>
<p>The plugin is designed with one key goal in mind: shortening the develop-test feedback loop. It integrates eclipse and the flexunit framework to make our lives as developers easier.<br />
The plan is to release the plugin on <a href="http://labs.adobe.com/">labs</a> as soon as possible (I&#8217;m about to go on holiday for a couple of weeks so it&#8217;ll be October at the earliest&#8230;) but I thought I&#8217;d give you an early heads-up on what I&#8217;ve been doing when its been too hot to walk the New York streets&#8230;</p>
<p><span id="more-30"></span><br />
So, here&#8217;s what I&#8217;ve done so far:</p>
<ul>
<li>Modded the flexunit visual layout to work better in an IDE window</li>
<li>Setup the plugin to switch test runner when you switch between projects</li>
<li>Modded the flexunit swf to make it easier to re-run the test by clciking on the bar</li>
<li>Re-run the test when the test harness is recompiled</li>
<li>Set it up so that the developer can run a subset of tests</li>
<li>Set it up so that the test harness mxml is templated and can be distinct per project</li>
</ul>
<p>Plans for the future:</p>
<ul>
<li>integrate more tightly with CI build processes</li>
<li>autogenerate ANT build script</li>
<li>ability to choose tests on a per-method rather than per-test class basis</li>
<li>Incorporate other very cool stuff that flexunit has coming down the line</li>
</ul>
<p>So, for now we are planning to have an internal release; the plugin is definitely alpha and I&#8217;d like to keep it  to a limited group to iron out bugs, tighten up my bad Java and find out what a cross-section of our developers need. The plan is to release internally to Adobe Consulting, but if you are a forgiving and patient person who could really benefit from this, drop me a note and we can chat&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2007/08/flexunit_eclipse_plugin_alpha.html">FlexUnit eclipse plugin alpha</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2007/08/flexunit_eclipse_plugin_alpha.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CruiseControl on the Mac &#8211; modifying the build script to work x-platform</title>
		<link>http://eyefodder.com/2007/06/cruisecontrol_on_the_mac_modif.html</link>
		<comments>http://eyefodder.com/2007/06/cruisecontrol_on_the_mac_modif.html#comments</comments>
		<pubDate>Tue, 12 Jun 2007 16:10:22 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Flash & Actionscript]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://localhost:8888/?p=27</guid>
		<description><![CDATA[<p>So, I thought I was doing pretty well, getting svn working on the mac, installing cruisecontrol for my continuous integration, even getting SCPlugin working with unsigned certificates. Then I tried to run my ant build, and ended up having all sorts of problems getting my mac debug player to run. Some investigating and help from [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2007/06/cruisecontrol_on_the_mac_modif.html">CruiseControl on the Mac &#8211; modifying the build script to work x-platform</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>So, I thought I was doing pretty well, getting svn working on the mac, installing <a href="http://cruisecontrol.sourceforge.net/overview.html">cruisecontrol</a> for my continuous integration, even getting <a href="http://scplugin.tigris.org/servlets/ProjectProcess?pageID=rgnEkt">SCPlugin</a> working with unsigned certificates. Then I tried to run my ant build, and ended up having all sorts of problems getting my mac debug player to run. Some investigating and help from the ANT folks later, and I have a solution</p>
<p><span id="more-27"></span><br />
So, when I ran my ant build, all went well until the <code>runTest</code> target executed (or at least tried to execute). I got the following build error:</p>
<pre class="brush: java; title: ; wrap-lines: true; notranslate">
Execute failed: java.io.IOException: debugPlayerMac.app cannot execute
</pre>
<p>You see the problem is that on a mac, the standalone player (like other applications on the Mac) is actually a folder containing all sorts of cleverness inside. Ant doesn&#8217;t know how to execute a folder, so I was a bit stuck. Until, after lots of digging, I found the answer in an old <a href="http://osflash.org/">osflash</a> mailing list <a href="http://readlist.com/lists/osflash.org/osflash/0/1908.html">archive</a>. Basically I have to use the &#8216;open&#8217; command to launch the app &#8211; something like this:</p>
<p>&nbsp;</p>
<pre class="brush: xml; title: ; notranslate">&lt;exec executable=&quot;open&quot;&gt;
&lt;arg line=&quot;${pathToFlashPlayer}&quot;/&gt;
&lt;arg line=&quot;${pathToSWFToPlay}&quot;/&gt;
&lt;/exec&gt;</pre>
<p>I tried this, and it worked nicely. The problem is that my ant build needs to wait until the test harness runs and closes the player before reading the log and parsing the results for cruisecontrol to consume. In the ant script above, the open command only stalls the ant script until it has finished doing its opening magic, so ant gets upset as the test results haven&#8217;t been written yet. I slept on this, then couldn&#8217;t think of an answer so I sent an email to the <a href="http://www.nabble.com/Running-.app-on-Mac-OSX-tf3908536.html">ant users </a> mailing list. Mere minutes later I got a <a href="http://www.nabble.com/Running-.app-on-Mac-OSX-tf3908536.html">reply</a> that helped me work out how to crack this.<br />
Basically, ant has the ability to run two threads, and move on when they are both complete. So in one thread we launch the player, and in another thread we first wait for the file to be available, then we do a check to see if it contains what we want (I am testing against the flag <code>-----------------TESTRUNNEROUTPUTENDS----------------</code> which I used in my result printer).  It worked like a charm:</p>
<pre class="brush: xml; title: ; notranslate">&lt;target name=&quot;runTest&quot; description=&quot;runs the test harness&quot; depends=&quot;compileTest&quot;&gt;
&lt;parallel&gt;
&lt;exec executable=&quot;open&quot; spawn=&quot;no&quot;&gt;
&lt;arg line=&quot;${debugPlayer}&quot;	/&gt;
&lt;arg line=&quot;'${testHarness.swf}'&quot;/&gt;
&lt;/exec&gt;
&lt;sequential&gt;
&lt;waitfor&gt;
&lt;available file=&quot;${flashlog.location}&quot;/&gt;
&lt;/waitfor&gt;
&lt;waitfor&gt;
&lt;isfileselected file=&quot;${flashlog.location}&quot;&gt;
&lt;contains text=&quot;-----------------TESTRUNNEROUTPUTENDS----------------&quot;/&gt;
&lt;/isfileselected&gt;
&lt;/waitfor&gt;
&lt;/sequential&gt;
&lt;/parallel&gt;
&lt;/target&gt;
</pre>
<p>The last step to making this properly cross platform for cruisecontrol was to have the right <code>&lt;exec&gt;</code> command called depending on the OS. Fortunately there is an <code>os</code> attribute you can specify on <code>&lt;exec&gt;</code> and the task will only run if the os matches the platform you are running the task on. A few minutes later, I had my amended runTest target:</p>
<pre class="brush: xml; title: ; notranslate">&lt;target name=&quot;runTest&quot; description=&quot;runs the test harness&quot; depends=&quot;compileTest&quot;&gt;
&lt;parallel&gt;
&lt;exec executable=&quot;${debugPlayerWin}&quot; spawn=&quot;no&quot; os=&quot;Windows XP&quot;&gt;
&lt;arg line=&quot;'${testHarness.swf}'&quot;/&gt;
&lt;/exec&gt;
&lt;exec executable=&quot;open&quot; spawn=&quot;no&quot; os=&quot;Mac OS X&quot;&gt;
&lt;arg line=&quot;${debugPlayerMac}&quot;	/&gt;
&lt;arg line=&quot;'${testHarness.swf}'&quot;/&gt;
&lt;/exec&gt;
&lt;sequential&gt;
&lt;waitfor&gt;
&lt;available file=&quot;${flashlog.location}&quot;/&gt;
&lt;/waitfor&gt;
&lt;waitfor&gt;
&lt;isfileselected file=&quot;${flashlog.location}&quot;&gt;
&lt;contains text=&quot;-----------------TESTRUNNEROUTPUTENDS----------------&quot;/&gt;
&lt;/isfileselected&gt;
&lt;/waitfor&gt;
&lt;/sequential&gt;
&lt;/parallel&gt;
&lt;/target&gt;
</pre>
<p>I&#8217;m planning to post my completed project build script and step through it in more detail than I did <a href="http://www.eyefodder.com/blog/2006/05/continuous_integration_with_fl_2.shtml">previously</a>. I&#8217;ve updated it quite a lot in the last year, and so far, I think its a lot neater. Before I do that, I&#8217;m going to post about my removing the python dependency from my continuous integration process.</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2007/06/cruisecontrol_on_the_mac_modif.html">CruiseControl on the Mac &#8211; modifying the build script to work x-platform</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2007/06/cruisecontrol_on_the_mac_modif.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlexUnit / ASUnit deathmatch results</title>
		<link>http://eyefodder.com/2006/07/flexunit_asunit_deathmatch_res.html</link>
		<comments>http://eyefodder.com/2006/07/flexunit_asunit_deathmatch_res.html#comments</comments>
		<pubDate>Sun, 02 Jul 2006 12:08:53 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Flash & Actionscript]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://localhost:8888/?p=19</guid>
		<description><![CDATA[<p>As I mentioned a few posts ago, I am looking into how asunit and flexunit can fit into our continuous integration set up. The move into AS3 has given me an opportunity to reassess how the 2 frameworks fit my/our needs. The prior post set out the criteria I was testing against &#8211; here is [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/07/flexunit_asunit_deathmatch_res.html">FlexUnit / ASUnit deathmatch results</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>As I mentioned a few <a href="http://www.eyefodder.com/blog/2006/06/unit_test_frameworks_for_as3_a.shtml">posts</a> ago, I am looking into how <a href="http://ww.asunit.org">asunit</a> and <a href="http://labs.adobe.com/wiki/index.php/ActionScript_3:resources:apis:libraries#FlexUnit">flexunit</a> can fit into our continuous integration set up. The move into AS3 has given me an opportunity to reassess how the 2 frameworks fit my/our needs. The prior post set out the criteria I was testing against &#8211; here is what I found&#8230;</p>
<p><span id="more-19"></span></p>
<h2>Overall</h2>
<p>Both frameworks seem to have followed the junit framework, and attempted a port from java to AS3. The good thing about  this is that there are very close similarities between usage of the two frameworks, and so switching from one to the other isn&#8217;t too much of a ballache. Both setups have the notion of a testRunner and resultPrinter, and I actually found that it was a very simple affair to adapt the <a href="http://www.eyefodder.com/blog/2006/06/flexunit_for_cruise_control_xm.shtml">code I wrote to use FlexUnit with Cruise Control</a> to work with ASUnit instead.</p>
<p>I did however find a problem when using the ASUnit testListener. When you run a test, the following methods get called on any testListeners you have (in my case its the CruiseControlResultPrinter):</p>
<ol>
<li>startTest</li>
<li>If an error / failure occurs:
<ul>
<li>addError</li>
<li>addFailure</li>
</ul>
</li>
<li>endTest</li>
</ol>
<p>The problem is that when startTest gets clled, the getCurrentMethod() method of the testCase returns null instead of the testMethod that is about to be executed. If you have had a nosy at my result printer code, you will see that I need this method to return the correct value when startTest gets called so I can append a testCase node with the method name as its &#8216;name&#8217; attribute. I managed to work around this by allowing a node to be added with a &#8216;null&#8217; value for its name; then when I try and access the testcase node, it first searches for a node with a matching name attribute, then for a node with a value of null for the name. I didn&#8217;t feel very comfortable with this, as it injects a weak link in my code. However, it wasn&#8217;t enough for me to strongly favour one framework over the other yet&#8230;</p>
<p>The next problem I had with ASUnit was unfortunately for me a show stopper. One of my criteria is that I am able to execute an asynchronous test (as well as asynchronous test setup). Unfortunately I didn&#8217;t manage to find a clean solution for doing this in ASUnit. There was a <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=14658324&amp;forum_id=42743">discussion on the mailing list </a>about how one might go about doing this, but unfortunately I couldnt find a solution that worked within my requirements. Luke made a very good point about the difference between asynchronous and event-driven, but nevertheless I still couldnt get an async test to work and correctly report back before the alltestscomplete event gets triggered with the test suite.</p>
<p>One of my other criteria was also that the framework didnt rely on Flex. For me right now, this is secondary as my current work is using Flex. However, it is still important to me to be able to have the ability to build a test suite for a flash based project. As far as I can see, the only real reliance Flexunit has on flex is the testRunner / result printer that ships with the framework. This would mean that if I needed to, I could build a flash only test runner. I think that the name flexunit doesn&#8217;t help, and if it were me, I&#8217;d be tempted to find a different name.</p>
<p>I also really like the ability to automatically create test suites that ASUnit provides. <a href="http://www.lennel.org/blog/2006/02/27/building-unit-tests-in-eclipse-from-an-ant-script-for-asunit/">Johannes pulled out the functionality for this to enable us to do this as a python script,</a> so I guess with different templates, you could get this working for flexunit.</p>
<h2>In conclusion</h2>
<p>If you have got this far, I guess you will have worked out that I will be going with flexunit for the time being. I&#8217;m kind of sad about this &#8211; I suppose I&#8217;m quite attached to ASUnit, as Ive been using it for a year and a half, and I really like the community spirit behind it. Ultimately though, it doesnt quite do what I need, and I really didnt want to get deeply under the hood of the framework code. I&#8217;m going to keep a very open mind on this decision, and see how asunit progresses. If anyone has anything to add to sway my decision one way or the other, I&#8217;d love to hear it too&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/07/flexunit_asunit_deathmatch_res.html">FlexUnit / ASUnit deathmatch results</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2006/07/flexunit_asunit_deathmatch_res.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FlexUnit UI factory</title>
		<link>http://eyefodder.com/2006/06/flexunit_ui_factory.html</link>
		<comments>http://eyefodder.com/2006/06/flexunit_ui_factory.html#comments</comments>
		<pubDate>Fri, 16 Jun 2006 15:19:51 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Flash & Actionscript]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://localhost:8888/?p=17</guid>
		<description><![CDATA[<p>When I started looking into how we could use flexunit in our CI build, I was struck by how the UI is closely linked to the actual running of the test suite. I really wanted to be able to use the supplied flexunit GUI out of the box &#8211; after all, it does everything the [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/06/flexunit_ui_factory.html">FlexUnit UI factory</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>When I started looking into how we could use flexunit in our CI build, I was struck by how the UI is closely linked to the actual running of the test suite. I really wanted to be able to use the supplied flexunit GUI out of the box &#8211; after all, it does everything the developer needs, and yet in order to have the results understood by our build process, we would need the results <a href="http://www.eyefodder.com/blog/2006/06/flexunit_for_cruise_control_xm.shtml">printed out differently</a>.</p>
<p>To acheive this, my Flexunit test harness uses a factory method pattern to decide how torunthe test suite. Here&#8217;s how&#8230;</p>
<p><span id="more-17"></span></p>
<p>I first started by taking the skeleton flexunit testsuite implementation outlined by Darron Schall <a href="http://www.darronschall.com/weblog/archives/000216.cfm">here</a>. Next, I removed the testRunner MXML node, and changed my creationComplete function to look like this:</p>
<pre class="brush: as3; title: ; notranslate">
private function onCreationComplete():void{
	var testRunner:IFlexUnitUI = FlexUnitUIFactory.createUI();
	var visualTR:UIComponent = testRunner as UIComponent;
	addChild(visualTR)
	visualTR.percentWidth = 100;
	visualTR.percentHeight = 100;
	testRunner.setTest(createSuite());
	testRunner.startTest();
}
</pre>
<p>OK, so far this doesnt really tell you guys much, so lets delve a little deeper into whats going on&#8230; my test runner satisfies an interface that simply allows me to set a test and start a test. This decouples the way we run our tests (and display our results) from the main testHarness. The <a href="http://www.eyefodder.com/blog/downloads/IFlexUnitUI.as">flexUnitUIFactory</a><br />
is a very simple interface:</p>
<pre class="brush: as3; title: ; notranslate">package com.fmr.flexunit
{
	import flexunit.framework.TestSuite;
	public interface IFlexUnitUI
	{
		function setTest(t:TestSuite):void;
		function startTest():void;
	}
}</pre>
<p>Now, lets look at the factory itself:</p>
<pre class="brush: as3; title: ; notranslate">package com.fmr.flexunit
{
	import flash.system.Capabilities;
	//creates an IFlexUnit UI for use by the test harness.
	// the idea is that one can have either visual feedback, or a lightweight text feedback, depending on requirements
	public class FlexUnitUIFactory
	{
		public static function createUI():IFlexUnitUI{
		var environment:String = Capabilities.playerType;
		var outObj:IFlexUnitUI;
		switch(environment){
			case &quot;StandAlone&quot;:
				outObj = new TextOutputUI();
				break;
			case &quot;PlugIn&quot;:
			default:
				outObj = new FlexUnitUI();
				break;
			}
			return outObj;
		}
	}
}</pre>
<p>The factory is actually very simple &#8211; it chooses a TextOutputUI if its running in a standalone player (and thus being run as an ANT build), or uses a pretty GUI if in the browser (thus being run by the developer). Each of these UI&#8217;s must satisfy our interface, and so I needed to subclass the flexunit GUI to get it to satisfy the interface:</p>
<pre class="brush: as3; title: ; notranslate">package com.fmr.flexunit
{
	import flexunit.flexui.TestRunnerBase;
	import flash.events.Event;
	import flexunit.framework.TestSuite;
	public class FlexUnitUI extends TestRunnerBase implements IFlexUnitUI
	{
		public static var testsCompleteEvent:String = &quot;testsComplete&quot;;
		override public function onAllTestsEnd() : void {
			super.onAllTestsEnd();
			dispatchEvent(new Event(testsCompleteEvent));
		}
		public function setTest(t:TestSuite):void{
			test = t;
		}
	}
}</pre>
<p>The TextOutputUI uses our CruiseControl friendly outputting classes, and is simply a VBox (as we need our elememnt to be a IUObject that can be atached to our main app):</p>
<pre class="brush: xml; title: ; notranslate">&lt;mx:VBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot; height=&quot;100%&quot; implements=&quot;com.fmr.flexunit.IFlexUnitUI&quot;&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
	import flexunit.framework.TestSuite;
	import flexunit.textui.TestRunner;
	public var test:TestSuite;
	public function setTest(t:TestSuite):void{
		test = t
	}
	public function startTest():void{
		CruiseControlTestRunner.run( test, onTestsComplete );
	}
	private function onTestsComplete():void{
		fscommand(&quot;quit&quot;);
	}
]]&gt;
&lt;/mx:Script&gt;
&lt;/mx:VBox&gt;</pre>
<p>Notice also that in our textOutputUI, when the tests are complete, the app is told to quit &#8211; this is a requirement of our ANT build process as once the unit tests are run, the main app should be built.</p>
<p>And that&#8217;s basically it. Using this method, our test harness can run differently depending on its environment. I havent had a chance to test this in the field yet, but I&#8217;ll let you know how it all works out&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/06/flexunit_ui_factory.html">FlexUnit UI factory</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2006/06/flexunit_ui_factory.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FlexUnit for Cruise Control &#8211; XML output</title>
		<link>http://eyefodder.com/2006/06/flexunit_for_cruise_control_xm.html</link>
		<comments>http://eyefodder.com/2006/06/flexunit_for_cruise_control_xm.html#comments</comments>
		<pubDate>Fri, 16 Jun 2006 13:43:53 +0000</pubDate>
		<dc:creator><![CDATA[Paul Barnes-Hoggett]]></dc:creator>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Flash & Actionscript]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://localhost:8888/?p=16</guid>
		<description><![CDATA[<p>If you read my earlier posts on Flex and continuous integration, you will remember that we had to do some work to get ASUnit to spit out its results in a manner that would be understood by Cruise Control. We built a log parser to parse results from the Flash players trace file into an [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/06/flexunit_for_cruise_control_xm.html">FlexUnit for Cruise Control &#8211; XML output</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>If you read my earlier posts on Flex and continuous integration, you will remember that we had to <a href="http://www.eyefodder.com/blog/2006/05/continuous_integration_with_fl_3.shtml">do some work</a> to get ASUnit to spit out its results in a manner that would be understood by Cruise Control. We <a href="http://www.eyefodder.com/blog/2006/05/continuous_integration_with_fl_4.shtml">built a log parser</a> to parse results from the Flash players trace file into an XML file detailing the unit test results, and also a simple status file saying if the test suite succeeded or failed. Here&#8217;s how I got FlexUnit to print out results that will be understood by our parser&#8230;</p>
<p><span id="more-16"></span></p>
<p>I based my work here on how the flexunit.textui.TestRunner and flexunit.textui.ResultPrinter class work. I created two classes: CruiseControlTestRunner and CruiseControlResultPrinter.</p>
<h2>CruiseControlTestRunner</h2>
<p>This class is incredibly similar to TestRunner. In fact the only difference is that our private variable printer is set up to use our other new class &#8211; CruiseControlResultPrinter. If this variable had been declared protected, then I would have subclassed TestRunner and simply changed the setup of the printer to use our new class&#8230; <a href="http://www.eyefodder.com/blog/downloads/CruiseControlTestRunner.as">You can download the file here</a></p>
<h2>CruiseControlTestPrinter</h2>
<p>The printer is a little more involved, but still not too tricky. what I do here is create an XML Object and append results as they come through. TestListeners (the interface that the printer implements) have functions that get triggered when a test starts and ends, and also if a test fails, or if there is an error. These can be used to construct our XML as the suite runs. Lets look at the class bit by bit: (or you can just <a href="http://www.eyefodder.com/blog/downloads/CruiseControlResultPrinter.as">download the class and get started</a></p>
<h3>Constructor</h3>
<p>Dead simple, we just initialize our XML with a top-level node:</p>
<pre class="brush: as3; title: ; notranslate">public function CruiseControlResultPrinter()
{
	__resultXML = new XML(&quot;&quot;);
}</pre>
<h3>startTest</h3>
<p>When a test starts, we want to append a testcase node to our XML. Each testcase node actually needs to sit in a testsuite node, so I created a helper function to automatically create a testsiute node for the testcase if one doesnt exist (ie if its the first test run in a particular Test Class):</p>
<pre class="brush: as3; title: ; notranslate"> public function startTest( test:Test ):void
{
	var suiteNode:XML = getSuiteNode(test)
	suiteNode.appendChild(new XML(&quot;&quot;));
	__testTimer = getTimer();
}
//------------------------------------------------------------------------------
private function getSuiteNode (test:Test):XML{
	var outNode:XML = __resultXML.testsuite.(@name==test.className)[0];
	if(outNode==null){
	outNode = new XML(&quot;&quot;);
	__resultXML.appendChild(outNode);
}
return outNode;
}</pre>
<h3>addError / addFailure</h3>
<p>When a test fails or errors, we need to append failure details to the testcase node. The child node is named either failure or error depending on the type of problem (these nodes get displayed differently in CruiseControl). A child node populated with the stack trace is appended to the testcase node:</p>
<pre class="brush: as3; title: ; notranslate">
public function addError( test:Test, error:Error ):void{
	onFailOrError(test,error,&quot;error&quot;);
}
//------------------------------------------------------------------------------
public function addFailure( test:Test, error:AssertionFailedError ):void{
	onFailOrError(test,error,&quot;failure&quot;);
}
private function onFailOrError(test:Test,error:Error, failOrError:String):void{
	__suiteSuccess = false;
	var testNode:XML = getTestNode(test);
	var childNode:XML = new XML(&quot;&amp;lt;&quot;+failOrError+&quot;&amp;gt;&quot;+error.getStackTrace()+&quot;&lt;!--&quot;+failOrError+&quot;--&gt;&quot;);
	testNode.appendChild(childNode);
}
private function getTestNode(test:Test):XML{
	return __resultXML.testsuite.testcase.(@name==TestCase(test).methodName)[0];
}</pre>
<h3>endTest</h3>
<p>If you look at the startTest code, you will see that we set a __testTimer variable. This comes into play in the endTest callback, where we set the execution time of the test Case:</p>
<pre class="brush: as3; title: ; notranslate">
public function endTest( test:Test ):void
{
	var testNode:XML = getTestNode(test);
	testNode.@time = (getTimer() - __testTimer)/1000;
}</pre>
<h3>print</h3>
<p>When the test suite is complete, the TestRunner calls the print function on our class. This is actually now a much simpler affair than the one I previously wrote for ASUnit (although I will be revisiting this for ASUnit for AS3 over the next few days&#8230;). It simply traces out our generated XML, and also includes the line at the bottom specifying test Suite success (this is read by our ANT build):</p>
<pre class="brush: as3; title: ; notranslate">
public function print( result:TestResult, runTime:Number ):void
{
	printHeader(runTime);
	printMain();
	printFooter(result);
}
private function printHeader( runTime:Number ):void
{
	trace(&quot;-----------------TESTRUNNEROUTPUTBEGINS----------------&quot;);
}
private function printMain():void{
	trace(__resultXML);
}
private function printFooter( result:TestResult ):void
{
	trace(&quot;Test Suite success: &quot;+(result.errorCount()+result.failureCount()==0)+&quot;n&quot;);
	trace(&quot;-----------------TESTRUNNEROUTPUTENDS----------------&quot;);
}</pre>
<p>And that&#8217;s basically it.. My next post is going to be about how I actually went about implementing these classes and got the test siute to display results differently depending on whether it was being run by the developer or as part of an ANT build&#8230;</p>
<p>The post <a rel="nofollow" href="http://eyefodder.com/2006/06/flexunit_for_cruise_control_xm.html">FlexUnit for Cruise Control &#8211; XML output</a> appeared first on <a rel="nofollow" href="http://eyefodder.com">Eyefodder</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://eyefodder.com/2006/06/flexunit_for_cruise_control_xm.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
