<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Railsware blog</title>
	
	<link>http://blog.railsware.com</link>
	<description>Benefit Driven Approach</description>
	<lastBuildDate>Tue, 21 Feb 2012 13:45:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/railsware" /><feedburner:info uri="railsware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Highrise Assist – enhance your possibilities in Highrise</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/MWfQspMf9LE/</link>
		<comments>http://blog.railsware.com/2012/02/06/1232/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 14:22:09 +0000</pubDate>
		<dc:creator>Rodion Vshevtsov</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[highrise 37signals gem]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1232</guid>
		<description><![CDATA[highrise_assist is command line tool for 37signals&#8217; highrise. Description If you are using http://highrisehq.com/, you definitely can notice that there are some processes in your company, that doesn&#8217;t fit to the functionality implemented by 37signals&#8217; team. Fortunately, they have quite strong API, that can be used for custom purposes. In our company we have bunch [...]]]></description>
			<content:encoded><![CDATA[<p><strong>highrise_assist</strong> is command line tool for 37signals&#8217; highrise.</p>

<h2>Description</h2>

<p>If you are using <a href="http://highrisehq.com/">http://highrisehq.com/</a>, you definitely can notice that there are some processes in your company, that doesn&#8217;t fit to the functionality implemented by 37signals&#8217; team. Fortunately, they have quite strong API, that can be used for custom purposes. In our company we have bunch of such customizations, that we have decided to group into the gem and deliver to the community. The first tool allows to export companies and contacts by tag (read more below). So <strong>highrise_assist</strong> is a command line set of tools, which let you do custom operations with your data in highrise.</p>

<h2>Installation</h2>

<pre style="padding: 10px; background-color: #000000; color: #00ff00;">$ gem install highrise_assist</pre>

<h2>Usage</h2>

<pre style="padding: 10px; background-color: #000000; color: #00ff00;">Usage: ./bin/highrise_assist COMMAND [options]

Commands:
  * export - export next highrise items:
  * cases
  * deals
  * people
  * companies
  * emails
  * notes
  * comments
  * attachments

Common options:
        --domain DOMAIN              highrise subdomain or full domain name
        --token TOKEN                highrise API authentication token
Export options:
        --tag TAG                    filter items with given tag name
        --directory DIRECTORY        working directory
        --format FORMAT              data format (yaml,xml)
        --skip-attachments           don't download attachments
        --skip-cases                 don't export cases
        --skip-deals                 don't export deals
        --skip-notes                 don't export notes
        --skip-emails                don't export emails
        --skip-comments              don't export comments

Misc options:
    -h, --help                       Show this message
    -v, --version                    Show version
</pre>

<h2>Export Command</h2>

<h3>Description</h3>

<p>If you are the using highrise for sales, human resources or some other activities, one day you will want to export data from the system. Here is the original article <a href="http://bit.ly/sTQr1W">http://bit.ly/sTQr1W</a>, which is describing the process. It&#8217;s quite easy and works fine, but with <strong>highrise_assist</strong> export you can do much better. This tool provides you with possibility to export companies and contacts with all the hierarchy of data including emails, notes, comments, cases, deals and even attachments (with web console you just don&#8217;t have such  possibility) in xml or yaml formats. It is possible to mark exact business objects with the tag and then just export them.</p>

<h4>The use case 1:</h4>

<p>As user of highrise
I want to archive old contacts and companies 
So that my list will be clean</p>

<p>Original help request: <a href="http://bit.ly/tIDlwk">http://bit.ly/tIDlwk</a>
What 37signals&#8217; team recommends: &#8220;Have you considered adding a tag to those contacts called &#8220;archived&#8221;?&#8221;
With <strong>highrise_assist</strong> export you can easily export all the data tagged as &#8220;archived&#8221;, and than just remove data from the system.</p>

<h4>The use case2:</h4>

<p>As user of highrise
I want to export all my data including attachments
So that I can move data to the other management systems</p>

<p>With <strong>highrise_assist</strong> export you can easily do this operation.</p>

<h2>Keep your highrise always clean!</h2>

<h3>Synopsis</h3>

<pre style="padding: 10px; background-color: #000000; color: #00ff00;">$ highrise_assist export OPTIONS</pre>

<h3>Example</h3>

<pre style="padding: 10px; background-color: #000000; color: #00ff00;">$ highrise_assist export \
  --domain MYSUBDOMAIN \
  --token 11111111111111111111111111111111 \
  --directory highrise_data \
  --tag old-clients \
  --format xml \
  --skip-attachments
</pre>

<h3>Export result:</h3>

<pre style="padding: 10px; background-color: #000000; color: #00ff00;">$ tree --dirsfirst
.
├── cases
│   ├── case-573785-test-case
│   │   ├── attachments
│   │   │   └── 22039573-20111111-p7km4bk33ugutcrrb5mxxw7fjj.jpeg
│   │   ├── case-573785-test-case.xml
│   │   └── note-78169727-test.xml
│   └── case-573786-what-is-highrise
│       ├── attachments
│       └── case-573786-what-is-highrise.xml
├── deals
│   └── deal-1471928-test-deal
│       ├── attachments
│       ├── deal-1471928-test-deal.xml
│       └── note-78499917.xml
└── persons
    └── person-92632832-test-test
        ├── attachments
        ├── cases
        │   └── case-573785-test-case -> ../../../cases/case-573785-test-case
        ├── deals
        │   └── deal-1471928-test-deal -> ../../../deals/deal-1471928-test-deal
        └── person-92632832-test-test.xml
</pre>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;count=horizontal&amp;text=Highrise%20Assist%20%26%238211%3B%20enhance%20your%20possibilities%20in%20Highrise" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;count=horizontal&amp;text=Highrise%20Assist%20%26%238211%3B%20enhance%20your%20possibilities%20in%20Highrise" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;linkname=Highrise%20Assist%20%26%238211%3B%20enhance%20your%20possibilities%20in%20Highrise" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;linkname=Highrise%20Assist%20%26%238211%3B%20enhance%20your%20possibilities%20in%20Highrise" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F02%2F06%2F1232%2F&amp;title=Highrise%20Assist%20%26%238211%3B%20enhance%20your%20possibilities%20in%20Highrise" id="wpa2a_2"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/MWfQspMf9LE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/02/06/1232/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/02/06/1232/</feedburner:origLink></item>
		<item>
		<title>Capybara with Given/When/Then steps in acceptance testing</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/vBTokpP80ew/</link>
		<comments>http://blog.railsware.com/2012/01/08/capybara-with-givenwhenthen-steps-in-acceptance-testing/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 23:15:54 +0000</pubDate>
		<dc:creator>ayanko</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[acceptance]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[steps]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1213</guid>
		<description><![CDATA[Capybara with Given/When/Then steps in acceptance testing. Many of us use cucumber to write acceptance tests. We must to say it&#8217;s very nice tool that allows you to write features in English plain text. The main goal is provide interface that should be clear for Customer(non-programmer) and Developer. Cucumber example: Feature: User signup As a [...]]]></description>
			<content:encoded><![CDATA[<p>Capybara with Given/When/Then steps in acceptance testing.</p>
<p>Many of us use <a href="http://cukes.info/">cucumber</a> to write acceptance tests.<br />
We must to say it&#8217;s very nice tool that allows you to write features in English plain text.<br />
The main goal is provide interface that should be clear for Customer(non-programmer) and Developer.</p>
<h3>Cucumber example:</h3>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1">Feature: User signup
  As a user
  I want to sign <span class="kw1">in</span>
  So I can use service features
&nbsp;
  Background:
    Given user with <span class="st0">&quot;jack@daniles.com&quot;</span> email <span class="kw1">and</span> <span class="st0">&quot;qwerty&quot;</span> password
&nbsp;
  Scenario: Signing <span class="kw1">in</span> with correct credentials
    <span class="kw1">When</span> I go to sign <span class="kw1">in</span> page
    <span class="kw1">And</span> I fill <span class="kw1">in</span> <span class="st0">&quot;email&quot;</span> with <span class="st0">&quot;jack@daniles.com&quot;</span>
    <span class="kw1">And</span> I fill <span class="kw1">in</span> <span class="st0">&quot;password&quot;</span> with <span class="st0">&quot;qwerty&quot;</span>
    <span class="kw1">And</span> I click <span class="st0">&quot;Login&quot;</span> button
    <span class="kw1">Then</span> I should see <span class="st0">&quot;Welcome, jack@daniles.com!&quot;</span>
&nbsp;
  Scenario: User tries to sign <span class="kw1">in</span> with incorrect password
    <span class="kw1">When</span> I go to sign <span class="kw1">in</span> page
    <span class="kw1">And</span> I fill <span class="kw1">in</span> <span class="st0">&quot;email&quot;</span> with <span class="st0">&quot;jack@daniles.com&quot;</span>
    <span class="kw1">And</span> I fill <span class="kw1">in</span> <span class="st0">&quot;password&quot;</span> with <span class="st0">&quot;bla&quot;</span>
    <span class="kw1">And</span> I click <span class="st0">&quot;Login&quot;</span> button
    <span class="kw1">Then</span> I should see <span class="st0">&quot;Invalid credentials&quot;</span></pre></div></div></div></div></div></div></div>


<p>It&#8217;s very readable. But cucumber has one big downside:</p>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
Steps maintenance
</pre>
<p>All steps are global and a instance variable from one step is accessible in another step.<br />
In big project it can easy lead to mess.<br />
Also you can read some rants about cucumber:</p>
<ul>
<li><a href="http://www.software-testing.com.au/blog/2010/08/31/does-cucumber-suck/">Does cucumber suck?</a></li>
<li><a href="http://blog.codegram.com/2011/5/why-cucumber-sucks-and-i-still-love-it">Why Cucumber sucks and I still love it</a></li>
<li><a href="https://gist.github.com/770894">Why Steak (over Cucumber)</a></li>
</ul>
<p>Previously we also use cucumber as tool for user stories.<br />
Lately we found that our customers <strong>NEVER</strong> read cucumber features.<br />
So do we need it anymore? Let&#8217;s check alternatives.</p>
<p>As you probably know, cucumber use internally <a href="https://github.com/jnicklas/capybara">Capybara</a> for steps implementation. And there is even more &#8211; latest version of Capybara comes with a built in DSL for creating descriptive acceptance tests!</p>
<p>So we decided to switch to pure rspec+capybara testing.<br />
We moved our features to <em>spec/acceptance</em> directory.<br />
Let&#8217;s look at rspec+capybara example.</p>
<h3>RSpec+Capybara example</h3>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
$ cat spec/acceptance/signup_feature_spec.rb
</pre>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1">feature <span class="st0">&quot;User signup&quot;</span> <span class="kw1">do</span>
  background <span class="kw1">do</span>
    <span class="re1">@user</span> = Factory<span class="br0">&#40;</span><span class="re3">:user</span>, <span class="re3">:email</span> <span class="sy0">=&gt;</span> <span class="st0">'jack@daniles.com'</span>, <span class="re3">:password</span> <span class="sy0">=&gt;</span> <span class="st0">'qwerty'</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  scenario <span class="st0">&quot;Signing in with correct credentials&quot;</span> <span class="kw1">do</span>
    page.<span class="me1">visit</span> <span class="st0">&quot;/sessions/new&quot;</span>
    page.<span class="me1">fill_in</span> <span class="st0">&quot;email&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;jack@daniles.com&quot;</span>
    page.<span class="me1">fill_in</span> <span class="st0">&quot;password&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;qwerty&quot;</span>
    page.<span class="me1">click_button</span> <span class="st0">&quot;Login&quot;</span>
    page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Welcome, jack@daniles.com!&quot;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  scenario <span class="st0">&quot;User tries to sign in with incorrect password&quot;</span> <span class="kw1">do</span>
    page.<span class="me1">visit</span> <span class="st0">&quot;/sessions/new&quot;</span>
    page.<span class="me1">fill_in</span> <span class="st0">&quot;email&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;jack@daniles.com&quot;</span>
    page.<span class="me1">fill_in</span> <span class="st0">&quot;password&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;bla&quot;</span>
    page.<span class="me1">click_button</span> <span class="st0">&quot;Login&quot;</span>
    page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Invalid credentials&quot;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<p>Thus approach has one big benefit:</p>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
Feature description and feature implementation are located together.
</pre>
<p>You don&#8217;t need anymore to jump between feature and step files to guess where is implementation for a step.<br />
It&#8217;s nice but there are also two downsides.</p>
<p>First downsides is that RSpec documentation output will be too poor and it&#8217;s not enough informative:</p>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
$ rspec -fs -c spec/acceptance/signup_feature_spec.rb

User signup
  Signing in with correct credentials
  User tries to sign in with incorrect password

Finished in 13.55 seconds
2 examples, 0 failures
</pre>
<p>Second downside is that scenario does not have anymore exact boundary blocks or steps.<br />
It makes harder to understand the scenario flow.</p>
<p>Real user story often has big scenarios and we realized that cucumber steps were cool.</p>
<p>There were two ways:</p>
<ul>
<li>switch back to cucumber</li>
<li>go further and invent</li>
</ul>
<p><a href="http://railsware.com/team">Railswarians</a> never go back <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Our Solution</h3>
<p>If you decided to switch from Cucumber to Capybara acceptance testing try <a href="https://github.com/railsware/rspec-example_steps">rspec-example steps</a> gem.</p>
<p>With this gem you may use <em>Given/When/Then</em> steps into rspec example!</p>
<h3>RSpec+Capybara+Steps example</h3>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1">feature <span class="st0">&quot;User signup&quot;</span> <span class="kw1">do</span>
  background <span class="kw1">do</span>
    <span class="re1">@user</span> = Factory<span class="br0">&#40;</span><span class="re3">:user</span>, <span class="re3">:email</span> <span class="sy0">=&gt;</span> <span class="st0">'jack@daniles.com'</span>, <span class="re3">:password</span> <span class="sy0">=&gt;</span> <span class="st0">'qwerty'</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  Steps <span class="st0">&quot;Signing in with correct credentials&quot;</span> <span class="kw1">do</span>
    <span class="kw1">When</span> <span class="st0">&quot;I go to sign in page&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">visit</span> <span class="st0">&quot;/sessions/new&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I fill in right email&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">fill_in</span> <span class="st0">&quot;email&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="re1">@user</span>.<span class="me1">email</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I fill in  right password&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">fill_in</span> <span class="st0">&quot;password&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;qwerty&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I click login&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">click_button</span> <span class="st0">&quot;Login&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">Then</span> <span class="st0">&quot;I should see greeting&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Welcome, #{@user.email}!&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  Steps <span class="st0">&quot;User tries to sign in with incorrect password&quot;</span> <span class="kw1">do</span>
    <span class="kw1">When</span> <span class="st0">&quot;I go to sign in page&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">visit</span> <span class="st0">&quot;/sessions/new&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I fill in right email&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">fill_in</span> <span class="st0">&quot;email&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="re1">@user</span>.<span class="me1">email</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I fill in wrong password&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">fill_in</span> <span class="st0">&quot;password&quot;</span>, <span class="re3">:with</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;bla&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">And</span> <span class="st0">&quot;I click login&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">click_button</span> <span class="st0">&quot;Login&quot;</span>
    <span class="kw1">end</span>
    <span class="kw1">Then</span> <span class="st0">&quot;I should see error&quot;</span> <span class="kw1">do</span>
      page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Invalid credentials&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<p>And documentation output will be:</p>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
$ rspec -fs -c spec/acceptance/signup_feature_spec.rb
</pre>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
User signup
  Signing in with correct credentials
    When I go to sign in page
    And I fill in right email
    And I fill in right password
    And I click login" do
    Then I should see greeting
  User tries to sign in with incorrect password
    When I go to sign in page
    And I fill in right email
    And I fill in wrong password
    And I click login
    Then I should see error

Finished in 13.55 seconds
2 examples, 0 failures
</pre>
<p>Now it&#8217;s much better. Isn&#8217;t it? <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>RSpec Example Steps features</h3>
<ul>
<li>Does not hack RSpec Example. It only extends it.</li>
<li>Brings Given/When/Then/And/But steps support into rspec example block that allow you to better organize scenario</li>
<li>Adds shared_steps DSL</li>
<li>Adds ability to mark step as pending</li>
<li>Reports with color about passed/pending/failed step into documentation formating output</li>
</ul>
<h3>Installation</h3>
<pre style="padding:10px;background-color:#000000;color:#00ff00">
$ gem install rspec-example_steps
</pre>
<h3>Usage</h3>
<p>See <a href="https://github.com/railsware/rspec-example_steps/blob/master/README.md">README</a> for more details.</p>
<p>Just add to <em>spec/spec_helper.rb</em></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'rspec/example_steps'</span></pre></div></div></div></div></div></div></div>


<p>And enjoy Given/When/Then step usage!</p>
<h3>References</h3>
<ul>
<li><a href="https://github.com/railsware/rspec-example_steps">rspec-example_steps</a></li>
<li><a href="https://github.com/cucumber/cucumber">cucumber</a></li>
<li><a href="https://github.com/LRDesign/rspec-steps">rspec-steps</a></li>
</ul>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;count=horizontal&amp;text=Capybara%20with%20Given%2FWhen%2FThen%20steps%20in%20acceptance%20testing" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;count=horizontal&amp;text=Capybara%20with%20Given%2FWhen%2FThen%20steps%20in%20acceptance%20testing" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;linkname=Capybara%20with%20Given%2FWhen%2FThen%20steps%20in%20acceptance%20testing" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;linkname=Capybara%20with%20Given%2FWhen%2FThen%20steps%20in%20acceptance%20testing" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F08%2Fcapybara-with-givenwhenthen-steps-in-acceptance-testing%2F&amp;title=Capybara%20with%20Given%2FWhen%2FThen%20steps%20in%20acceptance%20testing" id="wpa2a_4"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/vBTokpP80ew" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/01/08/capybara-with-givenwhenthen-steps-in-acceptance-testing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/01/08/capybara-with-givenwhenthen-steps-in-acceptance-testing/</feedburner:origLink></item>
		<item>
		<title>Accessing application session in capybara</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/H6_KI1nVSM8/</link>
		<comments>http://blog.railsware.com/2012/01/07/accessing-application-session-in-capybara/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 12:00:57 +0000</pubDate>
		<dc:creator>ayanko</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[rack]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1200</guid>
		<description><![CDATA[Trouble There are some cases when you may need to access application session in your tests: User signup or registration flow is too long. Application use another backend and store result into session. In each story you must repeat the same steps. You can actually use some shared code but it does not speed-up tests [...]]]></description>
			<content:encoded><![CDATA[<h2>Trouble</h2>
<p>There are some cases when you may need to access application session in your tests:</p>
<ul>
<li>User signup or registration flow is too long.</li>
<li>Application use another backend and store result into session.</li>
</ul>
<p>In each story you must repeat the same steps. You can actually use some shared code but it does not speed-up tests anyway.</p>
<p>Nowadays if you want to access session in cucumber/capybara acceptance test you are in trouble.</p>
<p>Capybara&#8217; <a href="https://github.com/jnicklas/capybara/blob/master/README.md">README</a> says:</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
  Access to session and request is not possible from the test ...
</pre>
<p>And it&#8217;s true <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Rescue</h2>
<p>So is it actually possible to access session? Actually yes <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Instead of trying to hack capybara you may just extend your application in test environment!<br />
Just add some code that modify session according to given request parameters.</p>
<p>If you use rack based application then your are lucky &#8211;<br />
try <a href="https://github.com/railsware/rack_session_access">rack_session_access</a> gem.</p>
<p>If it&#8217;s another application you need implement concept yourself <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This gem should work with any rack application. We covered it with acceptance testing against:</p>
<ul>
<li>rack builder application</li>
<li>sinatra application</li>
<li>rails3 application</li>
</ul>
<h2>Usage</h2>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
  $ gem install rack_session_access
</pre>
<p>See <a href="https://github.com/railsware/rack_session_access/blob/master/README.md">README</a> for usage examples.</p>
<h2>Rails + Rspec + Capybara example</h2>
<p>Add to <em>spec/spec_helper.rb</em>:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'capybara/rspec'</span>
<span class="kw3">require</span> <span class="st0">'rack_session_access/capybara'</span>
&nbsp;
Rails.<span class="me1">application</span>.<span class="me1">config</span> <span class="kw1">do</span>
  config.<span class="me1">middleware</span>.<span class="me1">use</span> <span class="re2">RackSessionAccess::Middleware</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<p>And use <strong>set_rack_session</strong> helper in acceptance test:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'spec_helper'</span>
&nbsp;
feature <span class="st0">&quot;My feature&quot;</span> <span class="kw1">do</span>
  background <span class="kw1">do</span>
    <span class="re1">@user</span> = Factory<span class="br0">&#40;</span><span class="re3">:user</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
  scenario <span class="st0">&quot;logged in user goes to profile page&quot;</span> <span class="kw1">do</span>
    <span class="co1"># read your authorization engine manual how it store user into session</span>
    page.<span class="me1">set_rack_session</span><span class="br0">&#40;</span><span class="re3">:user_id</span> <span class="sy0">=&gt;</span> <span class="re1">@user</span>.<span class="me1">id</span><span class="br0">&#41;</span>
    page.<span class="me1">visit</span> <span class="st0">'/profile'</span>
    ...
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<h2>Conclusion</h2>
<p>Enjoy faster testing!</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/jnicklas/capybara">capybara</a></li>
<li><a href="https://github.com/railsware/rack_session_access">rack_session_access</a></li>
</ul>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;count=horizontal&amp;text=Accessing%20application%20session%20in%20capybara" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;count=horizontal&amp;text=Accessing%20application%20session%20in%20capybara" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;linkname=Accessing%20application%20session%20in%20capybara" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;linkname=Accessing%20application%20session%20in%20capybara" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Faccessing-application-session-in-capybara%2F&amp;title=Accessing%20application%20session%20in%20capybara" id="wpa2a_6"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/H6_KI1nVSM8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/01/07/accessing-application-session-in-capybara/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/01/07/accessing-application-session-in-capybara/</feedburner:origLink></item>
		<item>
		<title>Testing gem integration with multiple ruby frameworks</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/MY7yaoNa16A/</link>
		<comments>http://blog.railsware.com/2012/01/07/testing-gem-integration-with-multiple-ruby-frameworks/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 10:45:36 +0000</pubDate>
		<dc:creator>ayanko</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1196</guid>
		<description><![CDATA[Preface When you develop some cool gem that should work in different ruby frameworks you definitely should write acceptance tests. Nowadays it&#8217;s pretty easy to do with RSpec+Capybara. Your goal Assume you develop MyRackMiddleware gem that should work in Sinatra and Rails application. Your actions Create gem layout To create layout use well-known bundle gem [...]]]></description>
			<content:encoded><![CDATA[<h2>Preface</h2>
<p>When you develop some cool gem that should work in different ruby frameworks<br />
you definitely should write acceptance tests.</p>
<p>Nowadays it&#8217;s pretty easy to do with RSpec+Capybara.</p>
<h2>Your goal</h2>
<p>Assume you develop MyRackMiddleware gem that should work in Sinatra and Rails application.</p>
<h2>Your actions</h2>
<h3>Create gem layout</h3>
<p>To create layout use well-known <em>bundle gem</em> command:</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
$ bundle gem my_rack_middleware
</pre>
<p>It&#8217;s generate something like:</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
├── lib
│   ├── my_rack_middleware
│   │   └── version.rb
│   └── my_rack_middleware.rb
├── Gemfile
├── my_rack_middleware.gemspec
└── Rakefile
</pre>
<p>Add to <em>Gemfile</em> :</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1">source <span class="st0">&quot;http://rubygems.org&quot;</span>
&nbsp;
gemspec
&nbsp;
gem <span class="st0">'rspec'</span>
gem <span class="st0">'capybara'</span>
&nbsp;
gem <span class="st0">'sinatra'</span>
gem <span class="st0">'rails'</span></pre></div></div></div></div></div></div></div>


<p>Now start use BDD <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Before start implementation we need two sample applications.<br />
Let&#8217;s put they into <em>apps</em> directory.</p>
<h3>Creating Sinatra test application</h3>
<p>Thus Sinatra is simple framework it&#8217;s trivial to create test application:</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
$ cat apps/test_sinatra_app.rb
</pre>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'sinatra'</span>
<span class="kw1">class</span> TestSinatraApp <span class="sy0">&lt;</span> <span class="re2">Sinatra::Base</span>
  enable <span class="re3">:sessions</span>
&nbsp;
  get <span class="st0">'/login'</span> <span class="kw1">do</span>
    body <span class="st0">&quot;Please log in&quot;</span>
  <span class="kw1">end</span>
&nbsp;
  post <span class="st0">'/login'</span> <span class="kw1">do</span>
    session<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span> = params<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span>
    redirect to<span class="br0">&#40;</span><span class="st0">'/profile'</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  get <span class="st0">'/profile'</span> <span class="kw1">do</span>
    <span class="kw1">if</span> user_email = session<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span>
      body <span class="st0">&quot;Welcome, #{user_email}!&quot;</span>
    <span class="kw1">else</span>
      redirect to<span class="br0">&#40;</span><span class="st0">'/login'</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<h3>Creating Rails3 test application</h3>
<p>When you think that with rails it will be hard then your are wrong <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Thanks to rails3 design its also rather simple! Let&#8217;s see:</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
$ cat apps/test_rails_app.rb
</pre>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'rails'</span>
<span class="kw3">require</span> <span class="st0">'action_controller/railtie'</span>
&nbsp;
<span class="kw1">module</span> TestRailsApp
  <span class="kw1">class</span> Application <span class="sy0">&lt;</span> <span class="re2">Rails::Application</span>
    config.<span class="me1">secret_token</span> = <span class="st0">'572c86f5ede338bd8aba8dae0fd3a326aabababc98d1e6ce34b9f5'</span>
&nbsp;
    routes.<span class="me1">draw</span> <span class="kw1">do</span>
      get  <span class="st0">'/login'</span>   <span class="sy0">=&gt;</span> <span class="st0">'test_rails_app/sessions#new'</span>
      post <span class="st0">'/login'</span>   <span class="sy0">=&gt;</span> <span class="st0">'test_rails_app/sessions#create'</span>
      get  <span class="st0">'/profile'</span> <span class="sy0">=&gt;</span> <span class="st0">'test_rails_app/profiles#show'</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">class</span> SessionsController <span class="sy0">&lt;</span> <span class="re2">ActionController::Base</span>
    <span class="kw1">def</span> new
      render <span class="re3">:text</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;Please log in&quot;</span>
    <span class="kw1">end</span>
&nbsp;
    <span class="kw1">def</span> create
      session<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span> = params<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span>
      redirect_to <span class="st0">'/profile'</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">class</span> ProfilesController <span class="sy0">&lt;</span> <span class="re2">ActionController::Base</span>
    <span class="kw1">def</span> show
      <span class="kw1">if</span> user_email = session<span class="br0">&#91;</span><span class="re3">:user_email</span><span class="br0">&#93;</span>
        render <span class="re3">:text</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;Welcome, #{user_email}!&quot;</span>
      <span class="kw1">else</span>
        redirect_to <span class="st0">'/login'</span> 
      <span class="kw1">end</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<p>So you have <em>whole rails application</em> in one file. Nice! <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Write integration tests</h3>
<p>Now is most interesting part of this article.<br />
Capybara gem itself has rspec helpers that allows you to write rspec examples<br />
in way of acceptance testing (aka <em>feature</em> and <em>scenario</em>).</p>
<p>Actually internally <em>feature</em> is just alias to ExampleGroup (describe) and <em>scenario</em> is alias to Example (it).<br />
But this syntax follows you to think different.</p>
<p>Put in <em>spec/spec_helper.rb</em></p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'capybara/rspec'</span>
&nbsp;
<span class="kw3">require</span> <span class="st0">'rack_session_access'</span>
<span class="kw3">require</span> <span class="st0">'rack_session_access/capybara'</span>
&nbsp;
<span class="co1"># load test applications</span>
<span class="kw4">Dir</span><span class="br0">&#91;</span><span class="kw4">File</span>.<span class="me1">expand_path</span><span class="br0">&#40;</span><span class="st0">'../../apps/*.rb'</span>, <span class="kw2">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#93;</span>.<span class="me1">each</span> <span class="kw1">do</span> <span class="sy0">|</span>f<span class="sy0">|</span>
  <span class="kw3">require</span> f
<span class="kw1">end</span>
&nbsp;
<span class="co1"># configure sinatra application to use MyRackMiddleware</span>
TestSinatraApp.<span class="me1">configure</span> <span class="kw1">do</span> <span class="sy0">|</span>app<span class="sy0">|</span>
  app.<span class="me1">use</span> MyRackMiddleware
<span class="kw1">end</span>
&nbsp;
<span class="co1"># configure rails application to use MyRackMiddleware</span>
<span class="re2">TestRailsApp::Application</span>.<span class="me1">configure</span> <span class="kw1">do</span> <span class="sy0">|</span>app<span class="sy0">|</span>
  app.<span class="me1">middleware</span>.<span class="me1">use</span> MyRackMiddleware
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<p>Write acceptance spec for example in <em>spec/middleware_spec.rb</em> :<br />
Follow DRY principle and use <em>shared_examples</em>!</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1"><span class="kw3">require</span> <span class="st0">'spec_helper'</span>
&nbsp;
shared_examples <span class="st0">&quot;common scenarios&quot;</span> <span class="kw1">do</span>
  scenario <span class="st0">&quot;test application itself&quot;</span> <span class="kw1">do</span>
    page.<span class="me1">visit</span> <span class="st0">&quot;/login&quot;</span>
    page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Please log in&quot;</span><span class="br0">&#41;</span>
&nbsp;
    page.<span class="me1">visit</span> <span class="st0">&quot;/profile&quot;</span>
    page.<span class="me1">should</span> have_content<span class="br0">&#40;</span><span class="st0">&quot;Please log in&quot;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
&nbsp;
  scenario <span class="st0">&quot;MyRackMiddleware related scenario ...&quot;</span> <span class="kw1">do</span>
    ...
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
feature <span class="st0">&quot;MyRackMiddleware&quot;</span>, <span class="sy0">%</span>q<span class="br0">&#40;</span>
  As ROLE
  I want FEATURE
  So I have BENEFIT
<span class="br0">&#41;</span> <span class="kw1">do</span>
&nbsp;
  context <span class="st0">&quot;with Sinatra application&quot;</span> <span class="kw1">do</span>
    background <span class="kw1">do</span>
      Capybara.<span class="me1">app</span> = TestSinatraApp
    <span class="kw1">end</span>
&nbsp;
    include_examples <span class="st0">&quot;common scenarios&quot;</span>
  <span class="kw1">end</span>
&nbsp;
  context <span class="st0">&quot;with Rails application&quot;</span> <span class="kw1">do</span>
    background <span class="kw1">do</span>
      Capybara.<span class="me1">app</span> = <span class="re2">TestRailsApp::Application</span>
    <span class="kw1">end</span>
&nbsp;
    include_examples <span class="st0">&quot;common scenarios&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div></div></div></div></div></div>


<h3>Run tests</h3>
<p>Before implementation run specs</p>
<pre style="padding:10px;overflow:scroll;background-color:#000000;color:#00ff00">
$ bundle exec rspec -fs -c spec/middleware_spec.rb
</pre>
<p>Now you may add scenarios that cover your MyRackMiddleware influence on applications and start your middleware implementation!</p>
<h3>Conclusion</h3>
<p>We hope this article will help you to write better tests for your gems.</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/jnicklas/capybara">capybara</a></li>
<li><a href="https://www.relishapp.com/rspec">rspec</a></li>
</ul>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;count=horizontal&amp;text=Testing%20gem%20integration%20with%20multiple%20ruby%20frameworks" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;count=horizontal&amp;text=Testing%20gem%20integration%20with%20multiple%20ruby%20frameworks" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;linkname=Testing%20gem%20integration%20with%20multiple%20ruby%20frameworks" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;linkname=Testing%20gem%20integration%20with%20multiple%20ruby%20frameworks" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F07%2Ftesting-gem-integration-with-multiple-ruby-frameworks%2F&amp;title=Testing%20gem%20integration%20with%20multiple%20ruby%20frameworks" id="wpa2a_8"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/MY7yaoNa16A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/01/07/testing-gem-integration-with-multiple-ruby-frameworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/01/07/testing-gem-integration-with-multiple-ruby-frameworks/</feedburner:origLink></item>
		<item>
		<title>PivotalBooster – Keep your stories up to date!</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/_TfBs3Bc5us/</link>
		<comments>http://blog.railsware.com/2012/01/04/pivotalbooster-keep-your-stories-up-to-date/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 18:57:36 +0000</pubDate>
		<dc:creator>Sergey Korolev</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[pivotal]]></category>
		<category><![CDATA[pivotalbooster]]></category>
		<category><![CDATA[Products]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1154</guid>
		<description><![CDATA[&#160; The Railsware company is proud to show you our brand new free product – PivotalBooster. The PivotalBooster is a simple and fast Mac OS X client for the popular Pivotal Tracker service. Railsware put great efforts to make your work with Pivotal Tracker more comfortable and faster. PivotalBooster features allow you concentrate on all the [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p><a href="http://blog.railsware.com/wp-content/uploads/2012/01/login_logo.png"><img class="aligncenter size-full wp-image-1158" title="Pivotal booster logo" src="http://blog.railsware.com/wp-content/uploads/2012/01/login_logo-e1325699771288.png" alt="" width="175" height="157" /></a></p>
<p>The Railsware company is proud to show you our brand new free product – <a title="PivotalBooster" href="http://www.pivotalbooster.com" target="_blank">PivotalBooster</a>.</p>
<p style="text-align: justify;">The PivotalBooster is a simple and fast Mac OS X client for the popular <a title="Pivotal Tracker" href="http://www.pivotaltracker.com" target="_blank">Pivotal Tracker</a> service. Railsware put great efforts to make your work with Pivotal Tracker more comfortable and faster. PivotalBooster features allow you concentrate on all the stories you have, get all the information you need, be always up to date, and more.</p>
<p style="text-align: left;"><img class="aligncenter  wp-image-1167" title="center.jpg (960×900)" src="http://blog.railsware.com/wp-content/uploads/2012/01/center.jpg-960×900.png" alt="" width="571" height="354" /></p>
<p style="text-align: justify;">We have lots of ideas and features to implement in future releases and we need your active help to make our product even better. We’d appreciate any comment or feedback as your opinion is very important for us. Please feel free to share your thoughts!</p>
<p style="text-align: justify;">For sure you can also follow us on <a title="Twitter" href="http://twitter.com/#!/PivotalBooster" target="_blank">Twitter</a> and like us on <a href="http://www.facebook.com/pages/PivotalBooster/269673473091792" target="_blank">Facebook</a> to get more information and news.</p>
<p><span id="more-1154"></span></p>
<div>
<h4>Feature List:</h4>
<div></br></div>
<div><strong>“My Stories” on all the Projects</strong></div>
<div>All your stories of all projects assigned to you are collected by PivotalBooster in one place and shown to you in the sorted list for better navigation.</div>
<div></br></div>
<div><strong>Stories Short Info</strong></div>
<div>Short descriptions of all the stories that appear by a single click allow you to constantly track your current scope of work on all the projects.</div>
<div></br></div>
<div><strong>Stories Extended Info</strong></div>
<div>With even more details on each story you always know the key information you need. It includes name of a story, its description, who has requested it and who is assigned to, URL, and more.</div>
<div></br></div>
<div><strong>Status Update</strong></div>
<div>You can easily estimate a story or change its current state with the action buttons available for you on your Mac.</div>
<div></br></div>
<div><strong>Fast ID</strong></div>
<div>Putting IDs to commit messages is a good practice nowadays. With PivotalBooster you can easily operate with those <em>IDs</em>. It allows you to copy an <em>ID</em> by a single button click, or you can even copy that <em>ID</em> in the pivotal format <em>[#StoryID]</em> using the same button with the <strong>Option ⌥</strong> key pressed.</div>
<div></br></div>
<div><strong>Smart Filter</strong></div>
<div>For a better performance you can filter all your stories by name, description, labels, current state, its type, and its ID.</div>
<div></br></div>
<div><strong>Short Stats</strong></div>
<div>You can always see how many stories and story points there are in the icebox, current and done sections.</div>
<div></br></div>
<div><strong>Auto Sync</strong></div>
<div>Each 10 Minutes PivotalBooster automatically fetches the latest changes from the <a href="http://pivotaltracker.com/">pivotaltracker.com</a>. But if you need to sync right now, you can do it with a single button click or a key stroke.</div>
<div></br></div>
<div><strong>Growl Notifications</strong></div>
<div>Growl notification messages will keep you constantly updated on what have been changed in your stories.</div>
<div></br></div>
<div><strong>Product Owner Mode</strong></div>
<div>If you are a product owner, it can be more important for you to see updates on the scope requested by you. With PivotalBooster it’s easy &#8211; just select “Requested by me” on the login form. Inside the application you can easily switch between two modes using hot keys combination <strong>⌘+M</strong>, or use menu action.</div>
<div></br></div>
<div><strong>MoSCoW Prioritisation</strong></div>
<div>Fans of MoSCoW prioritisation can easily set priorities the way they used to without leaving the application. To find more about this methodology, visit <a href="http://en.wikipedia.org/wiki/MoSCoW_Method">http://en.wikipedia.org/wiki/MoSCoW_Method</a>.</div>
</div>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;count=horizontal&amp;text=PivotalBooster%20%26%238211%3B%20Keep%20your%20stories%20up%20to%20date%21" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;count=horizontal&amp;text=PivotalBooster%20%26%238211%3B%20Keep%20your%20stories%20up%20to%20date%21" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;linkname=PivotalBooster%20%26%238211%3B%20Keep%20your%20stories%20up%20to%20date%21" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;linkname=PivotalBooster%20%26%238211%3B%20Keep%20your%20stories%20up%20to%20date%21" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2012%2F01%2F04%2Fpivotalbooster-keep-your-stories-up-to-date%2F&amp;title=PivotalBooster%20%26%238211%3B%20Keep%20your%20stories%20up%20to%20date%21" id="wpa2a_10"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/_TfBs3Bc5us" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2012/01/04/pivotalbooster-keep-your-stories-up-to-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2012/01/04/pivotalbooster-keep-your-stories-up-to-date/</feedburner:origLink></item>
		<item>
		<title>Mailtrap: Save your customers from getting test emails.</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/8Xtd2iWLvUs/</link>
		<comments>http://blog.railsware.com/2011/12/12/mailtrap-save-your-customers-from-getting-test-emails/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 15:03:11 +0000</pubDate>
		<dc:creator>ld100</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[qa]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1100</guid>
		<description><![CDATA[We assume you&#8217;re a web developer, QA engineer, product manager, etc — somebody who&#8217;s doing internet software projects. Have you ever needed to test e-mail notifications in your web application? Today we&#8217;ll speak about common issues while testing e-mail notifications and best solutions for that issues. Common issues with manual e-mail notifications testing We believe [...]]]></description>
			<content:encoded><![CDATA[<p>We assume you&#8217;re a web developer, QA engineer, product manager, etc — somebody who&#8217;s doing internet software projects. Have you ever needed to test e-mail notifications in your web application? Today we&#8217;ll speak about common issues while testing e-mail notifications and best solutions for that issues.</p>
<h3>Common issues with manual e-mail notifications testing</h3>
<p>We believe most critical issue here is accidentally sending dummy e-mails to real customers while testing web applications at staging/development servers. But let&#8217;s start with easier once at first.</p>
<p>Let&#8217;s say you&#8217;re doing users registration where every new users gets registration confirmation e-mail. In order to register yet another user for testing purposes you need to have new unique email address that should be registered somewhere. That&#8217;ll become problematic unless you&#8217;ll use service like <a href="http://mailinator.com/">Mailinator</a> which seems good enough as a solution for our problem.</p>
<p>Now let&#8217;s make things a bit harder. Imagine our web application became successful and now we need to send weekly e-mail notifications to our users: a bit different for different users. How will you test that to know which e-mails were sent to which customers? Will you create tons of virtual users with tons of mail boxes and check each one? But that&#8217;s just so stupid and time-consuming!</p>
<p>In real life things are even worse. In my experience it is usually a good idea  to copy production database to your staging servers or development machines for test purposes — so you&#8217;ll work with a real data instead of something synthetic. But this also brings you a risk of sending test e-mails to the real customers from your development/staging environment. My personal score is about 2500 e-mails sent by mistake at a time. I know people whose personal record is <em>more than 2 millions emails sent by mistake!</em> Share your personal fuck up stories in comments <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<a href="http://blog.railsware.com/wp-content/uploads/2011/12/huh.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2011/12/huh.jpg" alt="" title="huh" width="225" height="141" class="alignnone size-full wp-image-1134" /></a></p>
<h3>Existing solutions for keeping your customers from test e-mails</h3>
<p>If you&#8217;re lazy or just don&#8217;t have enough time, you may skip this chapter and just scroll down to <em>Mailtrap: our solution to common problem</em> because our solution is really much better that others, believe me!</p>
<p>So which possible solutions are most popular?<br />
<span id="more-1100"></span></p>
<ul>
<li>Tweaking up your SMTP server, so it&#8217;ll send all messages based on specific rules, for example will rewrite recipient e-mail address to yours one. We used this solution for sending all e-mails to whole development team for one of our projects. It was fine but there was just one problem: each team member got tens to hundreds e-mails in his mailbox each time our QA engineers checked new application release. And what if you don&#8217;t have access to SMTP server settings?</li>
<li>Stripping customer e-mails from your test database with a special script, etc. In this case you&#8217;ll still need to have lots of test mailboxes which is quite a drawback, but you&#8217;ll be safe: real customers won&#8217;t get test e-mails from you.</li>
<li>Use dummy SMTP servers that&#8217;ll save all e-mails messages locally instead of sending them. <a href="http://rubygems.org/gems/mailcatcher">Mailcatcher</a> is a good example of such tool for Ruby. You can easily find same tools built with PHP, Python, etc. One major disadvantage on all of these tools is that they&#8217;re assumed to work on developer&#8217;s machine (so you can access that saved e-mails anytime), not on the staging servers where most non-developers test application functionality.</li>
<li>Some teams even prefer hardcoding different application logic for different environments. For example application will send e-mails normally from production servers but will forward it to special e-mail addresses for all e-mails other that @your-domain.com. This solution may be more flexible than previous 3 but also harder to implement and support.</li>
</ul>
<p>As you can see each solution have major disadvantages. That&#8217;s the reason we&#8217;ve created an alternative one called Mailtrap.</p>
<h3>Mailtrap: our solution to common problem</h3>
<p><a href="http://blog.railsware.com/wp-content/uploads/2011/12/fav.png"><img src="http://blog.railsware.com/wp-content/uploads/2011/12/fav.png" alt="" title="fav" width="16" height="16" class="alignleft size-full wp-image-1142" /></a><a href="http://mailtrap.io">Mailtrap</a> is a standardized solution aimed to help development teams to build and debug their email delivery functionality: it substitutes your SMTP server and allows viewing all your e-mails online at Mailtrap site, forward them to your normal mailbox if needed.</p>
<p><a href="http://blog.railsware.com/wp-content/uploads/2011/12/mtr.png"><img src="http://blog.railsware.com/wp-content/uploads/2011/12/mtr.png" alt="" title="mtr" width="565" height="316" class="aligncenter size-full wp-image-1136" /></a></p>
<p>So how does it work? You get Mailtrap&#8217;s SMTP credentials after registration. Than all you need to do is placing those credentials (hostname, port, login and password) to your application&#8217;s configuration (for non-production environments)&#8230; and Voilà — your e-mails sending is isolated from real users but still available to view and forward!</p>
<p>Ruby on Rails setup example.</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">
config.action_mailer.smtp_settings = {
    :address => 'stage.mailinator.io',
    :port => 2525,
    :user_name => 'box52',
    :password => '133632a53ddfec53a4b05496f7296a60'

}</pre>
<p>No local daemons setup, no tweaks on  your staging server, no application-level modifications — just change 4 lines of code, that&#8217;s it!<br />
Since Mailtrap uses standard SMTP protocol it is cross-platform: you&#8217;re able use it with any platform on any programming language.</p>
<p>All e-mails are now available to view at mailtrap.io. Each e-mail has unique URL — so you can share it with your team members with no problem while creating new bug tickets in your issue tracker, for example.<br />
For some cases we have alternative solution(for example, you&#8217;d like to see how your e-mail messages look in specific mail client): you can forward a message to specific e-mail address directly from Mailtrap&#8217;s web interface.</p>
<p><a href="http://blog.railsware.com/wp-content/uploads/2011/12/mtr_1.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2011/12/mtr_1-300x132.jpg" alt="" title="mtr_1" width="300" height="132" class="aligncenter size-medium wp-image-1145" /></a><br />
<a href="http://blog.railsware.com/wp-content/uploads/2011/12/mtr_21.jpg"><img src="http://blog.railsware.com/wp-content/uploads/2011/12/mtr_21-300x132.jpg" alt="" title="mtr_2" width="300" height="132" class="aligncenter size-medium wp-image-1149" /></a></p>
<h4>Are there any bells and whistles there?</h4>
<p>Yes, here is a quick list of current Mailtrap features:</p>
<ul>
<li>Ability to access ANY e-mail without registration</li>
<li>Sharing e-mail by copy&#8217;n'pasting its URL</li>
<li>Developer tools for debugging &amp; improving email templates which include HTML syntax highlighter, message source code view, CSS reseting.</li>
<li>Access to messages history.</li>
</ul>
<p>And yes, it is completely free!</p>
<p>Try <a href="http://mailtrap.io">Mailtrap</a> right now! We hope you&#8217;ll like it and waiting for your feedback at <a href="mailto:support@mailtrap.io">support@mailtrap.io</a></p>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;count=horizontal&amp;text=Mailtrap%3A%20Save%20your%20customers%20from%20getting%20test%20emails." scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;count=horizontal&amp;text=Mailtrap%3A%20Save%20your%20customers%20from%20getting%20test%20emails." scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;linkname=Mailtrap%3A%20Save%20your%20customers%20from%20getting%20test%20emails." title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;linkname=Mailtrap%3A%20Save%20your%20customers%20from%20getting%20test%20emails." title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F12%2Fmailtrap-save-your-customers-from-getting-test-emails%2F&amp;title=Mailtrap%3A%20Save%20your%20customers%20from%20getting%20test%20emails." id="wpa2a_12"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/8Xtd2iWLvUs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2011/12/12/mailtrap-save-your-customers-from-getting-test-emails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2011/12/12/mailtrap-save-your-customers-from-getting-test-emails/</feedburner:origLink></item>
		<item>
		<title>Happy 5th Birthday to Us!</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/Ze2fO9ex6p0/</link>
		<comments>http://blog.railsware.com/2011/12/02/happy-5th-birthday-to-us/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 10:16:00 +0000</pubDate>
		<dc:creator>gutiusha</dc:creator>
				<category><![CDATA[Office]]></category>
		<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1109</guid>
		<description><![CDATA[All HPB pictures on Flickr]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/railsware/6440752625/" title="_MG_7566 by railswarians, on Flickr"><img src="http://farm8.staticflickr.com/7145/6440752625_a6161f3e19.jpg" width="500" height="333" alt="_MG_7566"></a></p>
<p><a href="http://www.flickr.com/photos/railsware/6440749527/" title="_POJ7855 by railswarians, on Flickr"><img src="http://farm8.staticflickr.com/7153/6440749527_e45c518059.jpg" width="500" height="331" alt="_POJ7855"></a></p>
<p><a href="http://www.flickr.com/photos/railsware/6440752749/" title="_MG_7565 by railswarians, on Flickr"><img src="http://farm8.staticflickr.com/7143/6440752749_52b4294cf4.jpg" width="500" height="333" alt="_MG_7565"></a></p>
<p><a href="http://www.flickr.com/photos/railsware/sets/72157628244562239/with/6440752625/">All HPB pictures on Flickr</a></p>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;count=horizontal&amp;text=Happy%205th%20Birthday%20to%20Us%21" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;count=horizontal&amp;text=Happy%205th%20Birthday%20to%20Us%21" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;linkname=Happy%205th%20Birthday%20to%20Us%21" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;linkname=Happy%205th%20Birthday%20to%20Us%21" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2011%2F12%2F02%2Fhappy-5th-birthday-to-us%2F&amp;title=Happy%205th%20Birthday%20to%20Us%21" id="wpa2a_14"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/Ze2fO9ex6p0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2011/12/02/happy-5th-birthday-to-us/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2011/12/02/happy-5th-birthday-to-us/</feedburner:origLink></item>
		<item>
		<title>Railsware at Rubyshift and RubyC 2011 conferences</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/s1eHbbS3YzM/</link>
		<comments>http://blog.railsware.com/2011/11/23/railsware-at-rubyshift-and-rubyc-2011-conferences/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 14:40:28 +0000</pubDate>
		<dc:creator>Pavel Pavlovsky</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[ruby conferences]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1018</guid>
		<description><![CDATA[During last month railswarians took a part in a really great Ruby events: Rubyshift in Dnepropetrovsk, Ukraine and RubyC in Kyiv, Ukraine. RubyShift October 22-23 2011 Conference gathered more than 250 participants and speakers from all over the world including Pat Allan (@pat), Sven Fuchs (@svenfuchs), Josh Kalderimis (@joshkalderimis), Jon Leighton (@jonleighton), Thorben Schröder. This is the first time we [...]]]></description>
			<content:encoded><![CDATA[<p>During last month railswarians took a part in a really great Ruby events: <a href="http://rubyshift.org/">Rubyshift</a> in Dnepropetrovsk, Ukraine and <a href="http://rubyc.eu/">RubyC</a> in Kyiv, Ukraine.</p>
<h3>RubyShift October 22-23 2011</h3>
<p>Conference gathered more than 250 participants and speakers from all over the world including Pat Allan (<a href="https://twitter.com/#!/PAT">@pat</a>), Sven Fuchs (<a href="https://twitter.com/#!/svenfuchs">@svenfuchs</a>), Josh Kalderimis (<a href="https://twitter.com/#!/joshkalderimis">@joshkalderimis</a>), Jon Leighton (<a href="https://twitter.com/#!/jonleighton">@jonleighton</a>), Thorben Schröder.</p>
<p>This is the first time we decided to film such events and not only because 3 Railswarian heroes (Sergey Korolev, Sergey Boiko, Alexander Mishyn) had cool speeches on RubyShift stages. We really wanted to share good content with Ruby community and interview various participants on specifics of ukrainian development culture, their plans, issues and to understand the way we all have to move on better.</p>
<p>Conference videos are available at <a href="http://vimeo.com/channels/rubyshift2011">Vimeo</a> (Credits to Dmitry Larkin — our super-camera-man!). We will definitely share more speeches and interviews with Ruby stars soon.</p>
<p><img class="aligncenter" title="Interview with Sven Fuchs" src="http://farm7.static.flickr.com/6054/6345463649_e3956fc4ec.jpg" alt="" width="500" height="375" /></p>
<p><img class="aligncenter" title="Sergey Korolev. Heroes of non-silicol valley" src="http://farm7.static.flickr.com/6119/6345495195_6ce5b78c36.jpg" alt="" width="500" height="375" /></p>
<p><img class="aligncenter" title="Alexey &amp; RubyShift" src="http://farm7.static.flickr.com/6239/6345479341_29dc9571e3.jpg" alt="" width="500" height="375" /></p>
<p>More photos can be found at: <a href="http://bit.ly/v5z9kp">our Flickr stream</a>.</p>
<p>RubyShift  was organized great: venue and afterpartiies (yeah, everybody really enjoyed it) where smart, creative people met and socialized together.</p>
<p>Thanks again to organizers crew <a href="https://twitter.com/#!/beai">@beai</a>, <a href="https://twitter.com/#!/ifesdjeen">@ifesdjeen</a> and <a href="https://twitter.com/#!/mariya_o5">@mariya_o5</a>. Good luck to you, guys with more #RubyShifts in the future!</p>
<h3>RubyC November 5-6 2011</h3>
<p>RubyC conference taken a place in Kiev November 5-6.</p>
<p>Ruby guys like Joinas Nicklas (<a href="https://twitter.com/#!/jonicklas">@jonicklas</a>), Steve Klabnik (<a href="https://twitter.com/#!/steveklabnik">@steveklabnik</a>) , Ryan Bigg (<a href="https://twitter.com/#!/ryanbigg">@ryanbigg</a>), Darcy Laycock (<a href="https://twitter.com/#!/sutto">@sutto</a>) and Pat Allan (<a href="https://twitter.com/#!/pat">@pat</a>) rocked during these weekend. Railswarian Bogdan Gusiev made a great speech about <a href="http://vimeo.com/31900328">&#8220;Fighting Fat Models&#8221;</a>.</p>
<p>And again we shoot some nice <a href="http://blog.railsware.com/2011/11/23/rubyc-2011-conference-videos">videos</a>.</p>
<p>Finally, I&#8217;d like to wish Ukrainan developers to be more active, talk to guests, they are really willing to chat, that&#8217;s one of main reasons they&#8217;ve decided to attend these conferences. Talk to peopl like you during coffee breaks, afterparties. That&#8217;s the main event purpose: socialize, exchange, share your great ideas! Do not be scared of video cam as well <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It&#8217;s your opportunity to pass the message to a wide range of Ruby developers, business people, help in establishing community. Rock on guys!</p>
<h3>Conclusion</h3>
<p>Both conferences inspired us to be more active in introducing our work style, approaches, do more open source products and exchange innovations with community. Blogging, filming, interviewing participation and conferences organizintrg (yes, we have a lot of cool stuff to talk about!) and produce internal products so that we can make life of Ruby community and companies a bit easier — that&#8217;s our next step. And we will do it of course with lots of fun! <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Stay tuned!</p>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;count=horizontal&amp;text=Railsware%20at%20Rubyshift%20and%20RubyC%202011%20conferences" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;count=horizontal&amp;text=Railsware%20at%20Rubyshift%20and%20RubyC%202011%20conferences" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;linkname=Railsware%20at%20Rubyshift%20and%20RubyC%202011%20conferences" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;linkname=Railsware%20at%20Rubyshift%20and%20RubyC%202011%20conferences" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frailsware-at-rubyshift-and-rubyc-2011-conferences%2F&amp;title=Railsware%20at%20Rubyshift%20and%20RubyC%202011%20conferences" id="wpa2a_16"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/s1eHbbS3YzM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2011/11/23/railsware-at-rubyshift-and-rubyc-2011-conferences/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2011/11/23/railsware-at-rubyshift-and-rubyc-2011-conferences/</feedburner:origLink></item>
		<item>
		<title>RubyC 2011 Conference Videos</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/9Wn7R7P7sGA/</link>
		<comments>http://blog.railsware.com/2011/11/23/rubyc-2011-conference-videos/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 12:04:11 +0000</pubDate>
		<dc:creator>Pavel Pavlovsky</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[rubyc]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=1058</guid>
		<description><![CDATA[We&#8217;ve shoot videos at recent european RubyC conference held in Kiev, Ukraine. Wider than Rails Author: Alexey Nayden (lightweight Ruby solutions) Language: English How to be awesome at Rails Author: Ryan Bigg Language: English CloudHostpro (platform for hosting Ruby applications) Author: Dmitriy Kostyuk Language: Russian Literate code Author: Steve Klabnik Language: English How to make [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve shoot videos at recent european RubyC conference held in Kiev, Ukraine.</p>
<h3>Wider than Rails</h3>
<p>Author: Alexey Nayden (lightweight Ruby solutions)<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31899143?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="407" height="229"></iframe></p>
<h3>How to be awesome at Rails</h3>
<p>Author: Ryan Bigg<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31904250?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<p><span id="more-1058"></span></p>
<h3>CloudHostpro (platform for hosting Ruby applications)</h3>
<p>Author: Dmitriy Kostyuk<br />
Language: Russian<br />
<iframe src="http://player.vimeo.com/video/31901545?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Literate code</h3>
<p>Author: Steve Klabnik<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31905130?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>How to make your Ruby or Rails app 10x faster</h3>
<p>Author: Alexander Dymo<br />
Language: Russian<br />
<iframe src="http://player.vimeo.com/video/31898382?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Full stack testing of your Ruby and JavaScript applications</h3>
<p>Author: Jonas Nicklas<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31901851?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Bridging the gap</h3>
<p>Author: Darcy Laycock<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31900535?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<h3>Typical development problems &amp; mistakes based on development internet TV</h3>
<p>Author: Timothy Tsvetkov<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31906212?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Cut and Polish (Crafting Gems)</h3>
<p>Author: Pat Allan<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31903681?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Rails + GoF Patterns</h3>
<p>Author: Marat Kamenshikov<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31906810?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Continuous Integration with Ruby</h3>
<p>Author: Roman Babenko<br />
Language: Ukrainian<br />
<iframe src="http://player.vimeo.com/video/31904048?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Fighting Fat models</h3>
<p>Author: Bogdan Gusiev<br />
Language: Russian<br />
<iframe src="http://player.vimeo.com/video/31900328?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<h3>Open Source for Efficient Cloud Management Systems</h3>
<p>Author: Sergey Sergyenko<br />
Language: English<br />
<iframe src="http://player.vimeo.com/video/31904603?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;count=horizontal&amp;text=RubyC%202011%20Conference%20Videos" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;count=horizontal&amp;text=RubyC%202011%20Conference%20Videos" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;linkname=RubyC%202011%20Conference%20Videos" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;linkname=RubyC%202011%20Conference%20Videos" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F23%2Frubyc-2011-conference-videos%2F&amp;title=RubyC%202011%20Conference%20Videos" id="wpa2a_18"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/9Wn7R7P7sGA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2011/11/23/rubyc-2011-conference-videos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2011/11/23/rubyc-2011-conference-videos/</feedburner:origLink></item>
		<item>
		<title>CapHub – multiple applications deployment with Capistrano</title>
		<link>http://feedproxy.google.com/~r/railsware/~3/4xa4XotNmj0/</link>
		<comments>http://blog.railsware.com/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 15:01:19 +0000</pubDate>
		<dc:creator>ayanko</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.railsware.com/?p=967</guid>
		<description><![CDATA[Today we&#8217;ll talk about deploying multiple applications via single Capistrano project, managing its deployment configurations in a single place. This approach is a must for projects with multiple applications deployment and recommended for any other project using Capistrano for deployment. We&#8217;ve created a tool called Caphub for simplifying creation of multi-deployment Capistrano projects. Before showing [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-973" src="https://github.com/railsware/caphub/raw/master/caphub.png" alt="" /></p>
<p>Today we&#8217;ll talk about deploying multiple applications via single Capistrano project, managing its deployment configurations in a single place.<br />
This approach is a must for projects with multiple applications deployment and recommended for any other project using Capistrano for deployment.<br />
We&#8217;ve created a tool called <a href="https://github.com/railsware/caphub">Caphub</a> for simplifying creation of multi-deployment Capistrano projects. Before showing it in details let&#8217;s review original Capistrano deployment methods: default and multi-stage. </p>
<h3>Preface</h3>
<p>We&#8217;re pretty sure you&#8217;re already familiar with basic capistrano setup. Let&#8217;s just repeat it briefly:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ cd blog
$ gem install capistrano
$ capify .</pre>
<p>Then you put project-specific configuration to <em>config/deploy.rb</em></p>
<p>Another thing that people usually use for deployment is <a href="https://github.com/capistrano/capistrano-ext">multistage extension</a> originally written by capistrano author.</p>
<p>This extension allows you to specify particular configuration related to specific <em>environments</em> easily. For example, production or qa environments. Common configuration is located in <em>config/deploy.rb</em> and specific configuration in <em>config/deploy/{stage_name}.rb</em> So any of your tasks are always executed as:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ cap CONFIGURATION_TASK NAMESPACE:TASK_NAME</pre>
<p>E.g.:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ cap production deploy:setup</pre>
<p>In our opinion this approach works fine&#8230; even <em>extremely fine</em>! Thank you, Jamis Buck!</p>
<h3>Decentralized multi-deployment approach</h3>
<p><img class="alignnone size-full wp-image-969" title="caphub-many-places" src="http://blog.railsware.com/wp-content/uploads/2011/11/caphub-many-places.png" alt="" width="600" height="400" /></p>
<p>Following examples assume you&#8217;re working on large or just complex project that contains several applications. For example you use <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA</a> approach. So deployment code is located in each of its applications.</p>
<p>There are serious disadvantages in this method:</p>
<ol>
<li><strong>Multiple directories</strong>: You must enter each project and start application deployment procedure there. So you either use <em>cd</em> command or open each project&#8217;s directory in a new terminal console.</li>
<li><strong>Copy-n-Paste</strong>: Some shared configuration and Capistrano recipes are just copy-n-pasted between projects. It&#8217;s not DRY.</li>
<li><strong>Deployment and Application mixing</strong>: We believe application code must be independent from deployment code — that is just different projects. So why would we put deployment code directly into main application repository? It makes a mess at least in SCM commit history.</li>
</ol>
<p>As an alternative you may use centralized deployment approach.</p>
<h3>Centralized multi-deployment approach</h3>
<p><img class="alignnone size-full wp-image-968" title="caphub-one-place" src="http://blog.railsware.com/wp-content/uploads/2011/11/caphub-one-place.png" alt="" width="600" height="338" /></p>
<p>Let&#8217;s create another repository and call it <em>mysite-deploy</em> for example. Create repository layout similar to Capistrano multistage convention:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">[mysite-deploy]$ tree --dirsfirst
.
├── config
│   ├── deploy
│   │   ├── billing
│   │   │   ├── production.rb
│   │   │   └── qa.rb
│   │   ├── core
│   │   │   ├── production.rb
│   │   │   └── qa.rb
│   │   └── customer
│   │       ├── production.rb
│   │       └── qa.rb
│   ├── keys
│   └── deploy.rb
├── recipes
├── Capfile
└── Gemfile</pre>
<p>What is the benefit?</p>
<ol>
<li><strong>Centralized location</strong>: <em>mysite-deploy</em> is your deployment control repository now. All deployment code located in <em>single</em> place and you can easily support or refactor it.</li>
<li><strong>Reuseable code</strong>: You don&#8217;t need to copy-n-paste Capistrano recipes or configuration files anymore. Such approach allows you to include shared configurations to certain subprojects. You can include external recipes via gems or put your own ones into recipes directory. You can easy configure/override particular recipe for certain configuration.</li>
<li><strong>Security policy</strong>: You may restrict access to deployment project so only specific people/departments would be able to deploy the application. Or if you use ssh keys you can create yet another repository <em>deployment-keys</em> and add it as git submodule or symlink it. There are lots of ways how you may organize your security policy. Anyway it is much easier with centralized deployment project location.</li>
</ol>
<p><span id="more-967"></span></p>
<h3>System configuration deployment</h3>
<p>Where do you store your web server configuration files configured for your applications? <em>nginx.conf</em> for example. Do you configure it each time from scratch? Do you copy it from one server to another? Do you put in your knowledge base? Do you put it in your application repository?</p>
<p>We believe system configuration also should be stored in SCM. And even more: system configuration is also treated as part of deployment infrastructure! Your system administrator may say it is not true but believe us <img src='http://blog.railsware.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So we advise you to create another repository, call it <em>mysite-sysconf</em> for example, and put configuration files there. You are free to organize sysconf repository layout as you wish. It depends on your deployment architecture. You can either store all config files in one repository mysite-sysconf or in several repositories like <em>mysite-sysconf-nginx</em>. Again it depends on your site architecture.</p>
<p>Then go to mysite-deploy repository and write deployment recipes. For example:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">[mysite-deploy]$ cap sysconf:nginx:production deploy:setup
[mysite-deploy]$ cap sysconf:nginx:production deploy</pre>
<p>Benefits:</p>
<ol>
<li><strong>System configuration is version-controlled</strong>: You won&#8217;t lose you system configuration changes. You can review any configuration file before it will be applied to production servers. You can test configuration on another servers.</li>
<li><strong>Automated deployment</strong>: It is easier to setup multiple servers with the same configurations. If you need to add extra server to existing architecture it&#8217;s also will be easy to do it with capistrano.</li>
</ol>
<p>Now let&#8217;s simplify deployment projects creation with Caphub.</p>
<h3>What is CapHub?</h3>
<p><a href="https://github.com/railsware/caphub">CapHub</a> is a simple tool that generates deployment repository layout described above for you. If you want to build own deployment repository <em>caphub</em> might be handy. It&#8217;s as easy as <em>bundle gem NAME</em> command.</p>
<h4>Installation</h4>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ gem install caphub</pre>
<h4>Usage</h4>
<p>Let&#8217;s create own deployment hub!</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ caphub mysite-deploy</pre>
<p>Go to <em>mysite-deploy</em> directory and install gems:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">$ bundle install</pre>
<p>Push repository to your remote server:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">git remote add origin your/remote/git/repo/url
git push -u origin master</pre>
<h4>Details</h4>
<p>Caphub generates minimal layout like:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">tree --dirsfirst
.
├── config
│   ├── deploy
│   └── deploy.rb
├── recipes
├── Capfile
├── Gemfile
└── Gemfile.lock</pre>
<p>Where <strong>Gemfile</strong> already contains some handy gems-recipes:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ruby"><pre class="de1">source <span class="st0">&quot;http://rubygems.org&quot;</span>
&nbsp;
gem <span class="st0">&quot;capistrano&quot;</span>
gem <span class="st0">&quot;capistrano_colors&quot;</span>
&nbsp;
gem <span class="st0">&quot;capistrano-multiconfig&quot;</span>
gem <span class="st0">&quot;capistrano-uptodate&quot;</span>
gem <span class="st0">&quot;capistrano-patch&quot;</span>
gem <span class="st0">&quot;capistrano-calendar&quot;</span></pre></div></div></div></div></div></div></div>


<p>The core of Caphub is actually <a href="https://github.com/railsware/capistrano-multiconfig">capistrano-multiconfig</a> gem. It automatically builds capistrano task-configrations from files located in <em>config/deploy/</em> directory.</p>
<p>So if you create file <em>config/deploy/apps/customer/production.tb</em>, corresponding configuration task will become available:</p>
<pre style="padding: 10px; overflow: scroll; background-color: #000000; color: #00ff00;">[mysite]$ cap -T
...
cap apps::customer:production          # Load apps:customer:production configuration
...</pre>
<p>Please read <a href="https://github.com/railsware/capistrano-multiconfig">capistrano-multiconfig</a> README file for more details.</p>
<h4>Extending with your recipes</h4>
<ul>
<li>Add gems that contain Capistrano recipes to <em>Gemfile</em></li>
<li>Configure and require recipes in <em>Capfile</em></li>
<li>Put your own recipes to <em>recipes</em> directory</li>
</ul>
<p>We believe that CapHub concept should be used even if you even have only one application repository. Just create another repository and move deployment there. Don&#8217;t mix different things together&#8230;</p>
<p>Divide et Impera!</p>
<h3>References</h3>
<ul>
<li><a href="https://github.com/capistrano/capistrano">capistrano</a></li>
<li><a href="https://github.com/capistrano/capistrano-ext">capistrano-ext</a></li>
<li><a href="https://github.com/stjernstrom/capistrano_colors">capistrano_colors</a></li>
<li><a href="https://github.com/railsware/capistrano-multiconfig">capistrano-multiconfig</a></li>
<li><a href="https://github.com/railsware/capistrano-uptodate">capistrano-uptodate</a></li>
<li><a href="https://github.com/railsware/capistrano-patch">capistrano-patch</a></li>
<li><a href="https://github.com/railsware/capistrano-calendar">capistrano-calendar</a></li>
</ul>
<p><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service facebook_like" src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;layout=button_count&amp;show_faces=false&amp;width=75&amp;action=like&amp;colorscheme=light&amp;height=20&amp;ref=addtoany" scrolling="no" style="border:none;overflow:hidden;width:90px;height:21px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;count=horizontal&amp;text=CapHub%20%26%238211%3B%20multiple%20applications%20deployment%20with%20Capistrano" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service twitter_tweet" src="http://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;counturl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;count=horizontal&amp;text=CapHub%20%26%238211%3B%20multiple%20applications%20deployment%20with%20Capistrano" scrolling="no" style="border:none;overflow:hidden;width:130px;height:20px"></iframe><!--<![endif]--><!--[if IE]><iframe frameborder="0" allowTransparency="true" class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><![endif]--><!--[if !IE]><!--><iframe class="addtoany_special_service google_plusone" src="https://plusone.google.com/u/0/_/%2B1/fastbutton?url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;size=medium&amp;count=true" scrolling="no" style="border:none;overflow:hidden;width:90px;height:20px"></iframe><!--<![endif]--><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;linkname=CapHub%20%26%238211%3B%20multiple%20applications%20deployment%20with%20Capistrano" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;linkname=CapHub%20%26%238211%3B%20multiple%20applications%20deployment%20with%20Capistrano" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.railsware.com%2F2011%2F11%2F18%2Fcaphub-multiple-applications-deployment-with-capistrano%2F&amp;title=CapHub%20%26%238211%3B%20multiple%20applications%20deployment%20with%20Capistrano" id="wpa2a_20"><img src="http://blog.railsware.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p><img src="http://feeds.feedburner.com/~r/railsware/~4/4xa4XotNmj0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.railsware.com/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.railsware.com/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Database Caching 11/37 queries in 0.010 seconds using disk: basic

Served from: blog.railsware.com @ 2012-02-21 16:04:32 -->

