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

<channel>
	<title>Techbelly &#187; jbehave</title>
	<atom:link href="http://www.techbelly.com/tag/jbehave/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techbelly.com</link>
	<description>Ben Griffiths&#039; weblog</description>
	<lastBuildDate>Sun, 18 Dec 2011 16:33:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A test by any other name</title>
		<link>http://www.techbelly.com/2005/06/24/a-test-by-any-other-name/</link>
		<comments>http://www.techbelly.com/2005/06/24/a-test-by-any-other-name/#comments</comments>
		<pubDate>Fri, 24 Jun 2005 08:56:37 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[agiledox]]></category>
		<category><![CDATA[jbehave]]></category>
		<category><![CDATA[rubyonrails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.techbelly.com/?p=223</guid>
		<description><![CDATA[RubyOnRails comes with built-in support for unit and functional testing &#8211; great for us test-driven development whackos. In a new rails application we&#8217;re developing, we used the excellent salted hash login generator to kick off the development of our site&#8217;s authentication. The login generator ships with tests &#8211; yippee! Since it&#8217;s a widely used extension [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.rubyonrails.org" title="">RubyOnRails</a> comes with built-in support for unit and functional testing &#8211; great for us test-driven development whackos. In a new rails application we&#8217;re developing, we used the excellent <a href="http://wiki.rubyonrails.com/rails/show/SaltedHashLoginGenerator" title="">salted hash login generator</a> to kick off the development of our site&#8217;s authentication. The login generator ships with tests &#8211; yippee! Since it&#8217;s a widely used extension for rails, it makes a useful example for some testing best practices that we&#8217;ve adopted.</p>
<p>[[Update: if you follow the conventions outlined here, you should be able to use the agiledox browser that I write about <a href="http://www.reevoo.com/blogs/bengriffiths/2006/04/05/rails-agiledox-browser/" title="">here</a>]]</p>
<p>Here&#8217;s an example of one of the tests:</p>
<pre>
def test_auth_bob
    @request.session['return-to'] = "/bogus/location"
    post :login, :user =&gt; { "login" =&gt; "bob", "password" =&gt; "atest" }
    assert_session_has "user"
    assert_equal @bob, @response.session["user"]
    assert_redirect_url "/bogus/location"
end
</pre>
<p>This test checks that the on successful login, the appropriate user is set in the session and that the browser is sent a redirect to a location stored in the session. I like my test methods to test one thing at a time &#8211; it becomes easier to narrow down any cause of failure. So, I split the two tests:</p>
<pre>
def test_auth_bob_1
    @request.session['return-to'] = "/bogus/location"
     post :login, :user =&gt; { "login" =&gt; "bob", "password" =&gt; "atest" }
     assert_redirect_url "/bogus/location"
end

def test_auth_bob_2
   post :login, :user =&gt; { "login" =&gt; "bob", "password" =&gt; "atest" }
   assert_session_has "user"
   assert_equal @bob, @response.session["user"]
end
</pre>
<p>Now, we have two tests: one that checks that the controller redirects and the other that the session has the user set. But we have some duplication that&#8217;s crept in and we need to do a bit of work on the test names.</p>
<pre>
def log_in_with_valid_user
   post :login, :user =&gt; { "login" =&gt; "bob", "password" =&gt; "atest" }
end

def test_should_redirect_to_page_stored_in_session_on_successful_login
  @request.session[:return_to] = "/bogus/location"
  log_in_with_valid_user
  assert_redirect_url "/bogus/location"
end

def test_should_store_user_object_in_session_on_successful_login
  log_in_with_valid_user
  assert_session_has :user
  assert_equal @bob, @response.session[:user]
end
</pre>
<p>We find that the pattern &#8216;test_should_***_on_***&#8217; a useful way of naming tests &#8211; it&#8217;s an idea stolen from <a href="http://dist.codehaus.org/jbehave/1.0.0-alpha2/website/index.html" title="">JBehave</a> . If this test were to fail, I&#8217;m reminded that I should (!) ask myself the question &#8216;should the class I&#8217;m testing do this?&#8217; before I go on a bug-hunt. The other advantage is that I can use my test classes to generate some simple documentation for my classes. Here&#8217;s a rake target that can do just that:</p>
<pre>
desc "Generate agiledox-like documentation for tests"
task :agiledox do
  tests = FileList['test/**/*_test.rb']
  tests.each do |file|
    m = %r".*/([^/].*)_test.rb".match(file)
    puts m[1]+" should:\n"
    test_definitions = File::readlines(file).select {|line| line =~ /.*def test.*/}
    test_definitions.each do |definition|
      m = %r"test_(should_)?(.*)".match(definition)
      puts " - "+m[2].gsub(/_/," ")
    end
  puts "\n"
 end
end
</pre>
<p>An example from our codebase, typing <code>rake agiledox</code> generates:</p>
<pre>
security_controller should:
 - redirect to page stored in session on successful login
 - store user object in session on successful login
 - redirect to page stored in session after signup
 - store user object in session after signup
 - reject signup when passwords do not match
 - reject signup when login too short
 - report both errors if passwords dont match and username too short
 - not store user in session if password not correct on signup
 - remain on login page if password not correct on signup
 - remove user from session on log out
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.techbelly.com/2005/06/24/a-test-by-any-other-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

