


<?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>CantRemembrances &#187; tdd</title>
	<atom:link href="http://blog.cantremember.com/tag/tdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.cantremember.com</link>
	<description>Memes of a technical vein discovered during CantRemember.com implementation</description>
	<lastBuildDate>Tue, 16 Feb 2010 06:36:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>being too rapid on the things that matter</title>
		<link>http://blog.cantremember.com/being-too-rapid-on-the-things-that-matter/</link>
		<comments>http://blog.cantremember.com/being-too-rapid-on-the-things-that-matter/#comments</comments>
		<pubDate>Fri, 08 May 2009 05:04:51 +0000</pubDate>
		<dc:creator>dfoley</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[mentor]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://blog.cantremember.com/?p=144</guid>
		<description><![CDATA[it took me a while to come up with the title for this post.  and it&#8217;s and Opinion Piece, not Techincal &#8230; so you&#8217;ll see why &#8230;
i&#8217;m working for a new company now, and they&#8217;re rocking it for RoR apps on the iPhone. sounds like a good place to be. one of the many [...]]]></description>
			<content:encoded><![CDATA[<p>it took me a while to come up with the title for this post.  and it&#8217;s and Opinion Piece, not Techincal &#8230; so you&#8217;ll see why &#8230;</p>
<p>i&#8217;m working for a new company now, and they&#8217;re rocking it for RoR apps on the iPhone. sounds like a good place to be. one of the many reasons why this position works for me is because these guys are all about GTD and getting it out there. lean &#8216;n&#8217; mean</p>
<p>whereas i&#8217;ve become very used to a holistic detail-orented, wisened test-backed process. great for Enterprise, but not so much for the reckless streets of Startup 3.0 .  so i&#8217;m in a learning process. i&#8217;ve turned around some good stuff quickly, and it&#8217;s very satisfying</p>
<p>but i&#8217;ve screwed the pooch twice since i&#8217;ve been there.  it&#8217;s totally a judgement call thing &#8212; i&#8217;m shooting <i>too</i> fast from the hip, and don&#8217;t feel like i really grasp the balance here &#8230;</p>
<p>first project i worked on was related to account management. they wanted a quick turn-around, i gave it a shot, had the whole thing backed with solid testing, and ready for on-time deployment with a smile. and in trying to keep track of all the new system permutations &#8212; i&#8217;d been there 2 weeks or so &#8212; i forgot one basic thing, and forgot to test for another. a nice little Perfect Storm. one emergency 1am database rollback later, we had a load of pissed customers and a helluva lot of explaining to do</p>
<p>so, then this past week, i went in to fix a minor rounding issue bug.  those can be touchy.  the <b>right</b> way to do it is with <a href="http://www.ruby-doc.org/stdlib/libdoc/bigdecimal/rdoc/classes/BigDecimal.html"><code>BigDecimal</code></a>. yep, i&#8217;ve done that in Java too with <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html"><code>BigDecimal</code></a>.  overall, it&#8217;s somewhat ponderous, detail-oriented, and can easily be polluted with <code>Float</code>s and the like.  so i&#8217;d taken a shortcut, realizing that the low-level C impl was doing String conversion without the rounding issue.  so i took the low-hanging fruit:</p>
<pre><code>total.to_s.to_i</code></pre>
<p><i>awesome !!1!</i>. well, that is until you get into the 100-of-trillions area, otherwise shown as <code>1.0e+14</code>. guess what happens when you parse that into a Fixnum? no database rollback this time, but Da Boss had to spend <i>days</i> sorting out the visceral impact of ridiculous sums of bogus exploit money pouring into our RPG</p>
<p>security, privacy and account management.  payment calculations.  not the sort of things to take shortcuts on.  yet, if you&#8217;re embracing a culture that wants it done quickly and with minimum impact, it&#8217;s a risk you might be willing to take.  it&#8217;s not like i didn&#8217;t have test scripts &#8230; i just forgot to head into scientific notation territory.  just like i forgot to check for the implication of null password acceptance <em>( long story there, special account cases, etc. )</em></p>
<p>i&#8217;m putting these things up here for my fellow developers to laugh at. &nbsp; &#8220;I mean, c&#8217;mon. All that&#8217;s totally obvious stuff.&#8221; &nbsp; &#8220;I&#8217;d never miss that, that&#8217;s sophmore shit.&#8221; &nbsp; good, get it out of your system, laughing boy</p>
<p>but believe me, when you&#8217;re on the other end of it, and had been in the middle of it and all full of all the other things that you needed to keep track of at that time, heh, well, that&#8217;s when you&#8217;ll really need to keep yerself laughing :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cantremember.com/being-too-rapid-on-the-things-that-matter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter4R shifts RSpec onto my Front Burner</title>
		<link>http://blog.cantremember.com/twitter4r-shifts-rspec-onto-my-front-burner/</link>
		<comments>http://blog.cantremember.com/twitter4r-shifts-rspec-onto-my-front-burner/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 09:00:33 +0000</pubDate>
		<dc:creator>dfoley</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.cantremember.com/?p=94</guid>
		<description><![CDATA[As usual, my day did not pan out as expected.  But, also as usual, I learned a lot!
Coming Up To Speed on Rspec
So, learning rspec has been on my list for a while.  I finally got around to it.  Nice framework.  I am familiar with EasyMock, and am aware of JMock. [...]]]></description>
			<content:encoded><![CDATA[<p>As usual, my day did not pan out as expected.  But, also as usual, I learned a lot!</p>
<h3>Coming Up To Speed on Rspec</h3>
<p>So, learning <a href="http://rspec.info/"><strong>rspec</strong></a> has been on my list for a while.  I finally got around to it.  Nice framework.  I am familiar with <a href="http://www.easymock.org/">EasyMock</a>, and am aware of <a href="http://www.jmock.org/">JMock</a>.  I never had an opportunity to get into <a href="http://code.google.com/p/mockito/">Mockito</a>, but I&#8217;d give it a glance next time I put on my Java hat.</p>
<p>There is some decent documentation on it out there.  I found these links particularly helpful:</p>
<ul>
<li>The <a href="http://rspec.info/documentation/">formal documentation</a>.</li>
<li>David Chelimsky&#8217;s <a href="http://blog.davidchelimsky.net/articles/2007/05/14/an-introduction-to-rspec-part-i">from-the-ground-up description</a></li>
<li>rspec.info&#8217;s drill-down into <a href="http://rspec.info/documentation/mocks/">Mocks and Stubs</a></li>
<li>Luke Redpath&#8217;s cross-over into <a href="http://www.lukeredpath.co.uk/blog/developing-a-rails-model-using-bdd-and-rspec-part-1.html">usage under Rails</a></li>
</ul>
<p>During my ramping-up, I took the <a href="http://blog.cantremember.com/learning-ruby-through-assertions-and-podcasts/">usual meta-approach</a> of creating a test suite &#8212; and <em>yaaay</em>, that&#8217;s what <code>rspec</code> is meant for! &#8212; which I then used to test out its own range of capabilities.  The <a href="http://rspec.rubyforge.org/rspec/1.1.12/">Modules in the rdoc</a> which I&#8217;ve found to provide the most value are:</p>
<ul>
<li><strong>Spec::Expectations::ObjectExpectations</strong> for conditionals (eg. <code>should</code> &#038; <code>should_not</code>)</li>
<li><strong>Spec::Matchers</strong> for expectations (eg. <code>equal(<em>value</em>)</code>, <code>be_a(<em>class</em>)</code>, <code>respond_to(<em>method_sym</em>)</code>, <code>raise_error</code>)</li>
<li><strong>Spec::Mocks::Methods</strong> for mock method definition (eg. <code>should_receive(<em>method_sym</em>)</code>)</li>
<li><strong>Spec::Mocks::MessageExpectation</strong> for mock behaviour (eg. <code>with(<em>*args</em>)</code>, <code>once</code>, <code>exactly(<em>n</em>).times</code>, <code>any_number_of_times</code>)</li>
<li><strong>Spec::Mocks::ArgumentConstraints</strong> for mock arguments (eg. <code>an_instance_of(<em>class</em>)</code>, <code>anything</code>)</li>
<li><strong>Spec::Mocks::BaseExpectation</strong> for mock responses (eg. <code>and_return(<em>value</em>)</code>, <code>and_yield(<em>&#038;block</em>)</code>)</li>
</ul>
<p>I won&#8217;t got into the deep details, but here are some examples of conditionals and expectations that I paraphrased into my meta-test:</p>
<div class="pre_wrap">
<pre><code>	specify "knowledge of nil" do
		''.should_not be_nil
	end

	specify "numeric calculations" do
		(355.0 / 113).should be_close(Math::PI, 0.1)
	end

	specify "changes made by a closure" do
		array = []
		lambda {
			array << :a
		}.should change(array, :size)
	end

	specify "equality" do
		5.should eql 5
		5.should equal 5
		[:a].should_not equal [:a]
	end

	specify "raising of errors" do
		#	always construct fresh!!!
		#		otherwise it won't be re-wrappable
		def raiser(s=nil)
			lambda { raise(RuntimeError, s) if s }
		end

		raiser('x').should raise_error
		raiser('y').should raise_error(RuntimeError, 'y')
	end

	specify "closure satisfaction" do
		5.should satisfy {|n| (4..6).include?(n) }
	end

	specify "what lists do" do
		[].should respond_to(:each, :find, :size)
	end</code></code></pre>
</div>
<p>And here&#8217;s a little bit of silly mocking:</p>
<div class="pre_wrap">
<pre><code>	def expect_raise(type=Spec::Mocks::MockExpectationError, &#038;block)
		abort 'block must be provided' unless block_given?
		block.should raise_error(type)
	end

	specify "the basics" do
		@mock.should_receive :hello
		@mock.should_not_receive :goodbye

		@mock.hello
		expect_raise { @mock.stay }
		expect_raise { @mock.goodbye }
	end

	specify "how many times, and with what" do
		@mock.should_receive(:one).once.with(1)
		@mock.one 1

		@mock.should_receive(:string).exactly(1).times.with(an_instance_of(String))
		@mock.string 'a string'

		@mock.should_receive(:anything).exactly(3).times.with(any_args())
		@mock.anything
		@mock.anything :again
		@mock.anything :third, 'time'

		@mock.should_receive(:array_ish).with(duck_type(:each, :find, :size))
		@mock.array_ish [:item]
	end

	specify "what i return, raise or throw" do
		@mock.should_receive(:get_one).and_return(1)
		@mock.should_receive(:put_one).with(1)
		@mock.put_one @mock.get_one

		@mock.should_receive(:increment).any_number_of_times.with(instance_of(Fixnum)).and_return {|i| i + 1 }
		@mock.increment(1).should equal(2)

		@mock.should_receive(:raises_string).and_raise('something runtime')
		expect_raise(RuntimeError) { @mock.raises_string }

		@mock.should_receive(:pitch).and_throw(:ball)
		lambda { @mock.pitch }.should throw_symbol(:ball)
	end

	specify "yielding in a complex fashion" do
		@mock.should_receive(:gimmee).exactly(3).times.and_yield(:x)

		holder = []
		@mock.gimmee {|value| holder << value }
		holder.should eql([:x])
		2.times { @mock.gimmee {|value| holder << value } }
		holder.should eql([:x, :x, :x])
	end

	specify "validation via closure" do
		(@mock.should_receive(:threely) do |value|
			value.to_s.size.should eql(3)
		end).exactly(3).times

		@mock.threely 'x' * 3
		@mock.threely :key
		@mock.threely 333
	end</code></code></pre>
</div>
<p>These are just ways I thought of to exercise the width and breadth of the library.  Very nice.  I hope that these are useful examples for people new to this gem.</p>
<p>I recommend the other references from above for filling in the missing details.  Once you have a <code>context / specify</code> or a <code>describe / it</code> specification set up, you&#8217;ll be good to go.  There&#8217;s much more to the library &#8212; Stories, for instance &#8212; but that&#8217;s <a href="http://blog.emson.co.uk/2008/06/understanding-rspec-stories-a-tutorial/">for another day</a>.</p>
<h3>An Informative Walk through Twitter4R</h3>
<p>No, I didn&#8217;t really <em>want</em> to spend time learning <code>rspec</code> &#8212; I mean heck, I&#8217;m busy &#8212; but I had a personal need to expand the <a href="http://twitter4r.rubyforge.org/"><strong>Twitter4R</strong></a> gem.  Specifically, I wanted to add on some <a href="http://apiwiki.twitter.com/Search+API+Documentation">Twitter search</a> features, and I was very impressed with how this library has been built.  Contribution-wise, the final step that <a href="http://susanpotter.net/">Susan Potter</a> recommends is to craft up some rspec tests.</p>
<p>Of course, mock testing is only as good as the framework you&#8217;re built upon.  The assumption is that <code>Net::HTTP</code> is going to do it&#8217;s job, so mock it up and you can even test your Twitter features offline.  When I built <a href="http://wiki.cantremember.com/Bitly4R"><strong>Bitly4R</strong></a> (given that name, my thinking has clearly been <em>influenced</em>), I did everything as full-on functional tests.  It was easy; <a href="http://bit.ly/">bit.ly</a> has both <code>shorten</code> and <code>expand</code> commands, so I could reverse-test real values without having any fixed expectations.</p>
<p>However, Twitter is <a href="http://twitter.com/public_timeline">live</a> and user-generated, so who knows <em>what</em> you&#8217;ll find.  Mocking covers that for you.  And of course not having to hit the service itself shortest testing time dramatically.</p>
<p>Here&#8217;s one of my tests, again foreshortened:</p>
<div class="pre_wrap">
<pre><code>	before(:each) do
		Twitter::Client.send :public, :create_http_get_request

		@client = Twitter::Client.new
		@client_clone = Twitter::Client.new
	end

	it "produces a querystring with all the crazy stuff Twitter imagined" do
		the_params = nil

		@client.should_receive(:create_http_get_request).and_return {|uri, params|
			the_params = params
			@client_clone.create_http_get_request(uri, params)
		}
		@client.should_receive(:http_connect).and_return Net::HTTPNotFound.mock(:code => '404')

		#	pass through a few we can pick back out
		#	also, side-effect ... nil on invalid response
		@client.search('query_value', :rpp => 3).should be_nil

		the_params.should_not be_nil
		the_params[:q].should eql('query_value')
		the_params[:rpp].should eql(3)
	end</code></code></pre>
</div>
<p>Plus a little mocking of <code>Net::HTTPResponse</code>:</p>
<div class="pre_wrap">
<pre><code>class Net::HTTPResponse
	def self.mock(ops={})
		#	defaults
		ops = {
			:http_version => '1.1',
			:code => '200',
			:message => 'OK',
			:body => nil,
		}.merge(ops || {})

		#	construct
		###clazz = CODE_TO_OBJ[ops[:code]]
		clazz = self
		response = clazz.new(ops[:http_version], ops[:code], ops[:message])

		#	inject
		ops.each do |k, v|
			response.instance_variable_set "@#{k}".to_sym, v
		end

		#	mockulate
		response.instance_eval %q{
			def body; @body; end
		}

		response
	end
end</code></code></pre>
</div>
<p>Nothing like having some good inspiration to get you thinking about maintainability.  I&#8217;m a not a strong adherent to any of the <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> or <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">BDD</a> denominations, but testability itself is close to my heart.  Just ask the folks who&#8217;ll be looking at the micro-assertion Module that I wrote for my <a href="http://www.facebook.com/jobs_puzzles/">Facebook Puzzle</a> submissions (which work locally under test conditions but fail <em>miserably</em> once thrown over their wall).  Then again, I won&#8217;t need to write that (and test that) from scratch again.</p>
<p>So, back to talking glowingly about the <code>Twitter4R</code> architecture.  Yes, I used <strong>that</strong> word.  Yet regardless of that term&#8217;s heavyweightedness, it&#8217;s simply the result of carefully thinking out the formalization of a complex design.  And once a non-author delves into extending an existing implementation, that impl&#8217;s demeanor becomes readily clear :)</p>
<p>Some of the interesting things I saw:</p>
<ul>
<li>An inner <code>bless</code>-ish strategy, to inject the <code>Twitter::Client</code> into instanciated result classes.  I&#8217;ve seen blessing as an OO-Perl-ism, for self-ication, and that metaphor carries over very nicely to this context.</li>
<li>Generous use of blocks / lambdas / closures in methods, for contextual iteration (eg. iterate through each <code>Twitter::Message</code> in a <code>timeline</code> response).  Unnecessary, but an excellent convenience for a language that offers that optional capability in a very disposable fashion (from the caller&#8217;s perspective).</li>
<li>Retroactive sub-object population after construction.  <code>Twitter4R</code> relies upon the <a href="http://json.rubyforge.org/">json</a> gem, which deals primarily in Hashes.  Post-injection, the library itereates through Arrays of Hashes and transforms them into suitable <code>Twiltter::User</code> containers, etc.  A great place to put such logic in the construction chain, and it doesn&#8217;t take long to get really tired of Hash hierarchies.</li>
</ul>
<p>Good stuff, and learning with in a Ruby-centric mindset was invaluable for me.  We all have to start somewhere, eh.</p>
<h3>The Acute Long-Term Pain of Staticness</h3>
<p>There was one issue that I ran into; <em>static configuration</em>.  During my years of using the <a href="http://www.springsource.org/">Spring Framework</a>, my <a href="http://en.wikipedia.org/wiki/Inversion_of_Control">IOC</a>-addled brain started thinking of everything in terms of instances &#8212; Factory Beans, POJOs, Observers &#038; Listeners, Chain-of-Responsibility wrappers.  Static configuration is a common metaphor, and in this case, there&#8217;s a static <code>Twitter::Config</code> instance.  Convenient and centralized.  Makes perfect sense.</p>
<p>I mean, the fact that it was a configurable library <em>at all</em> was awesome.  I was able to easily set up a <code>Twitter::Client</code> to reference <a href="http://search.twitter.com">search.twitter.com</a>.  However, of course as soon as I did that, I whacked the ability for clients to talk to <code>twitter.com</code> in the process.  <em>Oops!</em></p>
<p>On GPs, I refused to modify the original code.  And I wanted to make sure that my superficial tweaks to the library would be thread-safe &#8212; temporarily swaping out the global <code>Twitter::Config</code> in mid-operation would be an issue.  Using <code>Mutex.synchronize</code> seemed like the perfect choice.  After finding that the same thread can&#8217;t lock a <code>Mutex</code> instance twice &#8212; grr!, that&#8217;s a great trick if you can work it &#8212; I overrode the one method that cared the most about <code>@@config</code>:</p>
<div class="pre_wrap">
<pre><code>	@@config_mutex = Mutex.new
	def configuration_mutex
		@@config_mutex
	end

	alias :raw_http_connect :http_connect
	def <strong>http_connect</strong>(*args, &#038;block)
		ops = (Hash === args.last) ? args.pop : {}

		result = nil
		self.configuration_mutex.synchronize do
			ops[:call_before].call if ops[:call_before]
			result = raw_http_connect *args, &#038;block
			ops[:call_after].call if ops[:call_after]
		end

		result
	end

	#
	#	...
	#

	@@SEARCH_CONNECT_HOOKS = {
		:call_before => lambda { self.configure_apply(:search) },
		:call_after => lambda { self.configure_apply(:default) },
	}

	#
	#	...
	#

	#	broken out of closure for mocking
	req = create_http_get_request(uri, params)
	response = http_connect(@@SEARCH_CONNECT_HOOKS) {|conn|	req }
	return nil unless Net::HTTPOK === response

	model = bless_model(Twitter::Search.unmarshal(response.body))</code></code></pre>
</div>
<p>It works like a charm.  Please, everyone just line up to tell me how I could have done it better.  And I don&#8217;t mean <em>quicker</em> or <em>cheaper</em>, I mean better.  Believe me, I would not have sunk the time into this end-around approach, if not for the fact that:</p>
<ol>
<li>I don&#8217;t want to maintain a local gem code modification (even though my impl is closely coupled to the gem impl already)</li>
<li>I intend to follow that practice, so every opportunity to pull and end-around is a Valuable Learning Experience.</li>
</ol>
<p>So, now my local <code>Twitter4R</code> has search capability gracefully latched onto it (and implemented much in the flavor of the library itself).  I have a mass of <code>rspec</code> examples to work off in the future.</p>
<p>Now, I haven&#8217;t spent a great amount of time testing the thread-safeness &#8212; no one in their right mind <em>wants</em> to do that &#8212; but my sundry <code>Twitter::Client</code> instances play nicely together in between searches and normal status operations.</p>
<p>And I had something useful to blog about!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cantremember.com/twitter4r-shifts-rspec-onto-my-front-burner/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
