<?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>SciWerks.com &#187; testing</title>
	<atom:link href="http://www.sciwerks.com/blog/category/ruby/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sciwerks.com/blog</link>
	<description>Software for scientists, by scientists</description>
	<lastBuildDate>Fri, 24 Oct 2008 01:02:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rails Testing Strategies: Valid and Invalid Data</title>
		<link>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-valid-and-invalid-data/</link>
		<comments>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-valid-and-invalid-data/#comments</comments>
		<pubDate>Mon, 12 Jun 2006 17:36:52 +0000</pubDate>
		<dc:creator>Kevin Olbrich</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-valid-and-invalid-data/</guid>
		<description><![CDATA[Consider this test&#8230;




def test_create


&#160; @item = Item.new


&#160; assert_valid @item


end 




Can you tell what the expected result of this test is?  
It turns out that you can&#8217;t tell from reading this test if it will pass or fail without knowing if &#8216;Item.new&#8217; returns a valid or invalid object.  If &#8216;Item&#8217; has a &#8216;validates_presence_of&#8217; statement [...]]]></description>
			<content:encoded><![CDATA[<p>Consider this test&#8230;</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_create</div>
</li>
<li class="li1">
<div class="de1">&nbsp; @item = Item.<span class="me1">new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_valid @item</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>Can you tell what the expected result of this test is?  </p>
<p>It turns out that you can&#8217;t tell from reading this test if it will pass or fail without knowing if &#8216;Item.new&#8217; returns a valid or invalid object.  If &#8216;Item&#8217; has a &#8216;validates_presence_of&#8217; statement in there, this new item will be invalid and the test will fail.  In addition, this test is &#8216;fragile&#8217;, subtle changes to the model definition can make the result of this test change.  This isn&#8217;t such a big deal if all you are doing is testing to see if an object is valid or not, but if you are writing a more involved test that depends on this assumption then you might be in trouble.</p>
<p>Currently the only way to ensure that your test data is valid is to add an assertion to each test making the appropriate test.  This isn&#8217;t very DRY.</p>
<p>One trick that I use to avoid repeating myself a lot in tests is to define a mock object like this..(putting this in a mock object keeps these methods out of production mode).</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="co1"># mocks/test/item.rb</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">require</span> &#8216;models/item&#8217;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">class</span> Item</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">#this assumes that an empty object is invalid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">#modify this as needed</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">new_invalid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; Item.<span class="me1">new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">new_valid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; item = <span class="kw2">self</span>.<span class="me1">new_invalid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; item.<span class="me1">name</span> = <span class="st0">&quot;new valid item&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1"># add any additional statements </span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1"># required to make the item valid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>Then in my tests I add&#8230;</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_valid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_valid Item.<span class="me1">new_valid</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_invalid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert !Item.<span class="me1">new_invalid</span>.<span class="me1">valid</span>?, <span class="st0">&quot;Item not invalid&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_save_invalid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; @invalid_item = Item.<span class="me1">new_invalid</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert !@invalid_item.<span class="me1">save</span>, <span class="st0">&quot;Saved invalid item&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>This way I am guaranteed to get a valid or invalid item when I need one.  in addition, if the definition of valid or invalid changes sufficiently the &#8216;test_valid&#8217; and &#8216;test_invalid&#8217; tests will fail, warning me that my assumptions in the rest of the tests are incorrect.</p>
<p>One problem with this approach is if your tests care about HOW the object is invalid.  In that case, you might need additional methods like &#8216;new_with_invalid_name&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-valid-and-invalid-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rails Testing Strategies: Positive and Negative Controls</title>
		<link>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-positive-and-negative-controls/</link>
		<comments>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-positive-and-negative-controls/#comments</comments>
		<pubDate>Mon, 12 Jun 2006 17:36:36 +0000</pubDate>
		<dc:creator>Kevin Olbrich</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-positive-and-negative-controls/</guid>
		<description><![CDATA[Testing your rails application can be a great way to make your application robust.  Proper testing aids in debugging, and can alert you when some minor change you made breaks something horribly.  Rails has some nice testing features &#8216;baked-in&#8217;, but the best advice I have seen so far regarding which actual tests to [...]]]></description>
			<content:encoded><![CDATA[<p>Testing your rails application can be a great way to make your application robust.  Proper testing aids in debugging, and can alert you when some minor change you made breaks something horribly.  Rails has some nice testing features &#8216;baked-in&#8217;, but the best advice I have seen so far regarding which actual tests to run is &#8230; &#8216;it depends&#8217;.  </p>
<p>Needless to say, that isn&#8217;t very practical advice.</p>
<p>Over the course of developing my own rails application, I have developed a list of &#8216;tests&#8217; that I like to run on my models and controllers. This article will discuss some of the strategic design of tests, but won&#8217;t cover how to implement them (well, not much anyway).</p>
<h2>Positive Controls</h2>
<p>Tests should be designed with both &#8216;positive&#8217; and &#8216;negative&#8217; controls in mind.  A positive control is a test or assertion that succeeds when you expect it to, and likewise a negative control fails when you expect it to.  For example, if you create and save an object using predefined good data, an appropriate positive control could be&#8230;</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_create</div>
</li>
<li class="li1">
<div class="de1">&nbsp; num_items = Item.<span class="me1">count</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; @item = Item.<span class="me1">new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert @item.<span class="me1">save</span>, <span class="st0">&quot;Item not saved&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_valid @item&nbsp; <span class="co1"># a positive control</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_equal num_items + <span class="nu0">1</span>, Item.<span class="me1">count</span>&nbsp; <span class="co1">#another positive control</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>In this case, we just check to make sure that the object is valid and that the number of them in the database has increased by one.  These types of tests don&#8217;t really tell you much.  The only time these types of tests fail is when something is seriously wrong with your database server, your ruby install, or your rails install.  The only other time this type of test will fail is if you change the definition of the &#8216;Item&#8217; model so that creating one using the &#8216;new&#8217; method results in an invalid object (more on that later).  The problem with positive controls is that when they pass, all they tell you is that nothing in the test caused an assertion to fail.  This could mean that everything is hunky-dory, or it could mean that your assertions are not working as expected.</p>
<p>Passing the test doesn&#8217;t mean much if the test itself can&#8217;t detect a failure.  Our test would pass just fine, even if the object model should really have a &#8216;validates_presence_of :name&#8217; specified.  It&#8217;s also easy to see that if we write a test like this&#8230;</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_name</div>
</li>
<li class="li1">
<div class="de1">&nbsp; @object = Object.<span class="me1">new</span><span class="br0">&#40;</span>:name=&gt;&#8217;<span class="kw3">test</span> name&#8217;<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; @object.<span class="me1">save</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_valid @object</div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_equal @object.<span class="me1">name</span>, &#8216;<span class="kw3">test</span> name&#8217;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>This test will still pass, even if the validation is not specified. Still, it&#8217;s nice to know that things work as expected.</p>
<h2>Negative Controls</h2>
<p>Negative controls are really much more handy.  A Negative control is a test that is designed to detect when things fail.<br />
If we write another test for our &#8216;item&#8217;</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">class</span> Item &lt; ActiveRecord::Base</div>
</li>
<li class="li1">
<div class="de1">&nbsp; validates_presence_of :name</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_valid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; @item = Item.<span class="me1">new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; @item.<span class="me1">name</span> = <span class="st0">&quot;test item&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert_valid @item</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">def</span> test_invalid</div>
</li>
<li class="li1">
<div class="de1">&nbsp; @item = Item.<span class="me1">new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; assert !@item.<span class="me1">valid</span>?, <span class="st0">&quot;Object is not invalid&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> </div>
</li>
</ol>
</div>
</div>
<p>If &#8216;test_invalid&#8217; passes, then you can be confident that your &#8216;validates_presence_of&#8217; is working.  If it had been commented out during a bug fix and never replaced, this test would fail, while &#8216;test_valid&#8217; would still happily report a success.</p>
<p>The same approach should be used when testing model methods.  At least one test for each type of expected output, and one for each possible failure mode.  Then make sure that the negative controls are in place so that they will pass when the model is fed corrupt data.</p>
<p>The bottom line&#8230; tests should be written to pass when you pass valid data, but they should also be written to pass when you pass missing, corrupt, or extra data.  The failure modes are the most useful during development since they will point out places where bugs and security holes may creep into your application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sciwerks.com/blog/2006/06/12/rails-testing-strategies-positive-and-negative-controls/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
