<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2332267113132659131</id><updated>2012-02-16T01:56:08.559-08:00</updated><category term='Ruby 1.9'/><category term='Watir'/><category term='Conferences'/><category term='RSpec'/><category term='Agile'/><category term='Design Patterns'/><category term='Groovy'/><category term='Books'/><category term='Testing'/><title type='text'>Jim Knowlton's Software Testing Blog</title><subtitle type='html'>Testing, Dynamic Languages and the Occassional Off-Topic Rant...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>36</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-3716714011003925425</id><published>2010-12-30T13:48:00.001-08:00</published><updated>2010-12-30T13:48:41.006-08:00</updated><title type='text'>Testing vs. Analysis</title><content type='html'>&lt;p&gt;There is a clear distinction in white box testing, between “testing” and “analysis”.&amp;nbsp; I think this distinction is important to call out.&amp;nbsp; On the one hand, we have &lt;strong&gt;&lt;em&gt;tests&lt;/em&gt;&lt;/strong&gt;, which are defined as:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;any activity which results in a binary pass/fail result.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;We also have analysis, which does not fulfill the above requirement but must nonetheless be performed.&amp;nbsp; These activities include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;code coverage analysis  &lt;li&gt;static code analysis  &lt;li&gt;dynamic code analysis  &lt;li&gt;performance analysis &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;When examining the work and expected deliverables of a QA team, it’s important to remember that the second group of items above is &lt;strong&gt;not&lt;/strong&gt; testing, and will return no pass/fail status.&amp;nbsp; The fact that it does not means that it is fundamentally different from tests, and needs to be reported to management in its own way, separate from test results.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-3716714011003925425?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/3716714011003925425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=3716714011003925425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3716714011003925425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3716714011003925425'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2010/12/testing-vs-analysis.html' title='Testing vs. Analysis'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-3604946430343305616</id><published>2010-09-15T13:38:00.001-07:00</published><updated>2010-09-15T13:38:49.080-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Lean Testing</title><content type='html'>&lt;p&gt;I’m currently in an Operations Management class as part of the MBA program I’ve been working on.&amp;nbsp; One of the main concepts the class introduces is “&lt;a href="http://en.wikipedia.org/wiki/Lean_manufacturing"&gt;lean manufacturing&lt;/a&gt;”, which was popularized by Toyota.&amp;nbsp; A main concept of it is “the seven types of waste” (or &lt;em&gt;muda&lt;/em&gt;).&amp;nbsp; They are:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Transport (moving products that is not actually required to perform the processing)  &lt;li&gt;Inventory (all components, &lt;a href="http://en.wikipedia.org/wiki/Work_in_process"&gt;work in process&lt;/a&gt; and finished product not being processed)  &lt;li&gt;Motion (people or equipment moving or walking more than is required to perform the processing)  &lt;li&gt;Waiting (waiting for the next production step)  &lt;li&gt;Overproduction (production ahead of demand)  &lt;li&gt;Over Processing (resulting from poor tool or product design creating activity)  &lt;li&gt;Defects (the effort involved in inspecting for and fixing defects)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Related to this, I discovered &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321150783/poppendieckco-20"&gt;“Lean Software Development – An Agile Toolkit”&lt;/a&gt; by &lt;a href="http://www.poppendieck.com/"&gt;Tom and Mary Poppendieck&lt;/a&gt;.&amp;nbsp; This book, published in 2003 (there is also a sequel), tries to marry lean manufacturing with the world of software development.&amp;nbsp; It is an area I’m especially interested in, especially in the realm of software testing.&lt;/p&gt; &lt;p&gt;I’ll be exploring the above areas of waste as they relate to testing in upcoming posts.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-3604946430343305616?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/3604946430343305616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=3604946430343305616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3604946430343305616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3604946430343305616'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2010/09/lean-testing.html' title='Lean Testing'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4705732413895720667</id><published>2010-02-24T09:51:00.000-08:00</published><updated>2010-09-14T16:14:34.910-07:00</updated><title type='text'>Why which scripting language you use (sometimes) doesn’t matter</title><content type='html'>&lt;p&gt;In discussing languages for testing, often the discussions can turn into debates, and the debates can turn into “religious” wars.&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000" face="Times New Roman"&gt;Ruby! &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#800080" face="Magneto"&gt;Python!&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff" face="Courier"&gt;Perl!&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;And the list goes on…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;But in some cases, the scripting language doesn’t matter all that much.&amp;#160; At least, not for testers.&amp;#160; All the scripting languages have some very basic functionality which makes them ideal for testing:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font color="#000000"&gt;test frameworks&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#000000"&gt;exception handling&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#000000"&gt;regular expressions&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#000000"&gt;vast module libraries to deal with things like database access, operating system functions, network connections etc.&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font color="#000000"&gt;And, sometimes it is more important what you’re trying to do than how you’re trying to do it.&amp;#160; Let’s think of, to pay homage to &lt;a href="http://www.exampler.com/blog/"&gt;Brian Marick&lt;/a&gt;, an &lt;em&gt;&lt;strong&gt;example&lt;/strong&gt;.&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Below is a basic example of a web application, and a web services interface to it.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_0_2kCh0mg9Q/S4VnFOKti4I/AAAAAAAAARA/G08rQ6bc84g/s1600-h/epo%20environment%5B4%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="epo environment" border="0" alt="epo environment" src="http://lh6.ggpht.com/_0_2kCh0mg9Q/S4VnFn22jZI/AAAAAAAAARE/sx7IRJSqYtg/epo%20environment_thumb%5B2%5D.jpg?imgmax=800" width="459" height="325" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As you can see, the application can be accessed via the browser.&amp;#160; However, there is also a web services interface (accessed via HTTP basic authentication) where functionality can be exercised simply by passing a URL to the server from a scripted web client.&lt;/p&gt;  &lt;p&gt;This allows a tester to write automation in virtually any scripting language to automate actions on a web application, without having to go through the user interface.&amp;#160; This could render which language you use to automate your tests (almost) irrelevant.&amp;#160; &lt;/p&gt;  &lt;p&gt;However, I still like &lt;font color="#ff0000" face="Times New Roman"&gt;Ruby&lt;/font&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4705732413895720667?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4705732413895720667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4705732413895720667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4705732413895720667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4705732413895720667'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2010/02/why-which-scripting-language-you-use.html' title='Why which scripting language you use (sometimes) doesn’t matter'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_0_2kCh0mg9Q/S4VnFn22jZI/AAAAAAAAARE/sx7IRJSqYtg/s72-c/epo%20environment_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4672776170808027770</id><published>2009-10-30T09:16:00.000-07:00</published><updated>2010-09-14T16:14:34.925-07:00</updated><title type='text'>“Best Practices”…Awful…or just irrelevant?</title><content type='html'>&lt;p&gt;I’ve been having a discussion on Twitter with some folks about the “best practices” term…many people hate it.&amp;#160; The argument against it is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;“Best” compared to what?&amp;#160; Best that’s ever been?&amp;#160; Seems fairly high-minded to call something “best”&lt;/li&gt;    &lt;li&gt;There’s no context.&amp;#160; Practices are more or less suitable depending on their context&lt;/li&gt;    &lt;li&gt;Calling a practice “best” invites contention because it is also a statement about the inferiority of other practices&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here’s my response:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I think anytime you use qualitative terms (“best”, “good”, “practice i like”), there’s subjectivity involved, and deifnitions are imprecise.&amp;#160; So unless we want to throw out all subjectivity (which seems impractical), we have to live with the ambiguity&lt;/li&gt;    &lt;li&gt;I generally use “best practice” as shorthand for “the best practice we as a team can devise, given our current situation.”&amp;#160; “Best practice” is just shorter.&amp;#160; I guess you could just say “practice”, which would be fine.&lt;/li&gt;    &lt;li&gt;I just don’t think it matters much.&amp;#160; I’ve never, ever been on a software project where the use of the “best practice” term caused a heated debate or caused software to ship later or with less quality.&amp;#160; So, it seems to me to be a quest for preciseness for preciseness’ sake.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Those are my thoughts…I’d be interested in hearing others…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4672776170808027770?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4672776170808027770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4672776170808027770' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4672776170808027770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4672776170808027770'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/10/best-practicesawfulor-just-irrelevant.html' title='“Best Practices”…Awful…or just irrelevant?'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-5477770025381255024</id><published>2009-10-27T11:28:00.000-07:00</published><updated>2010-09-14T16:14:34.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='RSpec'/><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>My Presentation for PNSQC</title><content type='html'>Can be found&lt;a href="http://docs.google.com/present/view?id=dgf3s75_0d8z85qgs"&gt; &lt;/a&gt;&lt;a href="http://docs.google.com/present/view?id=dgf3s75_0d8z85qgs"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-5477770025381255024?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/5477770025381255024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=5477770025381255024' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5477770025381255024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5477770025381255024'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/10/my-presentation-for-pnsqc.html' title='My Presentation for PNSQC'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2047001443043712897</id><published>2009-10-07T12:07:00.000-07:00</published><updated>2010-09-14T16:14:34.958-07:00</updated><title type='text'>Playing with Celerity</title><content type='html'>&lt;p&gt;I’ve been playing with JRuby lately.&amp;#160; One of the big reasons we picked Ruby for our test framework instead of JRuby (even though we’re testing a Java application) was Watir, and the fact that JRuby didn’t support it (or it didn’t support JRuby, depending on how you look at it).&amp;#160; I’ve recently been exposed to Celerity (&lt;a title="http://celerity.rubyforge.org/" href="http://celerity.rubyforge.org/"&gt;http://celerity.rubyforge.org/&lt;/a&gt;).&amp;#160; It looks pretty cool.&amp;#160; Here are some features of it:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It’s written for JRuby, so you have access to Java and any Java classes you might need to interface with &lt;/li&gt;    &lt;li&gt;The API is based on Watir, so it should be pretty familiar to test developers used to working in Watir &lt;/li&gt;    &lt;li&gt;It lays on top of Java’s HTMLUnit, so it works a little differently than Watir.&amp;#160; Instead of driving an actual browser (like IE), it communicates with a web server via HTTP – so it basically emulates a browser. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So far, I like it alot.&amp;#160; However, one big issue I’ve been having (which is actually an issue with HTMLUnit) is that in a browser, if I go to a site that uses SSL I get a warning page and I can tell it to ignore certificate issues.&amp;#160; However with HTMLUnit/Celerity, you can’t do that.&amp;#160; It expects SSL sites to have a certificate.&amp;#160; This causes Java exceptions if you don’t have one (like on a testing site).&lt;/p&gt;  &lt;p&gt;I’m still playing with it so maybe there is a workaround.&amp;#160; I hope so – I could see Celerity really filling a niche in the testing world.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2047001443043712897?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2047001443043712897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2047001443043712897' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2047001443043712897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2047001443043712897'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/10/playing-with-celerity.html' title='Playing with Celerity'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2271368589756245064</id><published>2009-08-27T10:30:00.000-07:00</published><updated>2010-09-14T16:14:34.975-07:00</updated><title type='text'>Why you should version-control your tests (and why they should be stored with dev code)</title><content type='html'>&lt;p&gt;You should absolutely version-control your tests.&amp;#160; Alister Scott talks about this &lt;a href="http://watirmelon.com/2009/08/06/version-control-your-automated-tests-quickly-easily-today-for-free/" target="_blank"&gt;in a recent blog post on his WatirMelon blog&lt;/a&gt;.&amp;#160; He also goes through the steps to easily set up an SVN repository on a shared Windows drive.&lt;/p&gt;  &lt;p&gt;I’d go a step further, though.&amp;#160; I think it is a no-brainer that the automated tests need to be stored in the same VC system as the code.&amp;#160; Here’s why:&lt;/p&gt;  &lt;p&gt;So, let’s say you’ve built a set of tests for a build.&amp;#160; You’re ready to ship, and the code is branched.&amp;#160; If you have your automated tests in a separate place from the code, you also have to branch the tests, and maintain the branch and (hopefully) have everything aligned properly.&lt;/p&gt;  &lt;p&gt;However, let’s say in an alternate (happier) universe, you’ve simply created a directory off your &lt;font face="Courier New"&gt;/trunk&lt;/font&gt; called &lt;font face="Courier New"&gt;qa&lt;/font&gt;, which is at a peer level with ‘dev’ (or whatever directory your source code is located in).&amp;#160; So, your directory would look like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;trunk     &lt;br /&gt;╚ dev      &lt;br /&gt;╚ qa&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now, all you do when you do a release is tag and branch everything under &lt;font face="Courier New"&gt;\trunk&lt;/font&gt;.&amp;#160; Then, all the tests appropriate for that version of code will be branched along with the code. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2271368589756245064?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2271368589756245064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2271368589756245064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2271368589756245064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2271368589756245064'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/08/why-you-should-version-control-your.html' title='Why you should version-control your tests (and why they should be stored with dev code)'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-296184737651648172</id><published>2009-08-19T12:57:00.000-07:00</published><updated>2010-09-14T16:14:34.991-07:00</updated><title type='text'>“What should we automate?” – A (partial) answer to the age-old question</title><content type='html'>&lt;p&gt;OK, I tricked you a little bit.&amp;#160; This might not be “the” answer to that age-old question, but it is “an answer”.&amp;#160; &lt;/p&gt;  &lt;p&gt;As Ynigo Montoya said in the movie &lt;em&gt;The Princess Bride&lt;/em&gt;, “Let me explain…no, let me sum up.”&amp;#160; On my project, we have basically three types of automation (from lowest-level to highest-level):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;unit tests &lt;/li&gt;    &lt;li&gt;acceptance tests (below the UI, above the code) &lt;/li&gt;    &lt;li&gt;black-box acceptance tests (driving the UI) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It seems to me to be a truism that the lowest-level test, all other things being equal, brings the greatest value.&amp;#160; So, a unit test, since it is run at checkin and has low cost, has tremendous value to drive quality.&amp;#160; That being the case, as an acceptance test developer, my first question should be, “what is the unit test not covering?”.&amp;#160; I can find this out by perusing the latest code coverage report for the application.&amp;#160; With this information, I can then plan acceptance tests to “plug the holes” wherever they might be in the unit test set.&lt;/p&gt;  &lt;p&gt;Ideally, a product should be mostly covered with unit tests.&amp;#160; However, out in the real world where QA engineers live, this is almost never the case.&amp;#160; Building acceptance tests to plug the holes can insure that the full product functionality is covered by a combination of unit and acceptance tests, and then the black-box testing (both automated and manual) can lay on top of that to validate the UI functionality.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-296184737651648172?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/296184737651648172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=296184737651648172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/296184737651648172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/296184737651648172'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/08/what-should-we-automate-partial-answer.html' title='“What should we automate?” – A (partial) answer to the age-old question'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-1496373329061411114</id><published>2009-08-13T13:02:00.000-07:00</published><updated>2010-09-14T16:14:35.011-07:00</updated><title type='text'>“Making Things Happen” – a first look</title><content type='html'>&lt;p&gt;I’m reading a book on project management called &lt;a href="http://oreilly.com/catalog/9780596517717/" target="_blank"&gt;“Making Things Happen”&lt;/a&gt;, by Scott Berkun.&amp;#160; It’s a great book.&amp;#160; One of the things I like about it is that it shows the universality of good project management principles.&amp;#160; Of course, software engineers can find value in the book, and that was my initial purpose in picking it up at my local bookstore.&amp;#160; However, as I read, I got one of those “aha” moments when you realize something you already knew, but hadn’t thought about in &lt;strong&gt;&lt;em&gt;quite&lt;/em&gt;&lt;/strong&gt; that way before.&lt;/p&gt;  &lt;p&gt;When I speak of the universality of project management, I’m speaking muuuuch more broadly than just the “engineer-business person” spread that people typically refer to.&amp;#160; No….here we’re talking Egyptian pyramids:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The history of engineering projects reveals that most projects have strong similarities.&amp;#160; They have requirements, designs, and constraints.&amp;#160; They depend on communication, decision making, and combinations of creative and logical thought.&amp;#160; Projects usually involve a schedule, a budget, and a customer.&amp;#160; &lt;/p&gt;    &lt;p&gt;Most importantly, the central task of projects is to combine the works of different people into a singular, coherent whole that will be useful to people or customers.&amp;#160; Whether a project is built out of HTML, C++, or cement and steel, there’s an undeniable core set of concepts that most projects share.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I’ve just started reading the book…but I found this really interesting, because we have a tendency to think in the technology industry that our issues are so unique, so never-been-seen-before that there are no models.&amp;#160; In fact, there are.&amp;#160; They might not always be perfect models, but certainly there are things we can learn from the success and failure of those who have come before…sometimes a long time before.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-1496373329061411114?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/1496373329061411114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=1496373329061411114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1496373329061411114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1496373329061411114'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/08/making-things-happen-first-look.html' title='“Making Things Happen” – a first look'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-5053310217689761147</id><published>2009-08-13T12:42:00.000-07:00</published><updated>2010-09-14T16:14:35.029-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>I'm presenting at PNSQC</title><content type='html'>I'll be presenting at the Pacific Northwest Software Quality Conference (PNSQC) in October on "Web Security Testing with Ruby and Watir".  Come say hi!  It looks like I'll be presenting on Oct 27th, in the afternoon...though schedules are fluid, so don't hold me to it.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.google.com/fileview?id=0B2VIeFg5LMV6NTZkMzM2MDktNDAyNC00ZTliLWI3MjAtYWE3OTJlYTk4YzA0&amp;amp;hl=en"&gt;Click here to view a preliminary draft of my paper.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-5053310217689761147?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/5053310217689761147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=5053310217689761147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5053310217689761147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5053310217689761147'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/08/i-presenting-at-pnsqc.html' title='I&amp;#39;m presenting at PNSQC'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-980297066825893810</id><published>2009-07-20T13:36:00.000-07:00</published><updated>2010-09-14T16:14:35.075-07:00</updated><title type='text'>Why Rake is a great tool for test run automation</title><content type='html'>&lt;p&gt;The more I use Rake for automation of our testing process, the more I like it.&amp;#160; Where I work, we have a Java-based web application.&amp;#160; However, I have found that using Rake, not Ant, is definitely the tool of choice for automating the configuration and running of our QA tests.&amp;#160;&amp;#160; Here are some of the reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Rake uses Ruby scripts as their ‘rakefile’&lt;/em&gt; – Ant uses XML files, which are great for storing structured data but have no real ability to perform logic or make decisions.&amp;#160; Rake, on the other hand, uses actual Ruby syntax within their ‘rakefile’, which means you have full access to the Ruby ecosystem.&amp;#160; This allows you to utilize decision structures, closures, even classes if you desire.&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Rake is fully supported by Intellij and TeamCity&lt;/em&gt; – I am not sure what Rake’s support is in other environments, but our development/automation environment is Jetbrains’ Intellij for the IDE and TeamCity for the build automation.&amp;#160; Both have terrific support for Ruby and Rake. &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Rake has great support for RSpec&lt;/em&gt; – RSpec is our test framework…and Rake has great support for it.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some of our tests in the future might be Jython tests run from the server (under the JVM), but they can still be easily launched from a Ruby/RSpec script (via a web services API).&amp;#160; This is ideal, because it gives us the best of both worlds…the ability to quickly script tests through Ruby when possible, but also the ability to access the product’s underlying classes when we need to.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-980297066825893810?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/980297066825893810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=980297066825893810' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/980297066825893810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/980297066825893810'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/07/why-rake-is-great-tool-for-test-run.html' title='Why Rake is a great tool for test run automation'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-6992603629910119830</id><published>2009-07-08T08:56:00.000-07:00</published><updated>2010-09-14T16:14:35.093-07:00</updated><title type='text'></title><content type='html'>Trying out my new look...tell me what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-6992603629910119830?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/6992603629910119830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=6992603629910119830' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/6992603629910119830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/6992603629910119830'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/07/trying-out-my-new-look.html' title=''/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4725776495684540967</id><published>2009-07-07T09:29:00.000-07:00</published><updated>2010-09-14T16:14:35.111-07:00</updated><title type='text'>Java properties files - in Ruby</title><content type='html'>&lt;p&gt;One nice thing about Java is its use of properties files, which are text files with a &lt;em&gt;.properties&lt;/em&gt; extension that contain key-value pairs of data. This way, changeable data can be stored in a file separate from the code. There is a way to do this in Ruby too, with YAML files and the Ruby &lt;strong&gt;YAML&lt;/strong&gt; module.&lt;/p&gt;&lt;p&gt;First, create a YAML file. This is simply a text file with a &lt;em&gt;.YAML&lt;/em&gt; extension, and with key-value pairs of data seperated by a colon. For example, let’s say you wanted to store a user name and password to run your tests with (for illustration purposes – normally it’s not a good idea to store a password in a text file). You’d set up your &lt;em&gt;properties.yaml&lt;/em&gt; file thus:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;username : jim&lt;br /&gt;password : mypassword&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Save the file. Now, you can access those properties through Ruby. Since I love using IRB to test functionality interactively, I’ll recommend you now fire up IRB. For this example, run IRB from the directory you created the YAML file.&lt;/p&gt;&lt;p&gt;Once IRB is up, require the YAML module:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;require ‘yaml’&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now, load the properties file and assign it to a variable:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;properties = YAML.load_file( './properties.yaml' )&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Once this is done, you can use the properties from your YAML file. Let’s say you had a login() method that takes two parameters, the username and password. You could at this point run your method thus:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;login(properties[“username”], properties[“password”])&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This will run your login() method with the username and password you defined in your &lt;em&gt;properties.yaml &lt;/em&gt;file.&lt;/p&gt;&lt;h4&gt;Design principles:&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;For properties &lt;em&gt;that will not change&lt;/em&gt;, I’d suggest you can define those in helper modules.&lt;/li&gt;&lt;li&gt;For properties &lt;em&gt;that will change in different environments&lt;/em&gt;, put them in a YAML file. This makes it much easier to customize a deployment.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4725776495684540967?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4725776495684540967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4725776495684540967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4725776495684540967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4725776495684540967'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/07/java-properties-files-in-ruby.html' title='Java properties files - in Ruby'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-3215862122114866310</id><published>2009-04-21T12:04:00.000-07:00</published><updated>2010-09-14T16:14:35.126-07:00</updated><title type='text'>Urgency vs. priority – an example and an assertion</title><content type='html'>&lt;p&gt;&lt;em&gt;QA Engineer:&amp;#160; So, manager, which is more important, A or B?     &lt;br /&gt;&lt;/em&gt;&lt;em&gt;QA Manager:&amp;#160; Well, engineer, they’re both important…they both have to be done.     &lt;br /&gt;&lt;/em&gt;&lt;em&gt;QA Engineer:&amp;#160; So how do I prioritize them?     &lt;br /&gt;&lt;/em&gt;&lt;em&gt;QA Manager: (a little frustrated)…like I said, they both have to be done.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;How many times has this scenario played out for you?&amp;#160; Many times for me.&amp;#160; So, let’s examine this problem with an example we all experience, our own need for oxygen, water and food.&amp;#160; &lt;/p&gt;  &lt;p&gt;All three are essential to our survival…without any of them, we will die.&amp;#160; There is no way to prioritize them in order of importance.&amp;#160; However, they definitely can be prioritized in order of urgency.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Without oxygen, you would be brain-damaged within minutes (and dead soon thereafter). &lt;/li&gt;    &lt;li&gt;Without water, you would die within days (one website I read said the average person would be dead within 9 days of 80 degree days). &lt;/li&gt;    &lt;li&gt;Without food, you can go months, but eventually you would die. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, although all are essential in the long run, oxygen is most urgent.&amp;#160; &lt;/p&gt;  &lt;p&gt;Does this mean we should always focus on our most urgent needs?&amp;#160; No.&amp;#160; If you focused only on your most urgent need (oxygen), and never paid attention to less urgent but equally essential needs (food and water), you would still die, albeit more slowly.&amp;#160; &lt;/p&gt;  &lt;p&gt;I think the lesson of this allegory is that we sometimes ask the wrong question.&amp;#160; A better question would be “which is more urgent to test, a or b?”&amp;#160; And if both are equally urgent, as well as equally important, then the laws of physics come into play, and you lay out how long each will take, and the amount of time you have available.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;One final note:&lt;/strong&gt;&amp;#160; this principle will certainly not alleviate the “I need everything done, and I need it yesterday!” issue.&amp;#160; But I do think it sheds some additional light on the questions to ask when prioritizing. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-3215862122114866310?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/3215862122114866310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=3215862122114866310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3215862122114866310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3215862122114866310'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/04/urgency-vs-priority-example-and.html' title='Urgency vs. priority – an example and an assertion'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-1579930996622606045</id><published>2009-04-16T13:39:00.000-07:00</published><updated>2010-09-14T16:14:35.139-07:00</updated><title type='text'>Another thing to love about RSpec</title><content type='html'>&lt;p&gt;I’ve been busy working on refactoring our test framework, and I ran across a gem (spoken in the usual sense, not in the RubyGem sense).&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;RSpec has a method for running a block of code before and after each example, before(:each) and after(:each).&amp;#160; Its syntax is pretty simple:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;describe “this is my feature” do&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;#160; before(:each)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; do_this_before_each_example()       &lt;br /&gt;&amp;#160; end       &lt;br /&gt;&amp;#160; after(:each)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and_do_this_at_the_end_of_each_example()       &lt;br /&gt;&amp;#160; end       &lt;br /&gt;&amp;#160; it “should be example 1” do       &lt;br /&gt;&amp;#160; end       &lt;br /&gt;&amp;#160; it “should be example 2” do       &lt;br /&gt;&amp;#160; end&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;end&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This is pretty standard stuff.&amp;#160; The &lt;strong&gt;&lt;em&gt;cool &lt;/em&gt;&lt;/strong&gt;part is you can also use a before(:all) and after(:all) method to do stuff (like major setup and teardown) once at the beginning of the describe block, and the after(:all) at the very end.&amp;#160; Since it can be tied to any describe block, it’s completely flexible how big a block of example it applies to.&lt;/p&gt;  &lt;p&gt;The more I use Ruby for testing…the less reason I have for looking at other languages.    &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-1579930996622606045?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/1579930996622606045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=1579930996622606045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1579930996622606045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1579930996622606045'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/04/another-thing-to-love-about-rspec.html' title='Another thing to love about RSpec'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-858113127463556976</id><published>2009-04-07T16:23:00.000-07:00</published><updated>2010-09-14T16:14:35.150-07:00</updated><title type='text'>Watir and security testing of web applications</title><content type='html'>&lt;p&gt;One of the tasks I have at work is security testing.&amp;#160; Watir makes a great tool for security testing of web apps.&amp;#160; There are several reasons for this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Many of the common security vulnerabilities related to web applications (SQL Injection, cross-site scripting, buffer overflow) have to do with simply posting different types of information to a web server via a client.&amp;#160; This is pretty much what Watir is all about.&amp;#160; It even gives you access to hidden elements, so it really is a great tool for submitting form data to a web server.&lt;/li&gt;    &lt;li&gt;The Ruby side of Watir, being a full-service language, has great tools for querying the database, checking audit logs and the like.&amp;#160; Also, you can generate random data (or large datasets) to throw at a web app, or even pull the test data from a CSV file.&lt;/li&gt;    &lt;li&gt;There are some things you might not be able to do through Watir, but can certainly be done with Ruby.&amp;#160; Again, this is perfect – because Watir is not really a test framework, it’s just a way to drive the Browser when you need to.&amp;#160; So, tests which are more low-level (such as web service communication or network tests) can be run through Ruby and RSpec, or whatever actual test framework you’re using.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In short, Watir makes a terrific tool in your arsenal for web security testing.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-858113127463556976?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/858113127463556976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=858113127463556976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/858113127463556976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/858113127463556976'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/04/watir-and-security-testing-of-web.html' title='Watir and security testing of web applications'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-7215153210126167632</id><published>2009-04-03T13:11:00.000-07:00</published><updated>2010-09-14T16:14:35.163-07:00</updated><title type='text'>Watir Design Patterns?</title><content type='html'>&lt;p&gt;I think the biggest thing a lot of us Watir developers need is a good guide to design patterns with Watir.&amp;#160; I know for myself, I know the commands and basic syntax pretty well, and can design a test structure that works, but I'm sure there are things I'm doing that could be designed better (I'm a tester, after all, not a full-time programmer).&amp;#160; I'd love a guide that describes best practices for how to set up a directory structure, set up rake for common tasks, etc. &lt;/p&gt;  &lt;p&gt;I know &lt;a href="http://github.com/bret/watircraft/tree/master"&gt;WatirCraft&lt;/a&gt; attempts to address this to some extent, but I guess I'm suggesting that some people might need to design their own framework, but not know how to do it.&lt;/p&gt;  &lt;p&gt;My two cents.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-7215153210126167632?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/7215153210126167632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=7215153210126167632' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7215153210126167632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7215153210126167632'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/04/watir-design-patterns.html' title='Watir Design Patterns?'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-7775953550254596460</id><published>2009-04-01T15:29:00.000-07:00</published><updated>2010-09-14T16:14:35.183-07:00</updated><title type='text'>Axiom Wednesday</title><content type='html'>&lt;p&gt;I’ve decided to start a tradition (April Fools’ Day is as good a day as any to start this, right?).&amp;#160; I often come across axioms in software development…short, pithy statements that attempt to express some greater truth.&amp;#160; Some are terrific.&amp;#160; Some a little less so.&amp;#160; Every Wednesday, I’ll explore one.&lt;/p&gt;  &lt;h5&gt;Today’s axiom is:&amp;#160; Read more code.&amp;#160;&amp;#160; Ideally, read more code than you write.&lt;/h5&gt;  &lt;p&gt;I extracted this axiom from &lt;a href="http://blog.grayproductions.net/"&gt;James Edward Gray II’s&lt;/a&gt; great presentation at &lt;a href="http://mwrc2009.confreaks.com/"&gt;MountainWest RubyConf 2009&lt;/a&gt;.&amp;#160; It really makes perfect sense…if you want to be a great writer, you read.&amp;#160; Lots.&amp;#160; None of us would respect a writer who didn’t read much.&amp;#160; Yet it’s all too common (I’m guilty too, I admit) to not really seek out code to read.&amp;#160; With basically all of the Ruby universe being open-source, there is a treasure-trove of interesting code to look at.&lt;/p&gt;  &lt;p&gt;One tip James gave at the conference was to not start out by finding the hairiest, most complex code to look at.&amp;#160; find a module that is fairly simple and straightforward (actually, Watir is great for this), and look at the source to see how it’s put together.&lt;/p&gt;  &lt;p&gt;Some advantages James mentions of reading code:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It can show you common idioms &lt;/li&gt;    &lt;li&gt;It’s good to practice breaking down possibly challenging code, because you will always have to work with other’s code &lt;/li&gt;    &lt;li&gt;Understanding how something works give you insight into any limitations it has &lt;/li&gt;    &lt;li&gt;Seeing bad code helps you write better code &lt;/li&gt;    &lt;li&gt;Knowledge workers always need more ideas &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-7775953550254596460?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/7775953550254596460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=7775953550254596460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7775953550254596460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7775953550254596460'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/04/axiom-wednesday.html' title='Axiom Wednesday'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-7886230173425187346</id><published>2009-03-31T10:53:00.000-07:00</published><updated>2010-09-14T16:14:35.204-07:00</updated><title type='text'>Why I chose Ruby</title><content type='html'>&lt;p&gt;At work, I write automated tests for a Java-based web application.&amp;#160; I’ve had several people ask me why I chose to implement tests in Ruby instead of Groovy.&amp;#160; The answer is actually pretty interesting.&lt;/p&gt;  &lt;p&gt;First of all, we started out in Groovy, and still have some Groovy-based tests.&amp;#160; I can see cases where we will still use Groovy.&amp;#160; It is a great way to script JVM-based applications.&amp;#160; However, for application tests, there were some components of Ruby that, in my mind, made it better as a test framework language:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Watir&lt;/strong&gt; – There simply isn’t a Groovy-based or Java-based tool that is as full-featured, mature and easy-to-use as &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt;.&amp;#160; Some of you may retort, “what about &lt;a href="http://watij.com/"&gt;Watij&lt;/a&gt;?”.&amp;#160; Watij is an attempt to port the functionality of Watir to Java/Ruby.&amp;#160; It’s very interesting, but hasn’t released an update in quite a while and in my tests with it, it wasn’t nearly as stable or “clean” as Watir.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;RubyGems&lt;/strong&gt; – One of my pet peeves about Java is that installing third-party modules and getting them to work is like a toothache, earache and sinus infection all at the same time.&amp;#160; Ruby, on the other hand, has &lt;a href="http://docs.rubygems.org/"&gt;RubyGems&lt;/a&gt;.&amp;#160; Basically, all I do is go to the ruby/bin directory, type ‘gem install &amp;lt;module name&amp;gt;’ and follow the prompts.&amp;#160; That’s it.&amp;#160; If there are dependencies, I’m prompted to install them.&amp;#160; It’s clean, simple and works seamlessly.&amp;#160; I actually think it is the best package-management system of any open-source language…period.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;RSpec&lt;/strong&gt; – Other than being able to describe tests in english as behavior I expect (which I really like), a feature I love about &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; is that I can create a slick HTML report simply with a command-line switch when I run the tests.&amp;#160; No &lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; (or Ant, if you’re a Java-phile) tasks required, no nothing else required.&amp;#160; Simple, and to the point.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;What all of these technologies have in common tells us a lot about what is important to testers in a test development environment.&amp;#160; All these tools:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Are simple to set up&lt;/li&gt;    &lt;li&gt;Have abundant online documentation&lt;/li&gt;    &lt;li&gt;Are very stable and solid…they work.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;None of this pertains to why I love Ruby as a language (which I do).&amp;#160; All these examples show that when it comes to test development, the availability of simple, easy-to-set-up, easy-to-use tools is absolutely critical.&amp;#160; And it’s why I picked Ruby.&lt;/p&gt;  &lt;p&gt;Oh, one other thing…the community rocks.&amp;#160; I’ve often posted questions and gotten answers within an hour.&amp;#160; Gotta love that.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-7886230173425187346?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/7886230173425187346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=7886230173425187346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7886230173425187346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7886230173425187346'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/why-i-chose-ruby.html' title='Why I chose Ruby'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2185798661579917862</id><published>2009-03-30T16:21:00.000-07:00</published><updated>2010-09-14T16:14:35.216-07:00</updated><title type='text'>Programming through vagueness</title><content type='html'>&lt;p&gt;It may sound counterintuitive, but one of the tidbits I’ve gotten from Russ Olsen’s &lt;a href="http://designpatternsinruby.com/"&gt;Design Patterns in Ruby&lt;/a&gt; is the idea of writing classes and methods in as general a form as possible.&amp;#160; He discusses an example of different types of vehicles and writes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a name="type possible"&gt;&lt;/a&gt;By writing code that uses the most general type possible—for example, by treating all of our planes and trains and cars like vehicles whenever we can—we reduce the total amount of coupling in our code. Instead of having 42 classes that are all tied to cars and boats and airplanes, perhaps we end up with 40 classes that know only about vehicles. Chances are that the remaining two classes will still give us trouble if we have to add another kind of vehicle, but at least we have limited the damage. &lt;/p&gt;    &lt;p&gt;In fact, if we have to change only a couple of classes, we have succeeded in separating out the parts that need to change (the two classes) from the parts that stay the same (the other 40 classes). The cumulative effect of turning down the coupling volume is that our code tends to be less likely to shatter in a horrendous chain reaction in the face of change.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This has tremendous value for testing.&amp;#160; Instead of writing methods like:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;load_preferences_page()      &lt;br /&gt;load_users_page()       &lt;br /&gt;load_security_page()&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;we can create a single, general method and simply pass it parameters thus:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;load_page(preferences)      &lt;br /&gt;load_page(users)       &lt;br /&gt;load_page(security)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This way, if the method needs to be changed, you only have to change one method, making the code easier to maintain and much less error-prone.&lt;/p&gt;  &lt;p&gt;Pretty elementary for you object-oriented veterans…but cool stuff nonetheless!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2185798661579917862?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2185798661579917862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2185798661579917862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2185798661579917862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2185798661579917862'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/programming-through-vagueness.html' title='Programming through vagueness'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-6031403497141585046</id><published>2009-03-24T16:44:00.000-07:00</published><updated>2010-09-14T16:14:35.233-07:00</updated><title type='text'>Running “cleanup” the beginning of a test</title><content type='html'>&lt;p&gt;Often a test will execute a “cleanup” method to delete items (often out of a database) that were created or used in the test, to make sure the next test has a clean environment to run in.&amp;#160; Sometimes though, the cleanup never gets run – if it is the last thing to run (as would seem logical), if there is a test failure it will never execute.&lt;/p&gt;  &lt;p&gt;A better option is to run the cleanup method at the &lt;em&gt;beginning&lt;/em&gt; of a test.&amp;#160; If the method simply executes SQL scripts to delete records, if the records for some reason aren’t found, it won’t generate any kind of error, so the script will run normally.&amp;#160; However, doing it this way (putting the cleanup at the beginning) insures the data cleanup will get executed on every test, insuring a clean environment for every test that gets run.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-6031403497141585046?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/6031403497141585046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=6031403497141585046' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/6031403497141585046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/6031403497141585046'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/running-cleanup-beginning-of-test.html' title='Running “cleanup” the beginning of a test'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2487406236845114321</id><published>2009-03-18T14:56:00.000-07:00</published><updated>2010-09-14T16:14:35.248-07:00</updated><title type='text'>MountainWest RubyConf 2009 videos starting to appear…</title><content type='html'>&lt;p&gt;Get them &lt;a href="http://mwrc2009.confreaks.com/"&gt;here&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2487406236845114321?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2487406236845114321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2487406236845114321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2487406236845114321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2487406236845114321'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/mountainwest-rubyconf-2009-videos.html' title='MountainWest RubyConf 2009 videos starting to appear…'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-5282851465938641483</id><published>2009-03-18T09:44:00.000-07:00</published><updated>2010-09-14T16:14:35.262-07:00</updated><title type='text'>Some quick hits from MountainWest RubyConf 2009</title><content type='html'>&lt;p&gt;I’ll write more on this later, but just wanted to drop a quick note on MountainWest RubyConf 2009, which I went to last weekend in Salt Lake City.&amp;#160; I really loved the conference, and hope it continues to grow.&amp;#160; I like that they don’t pack the conference with alot of expensive frills, and just basically focus on providing content.&amp;#160; Here’s my quick takeaways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Wow…lots of Macs.&amp;#160; I feel like an endangered species here with my Windows laptop. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.grayproductions.net/"&gt;James Edward Gray II&lt;/a&gt;:&amp;#160; we should be reading more code than we write.&amp;#160; No one would think much of a writer who didn’t read much. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://sequel.rubyforge.org/"&gt;Sequel&lt;/a&gt; looks really cool.&amp;#160; Jeremy Evans, who is the creator, gave this presentation.&amp;#160; I have been just using DBI and sending SQL queries “natively”, but I really like the way Sequel Rubifies database access. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.jeremymcanally.com/"&gt;Jeremy McAnally&lt;/a&gt; was hilarious – and I learned some things too, but need to re-look at my notes to remember what those things were. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.benmabey.com/"&gt;Ben Mabey&lt;/a&gt; gave an interesting talk on &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;…I’m still a little fuzzy on how it differs from &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, or what domain it occupies vs. RSpec…but I’ll definitely look into it further.&amp;#160; The RSpec book covers Cucumber as well, so I’m sure I’ll delve deeper.&amp;#160; Besides, any framework named after &lt;a href="http://en.wikipedia.org/wiki/Cucumber"&gt;vegetation&lt;/a&gt; can’t be all bad. &lt;/li&gt;    &lt;li&gt;Philippe Hanrigou spoke about learning lessons from Smalltalk…in a greater sense, he spoke of learning from the masters, which I think is a cool topic.&amp;#160; I think we can learn from everyone who comes before us, and learning about DaVinci can make us better Ruby coders.&amp;#160; Weird, huh. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;All in all, a great experience.&amp;#160; Some of it went over my head, and some was Rails-specific.&amp;#160; But much of the conference was really useful, and I look forward to going back next year.&amp;#160; Maybe I’ll see you there.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-5282851465938641483?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/5282851465938641483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=5282851465938641483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5282851465938641483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/5282851465938641483'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/some-quick-hits-from-mountainwest.html' title='Some quick hits from MountainWest RubyConf 2009'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4761528414600838234</id><published>2009-03-09T13:50:00.000-07:00</published><updated>2010-09-14T16:14:35.279-07:00</updated><title type='text'>Why Ruby is great as a “sticky” test framework</title><content type='html'>&lt;p&gt;One great advantage of developing a test framework in a scripting language like Ruby is that it allows you to glue together different types of tests in a single framework.&amp;#160; &lt;/p&gt;  &lt;p&gt;Here’s a perfect example.&lt;/p&gt;  &lt;p&gt;I had to write a test checking all the log files in a directory structure for a text string (in this case, a password).&amp;#160; In other words, I wanted to make sure the password wasn’t stored in plain text anywhere in the log files.&amp;#160; I found that Powershell has some awesome tools for doing this type of search on a Windows machine.&amp;#160; So, I wrote a Powershell script to search the directory, and if a match is found, it creates a “fail.txt” file:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;if (test-path fail.txt)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; del fail.txt       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;$adminSearch = dir -rec -filter *.log 'c:\windows\temp' |      &lt;br /&gt;select-string &amp;quot;PASSWORD=thisisthepassword&amp;quot;       &lt;br /&gt;if (!$adminSearch)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Write-Output(&amp;quot;pass&amp;quot;)       &lt;br /&gt;}       &lt;br /&gt;else       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Write-Output(&amp;quot;fail&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Write-Output([string]$adminSearch.count + &amp;quot; instances of passwords in log files: &amp;quot;) |       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; out-file -encoding ASCII -filepath fail.txt       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Write-Output($adminSearch) | out-file -append -noclobber -encoding ASCII -filepath fail.txt       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This done, I then write a Ruby/RSpec script that simply checks for the existence of the &lt;em&gt;fail.txt&lt;/em&gt; file:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;require 'spec' &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;describe &amp;quot;Information Disclosure Prevention&amp;quot; do &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;&amp;#160; it &amp;quot;Should not show passwords in plain text&amp;quot; do      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; system(&amp;quot;powershell.exe -File ./lib/passwordsearch.ps1 -command \&amp;quot;&amp;amp; {set-executionpolicy unrestricted}\&amp;quot;&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result = FileTest.exists?(&amp;quot;fail.txt&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result.should == false       &lt;br /&gt;&amp;#160; end       &lt;br /&gt;end&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;And that’s it.&amp;#160; As you can see, it’s easy to wrap RSpec examples inside any command/script that can be run from the command line.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4761528414600838234?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4761528414600838234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4761528414600838234' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4761528414600838234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4761528414600838234'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/why-ruby-is-great-as-sticky-test.html' title='Why Ruby is great as a “sticky” test framework'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4386745059213998060</id><published>2009-03-04T11:18:00.000-08:00</published><updated>2010-09-14T16:14:35.294-07:00</updated><title type='text'>Getting elements – Firebug to the rescue</title><content type='html'>&lt;p&gt;In using Watir, probably one of the biggest challenges is accessing elements that are buried inside several layers of Ajax/HTML.&amp;#160; You can run the &lt;font face="Courier New"&gt;show_all_objects()&lt;/font&gt; method, but that doesn’t always show everything on the page, and it can be difficult to parse through manually.&amp;#160; So what’s a test developer to do?&lt;/p&gt;  &lt;p&gt;Firebug to the rescue.&lt;/p&gt;  &lt;p&gt;Firebug is a Firefox plugin that provides several useful tools, but one is that it has a great DOM inspector that allows you to easily copy any HTML element on a page by simply clicking the “Inspect” button and clicking on the element to be inspected.&amp;#160; It then allows you to easily copy the element text to the clipboard.&lt;/p&gt;  &lt;p&gt;I will often use Firebug and watir-console together when building a test method.&amp;#160; There are times when I’m not sure of the best way to access an element, but with watir-console and Firebug running, I can experiment and fiddle with different code blocks, and find out what will work best.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://getfirebug.com/"&gt;Check it out here.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s a screenshot:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_0_2kCh0mg9Q/Sa7UDvqQBOI/AAAAAAAAANU/elyS5AM1R2k/s1600-h/firebug%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="firebug" border="0" alt="firebug" src="http://lh5.ggpht.com/_0_2kCh0mg9Q/Sa7UEB-6swI/AAAAAAAAANY/zy7aK50odtI/firebug_thumb%5B2%5D.jpg?imgmax=800" width="450" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4386745059213998060?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4386745059213998060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4386745059213998060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4386745059213998060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4386745059213998060'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/getting-elements-firebug-to-rescue.html' title='Getting elements – Firebug to the rescue'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_0_2kCh0mg9Q/Sa7UEB-6swI/AAAAAAAAANY/zy7aK50odtI/s72-c/firebug_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-3450407956079400417</id><published>2009-03-02T10:18:00.000-08:00</published><updated>2010-09-14T16:14:35.308-07:00</updated><title type='text'>Playing with Celerity</title><content type='html'>&lt;p&gt;I’ve started playing with a cool port of &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt; to &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;…it’s called Celerity.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://celerity.rubyforge.org/"&gt;Here’s the website.&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;This is how it is described on the website:&lt;/p&gt;  &lt;blockquote&gt;   &lt;h4&gt;Features&lt;/h4&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://celerity.rubyforge.org/benchmarks.html"&gt;Fast&lt;/a&gt; - No time-consuming &lt;acronym&gt;GUI&lt;/acronym&gt; rendering or unessential downloads &lt;/li&gt;      &lt;li&gt;Easy to use - Simple API &lt;/li&gt;      &lt;li&gt;&lt;a href="http://htmlunit.sourceforge.net/javascript.html"&gt;JavaScript support&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;Scalable - Java threads lets you run tests in parallel &lt;/li&gt;      &lt;li&gt;Portable - Cross-platform thanks to the JVM &lt;/li&gt;      &lt;li&gt;Unintrusive - No browser window interrupting your workflow (runs in background) &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;One issue I’ve had with Celerity (and JRuby in general) is that Watir supports SSL out-of-the-box, whereas with Celerity (or JRuby), when I try to access an SSL address, I get a Java exception that the certificate can’t be found.&amp;#160; I’m sure there is a workaround, but haven’t worked on it yet.&amp;#160; &lt;/p&gt;  &lt;p&gt;Other than that, I’ve played with it on a non-SSL website, and it seems to work exactly like Watir, only much faster and with no browser showing up.&amp;#160; Pretty cool.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-3450407956079400417?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/3450407956079400417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=3450407956079400417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3450407956079400417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/3450407956079400417'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/03/playing-with-celerity.html' title='Playing with Celerity'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-609448517758331414</id><published>2009-02-26T14:46:00.000-08:00</published><updated>2010-09-14T16:14:35.323-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>This might be a "duh!" thing but...</title><content type='html'>it was a new concept for me.  I always wondered why some of the methods in the Watir RDoc didn't have any documentation.  I asked Bret Pettichord about it, and it basically the gist is that if a method isn't documented, you can assume it is a non-public interface (not to be called directly).  &lt;br /&gt;&lt;br /&gt;I'm sure this is probably how things are normally done in the programming-language world, but it was new to me.  Thanks to Bret for providing this insight.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-609448517758331414?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/609448517758331414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=609448517758331414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/609448517758331414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/609448517758331414'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/this-might-be-thing-but.html' title='This might be a &amp;quot;duh!&amp;quot; thing but...'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-8468565099997442660</id><published>2009-02-26T09:41:00.000-08:00</published><updated>2010-09-14T16:14:35.336-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='RSpec'/><title type='text'>Integrating Ruby testing in Intellij and TeamCity...made easy</title><content type='html'>One of the greatest things about scripting languages is that they can work entirely through the command line and require very little in the way of infrastructure.&lt;br /&gt;&lt;br /&gt;For example, in my environment at work, our development environment is Java, and the tools are very Jetbrain-centric.  They use Intellij for their and IDE and (more important for me) use TeamCity for continuous integration.  This has two implications for me:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;JetBrains has a Ruby plugin for Intellij which works really well, so I can use the same dev environment as our developers, even though I'm working in Ruby.  It has code highlighting and code intelligence, and generally works well.  I'm also playing with RubyMine, a Jetbrains all-Ruby IDE.  It is based on Intellij so it has a great editor, but also supports Rake and has a nifty GUI test runner.  Right now it's in "free preview mode", I'm told when it releases it will be $99, which seems pretty reasonable.&lt;/li&gt;&lt;li&gt;One requirement I had when I started working for McAfee is that our component-level tests integrate into our TeamCity environment, so that test runs could be scheduled to be kicked off and so that test results would be easily viewable by anyone on the team at the location they are already going to.  This was easy, because TeamCity has a "command line" option for it's build runner.  That means anything that can be kicked off through the command line can be scheduled to run.  Of course, this includes RSpec-enabled Ruby scripts.  Since RSpec includes an option to output to HTML, and since TeamCity has a way of pointing to build "artifacts" to view from their website, I just set up my configuration so that the script outputs to an HTML file, and then pointed to that HTML file as my build artifact.  In this way, I can run Ruby tests and produce an HTML report in the TeamCity environment.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-8468565099997442660?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/8468565099997442660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=8468565099997442660' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/8468565099997442660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/8468565099997442660'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/integrating-ruby-testing-in-intellij.html' title='Integrating Ruby testing in Intellij and TeamCity...made easy'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-117599209179836954</id><published>2009-02-25T11:22:00.000-08:00</published><updated>2010-09-14T16:14:35.351-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>Customizing watir-console</title><content type='html'>Watir comes with a really cool command-line tool called watir-console. To start it, just type &lt;em&gt;watir-console &lt;/em&gt;at a prompt (assuming you have the ruby\bin directory in your path). It will bring up an irb prompt, but this isn't just any irb prompt. It has already required the watir module, and offers some cool features for interactively using Watir, such as tab completion of Watir commands.&lt;br /&gt;&lt;br /&gt;One thing you can do to make watir-console even more useful is to write a startup script. Here are the steps:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a helper script and put it in one of the Ruby library directories (such as C:\ruby\lib\ruby\1.8). Let's call it helper.rb.&lt;/li&gt;&lt;li&gt;Create a .irbrc file (just a text file) and store it in \ruby\bin. This is actually a Ruby file, and can have any Ruby commands you want to start up when Ruby starts. For our purposes, your script should 'require' the script you built in step 1.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That's it! Now, helper.rb (and its methods and constants) will be available in watir-console whenever you run it.&lt;/p&gt;&lt;p&gt;"What should I put in helper.rb", you ask? I'm a believer in examples, so here are a few examples of methods I created:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A &lt;strong&gt;'login()'&lt;/strong&gt; method to start a browser, go to the login page for my web app and log in. It returns the IE object, so it can be called from watir-console as "instance = login()". This allows you to then access "instance" as the IE instance to be manipulated.&lt;/li&gt;&lt;li&gt;Now you can run different methods to do different things. For example, my application does queries, so I have a &lt;strong&gt;'new_query()'&lt;/strong&gt; method that simply navigates to the page where I can create a query. It is accessed by calling &lt;em&gt;'new_query(instance)'&lt;/em&gt; from watir-console.&lt;/li&gt;&lt;/ul&gt;This makes Watir and watir-console indispensable in interactively testing web applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-117599209179836954?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/117599209179836954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=117599209179836954' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/117599209179836954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/117599209179836954'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/customizing-watir-console.html' title='Customizing watir-console'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4384657960689632957</id><published>2009-02-24T07:41:00.000-08:00</published><updated>2010-09-14T16:14:35.365-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby 1.9'/><title type='text'>Peter Cooper lists 23 useful Ruby 1.91 links...check them out, I have (well, most of them)</title><content type='html'>&lt;a href="http://www.rubyinside.com/23-useful-ruby-19-links-and-resources-1498.html"&gt;Here's the link...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My personal favorite...Dave Thomas' &lt;a href="http://pragdave.blogs.pragprog.com/pragdave/2008/10/fun-with-ruby-19-regular-expressions.html"&gt;"Fun with Ruby 1.9 Regular Expressions"&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4384657960689632957?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4384657960689632957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4384657960689632957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4384657960689632957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4384657960689632957'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/peter-cooper-lists-23-useful-ruby-191.html' title='Peter Cooper lists 23 useful Ruby 1.91 links...check them out, I have (well, most of them)'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2629428774519467028</id><published>2009-02-23T15:29:00.000-08:00</published><updated>2010-09-14T16:14:35.383-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Ruby Design Patterns - an epiphany</title><content type='html'>&lt;div class="Section1"&gt;&lt;p class="MsoNormal"&gt;I’ve been reading Russ Olsen’s great book, &lt;i&gt;&lt;a href="http://designpatternsinruby.com/"&gt;Design Patterns in Ruby&lt;/a&gt;.&lt;/i&gt;  I’ve always had my developer friends tell me design patterns are a great thing, the &lt;a href="http://en.wikipedia.org/wiki/Peanut_butter_and_jelly_sandwich"&gt;jelly to your peanut butter&lt;/a&gt;, the &lt;a href="http://en.wikipedia.org/wiki/Martin_and_Lewis"&gt;Martin to your Lewis&lt;/a&gt; if you are a software developer.  I gave it the typical…”huh…I’ll have to check that out...&lt;i&gt;sometime.&lt;/i&gt;”&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;No longer.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;As have been reading Olsen’s book, I am realizing, it has far-reaching implications that go beyond just writing a Ruby class efficiently.  For instance, one of the principles is “separate the things likely to change from the things likely to stay the same.”  This sounds simple…and it is.  But it’s also incredibly powerful.  Have you ever created a large suite of manual test steps, only to have the software change and need to re-write virtually all of them?  If you apply this principle, your manual test scripts will be more durable and more flexible.  And it didn’t involve writing a single line of Ruby (or any) code.  It simply involved applying a true principle.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Take a look at this book…it will definitely cause you to think in a different way.  And that’s always a good thing.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2629428774519467028?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2629428774519467028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2629428774519467028' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2629428774519467028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2629428774519467028'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/ruby-design-patterns-epiphany.html' title='Ruby Design Patterns - an epiphany'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-7583832559144757454</id><published>2009-02-21T15:43:00.000-08:00</published><updated>2010-09-14T16:14:35.398-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RSpec'/><category scheme='http://www.blogger.com/atom/ns#' term='Watir'/><title type='text'>Brett Pettichord working on new Watir testing framework</title><content type='html'>&lt;a href="http://www.io.com/~wazmo/blog/archives/2009_02.html#000291"&gt;Brett Pettichord's latest blog post &lt;/a&gt;has some information on a new Watir-based testing framework.  It looks pretty interesting.  Since I use Watir extensively for my testing work, I have a particular interest in Brett's work. &lt;br /&gt;&lt;br /&gt;I guess my initial question is...what exactly does it provide that Watir/RSpec doesn't?  I might download and play with it some...will blog about my impressions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-7583832559144757454?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/7583832559144757454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=7583832559144757454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7583832559144757454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/7583832559144757454'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/brett-pettichord-working-on-new-watir.html' title='Brett Pettichord working on new Watir testing framework'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-1361498525280334396</id><published>2009-02-21T10:21:00.000-08:00</published><updated>2010-09-14T16:14:35.413-07:00</updated><title type='text'>MountainWest RubyConf 2009 - see ya there</title><content type='html'>I’ll be at the &lt;a href="http://mtnwestrubyconf.org/2009/"&gt;Mountain West RubyConf 2009 &lt;/a&gt;in Salt Lake City March 13-14…if you’ll be there, look me up. I hope to make some good contacts in Rubyland and learn some stuff. Besides, my work is paying for the conference, so who can beat that?&lt;br /&gt;&lt;br /&gt;Also, I may be presenting to the Software Association of Oregon (SOA) in the near future about Ruby, Watir and RSpec (and how to build a web testing framework using them). Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-1361498525280334396?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/1361498525280334396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=1361498525280334396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1361498525280334396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/1361498525280334396'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/mountainwest-rubyconf-2009-see-ya-there.html' title='MountainWest RubyConf 2009 - see ya there'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-4841960688678440185</id><published>2009-02-21T10:20:00.000-08:00</published><updated>2010-09-14T16:14:35.429-07:00</updated><title type='text'>The idea behind this blog</title><content type='html'>I’m a software qa engineer who works with Ruby, Watir and RSpec every day, and I noticed there weren’t any blogs out in the ’sphere for folks like me. So, here I am. I often have more questions than answers, but I figured maybe if I just start writing, others might find something here that’s useful too.&lt;br /&gt;&lt;br /&gt;Welcome to my black-cloud-qa-type, Ruby world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-4841960688678440185?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/4841960688678440185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=4841960688678440185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4841960688678440185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/4841960688678440185'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2009/02/idea-behind-this-blog.html' title='The idea behind this blog'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-8635827973390351292</id><published>2008-07-18T08:31:00.000-07:00</published><updated>2008-07-18T08:40:30.140-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>"The Simplest Thing that Could Possibly Work"...or not</title><content type='html'>&lt;a href="http://blog.jayfields.com/2008/06/simplest-thing-that-could-possibly-work.html"&gt;In a recent blog post&lt;/a&gt;, Jay Fields argues that the canonical (at least in the agile world) "Simplest Thing that Could Possibly Work" tenet might need some caveats:&lt;br /&gt;&lt;blockquote&gt;Often the emphasis of the phrase is like so: the &lt;strong&gt;&lt;em&gt;simplest&lt;/em&gt;&lt;/strong&gt; thing that could possibly work. However, recently &lt;a href="http://iansrobinson.com/2008/06/26/simplest-thing-that-could-possibly-work/"&gt;Ian Robinson&lt;/a&gt; was discussing the idea that the emphasis should be: the simplest thing that could &lt;strong&gt;&lt;em&gt;possibly&lt;/em&gt;&lt;/strong&gt; work. The difference is only emphasis, but it's a change worth considering.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I'd suggest that we go one further, and emphasize it as the simplest thing that could possibly &lt;strong&gt;&lt;em&gt;work&lt;/em&gt;&lt;/strong&gt;.  When you think about it, what does it mean to work? &lt;br /&gt;&lt;ul&gt;&lt;li&gt;To successfully compile?  &lt;/li&gt;&lt;li&gt;To run without crashing?  &lt;/li&gt;&lt;li&gt;To be well-designed?  &lt;/li&gt;&lt;li&gt;To be easily maintainable?&lt;/li&gt;&lt;li&gt;To please users?  &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All these could be used as criteria for "working", given a particular context.  &lt;/p&gt;&lt;p&gt;&lt;em&gt;In my mind, ultimately the most important question to ask in applying this maxim is, "how do I define 'work'?"&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-8635827973390351292?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/8635827973390351292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=8635827973390351292' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/8635827973390351292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/8635827973390351292'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2008/07/simplest-thing-that-could-possibly.html' title='&quot;The Simplest Thing that Could Possibly Work&quot;...or not'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332267113132659131.post-2756621367414789338</id><published>2008-07-16T22:36:00.000-07:00</published><updated>2008-07-16T22:43:58.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Thoughts</title><content type='html'>I've been diving into Groovy lately...I just started a new job a few weeks ago at McAfee, and most of our application is written in Java.  As a dynamic-language lover, it chaps me to think of spending all my time writing tests in Java.  Writing tests (in this case, white-box tests aimed at business logic level functionality) has always seemed to me to be ideally suited to scripting languages.&lt;br /&gt;&lt;br /&gt;I've looked at Jython and JRuby, and, as much as I love both those languages, it would seem to me that I want to leverage the Java knowledge as much as possible that exists here.  Hence, I'm looking at Groovy.  I'm reading Venkat Subramaniam's "Programming Groovy", and love the language so far.  It seems to bring much of the dynamic language features (dynamic typing, optional semicolons, closures, automatically importing a bunch of Java classes) that I'm looking for.  And it's a much easier sell to a Java shop than trying to get them to bite on a language (such as Java or Ruby) that's a total departure from what they have invested in.&lt;br /&gt;&lt;br /&gt;It would seem we are exactly the type of Java users Groovy is aimed at.  I'll blog more on my thoughts of Groovy (and I'll write a review of Venkat's book) in future posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332267113132659131-2756621367414789338?l=jimknowlton.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jimknowlton.blogspot.com/feeds/2756621367414789338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332267113132659131&amp;postID=2756621367414789338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2756621367414789338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332267113132659131/posts/default/2756621367414789338'/><link rel='alternate' type='text/html' href='http://jimknowlton.blogspot.com/2008/07/groovy-thoughts.html' title='Groovy Thoughts'/><author><name>Jim Knowlton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/_0_2kCh0mg9Q/SacSDRkiGAI/AAAAAAAAAMw/5XxrRhy65zg/S220/jim.jpg'/></author><thr:total>0</thr:total></entry></feed>
