<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The Testing Blog &#187; Marisa Seal</title>
	<atom:link href="http://thetestingblog.com/author/marrrisa/feed/" rel="self" type="application/rss+xml" />
	<link>http://thetestingblog.com</link>
	<description>Why, testing, of course!</description>
	<lastBuildDate>Tue, 31 Aug 2010 23:16:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='thetestingblog.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5bc883277a9e573ad056d2ccd360a439?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Testing Blog &#187; Marisa Seal</title>
		<link>http://thetestingblog.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://thetestingblog.com/osd.xml" title="The Testing Blog" />
	<atom:link rel='hub' href='http://thetestingblog.com/?pushpress=hub'/>
		<item>
		<title>What I Learned by Contributing to FitNesse</title>
		<link>http://thetestingblog.com/2010/01/04/contributing-to-fitnesse/</link>
		<comments>http://thetestingblog.com/2010/01/04/contributing-to-fitnesse/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 07:52:17 +0000</pubDate>
		<dc:creator>Marisa Seal</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[testing tools]]></category>
		<category><![CDATA[fitnesse]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://thetestingblog.com/?p=353</guid>
		<description><![CDATA[by Marisa Seal As of today, I am officially a contributor to FitNesse. I contributed a new feature idea and its implementation (the initial idea was borrowed from FitLibrary&#8217;s SequenceFixture but morphed a bit based on suggestions from Bob Martin), and also worked on Slim version detection. I am not a developer by training nor [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=353&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://thetestingblog.com/author/marrrisa/" target="_blank">Marisa Seal</a></p>
<p>As of today, I am officially a <a href="http://fitnesse.org/.FrontPage.FitNesseDevelopment.FitNesseRelease20100103" target="_blank">contributor to FitNesse</a>. I contributed a <a href="http://fitnesse.org/FitNesse.SuiteAcceptanceTests.SuiteSlimTests.TestSequentialArgumentProcessing" target="_blank">new feature</a> idea and its implementation (the initial idea was borrowed from FitLibrary&#8217;s <a href="http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.FitLibraryFixtures.SequenceFixture" target="_blank">SequenceFixture</a> but morphed a bit based on suggestions from Bob Martin), and also worked on Slim version detection. I am not a developer by training nor trade, but armed with basic coding skills and fueled by the guidance and what I can only describe as the graciousness of Uncle Bob, I was successful. The experience was trying, exciting, and actually pretty fun. While I learned an awful lot more than I&#8217;m going to detail here, I think I had three really important realizations while working on the updates.</p>
<h3>TDD Works!</h3>
<p>Given that I am a tester, I have read/learned about, discussed, and even advocated TDD. Given that I do not (usually) write production code, I had never actually tried it. I decided I&#8217;d give it a go since I needed to write unit tests for my updates anyway.</p>
<p>The existing unit tests for the class I updated served as my guide. I wrote a test to verify the simplest case of the new feature. I ran it &#8211; here&#8217;s the interesting thing: it passed. This surprised me, but also informed me that I <em>did not need to make any changes</em> to the code for the simplest case. The update involved implementing a special character to invoke a different processing scheme for function calls in Slim Script tables, so I had figured that I&#8217;d at least need to update the code to ignore the special character in the simplest case&#8230;but as the unit test proved, I did not.</p>
<p>I wrote a second unit test to verify another simple (yet different) case &#8211; this one failed as expected. I added code to the class in question, ran the test, and saw it fail again. But aha &#8211; I also saw <em>why</em> it failed, and that information helped me find my mistake. At this point I&#8217;d like to say that I made the fix, ran the test, and saw it pass &#8211; but it didn&#8217;t happen that way. I went through a few iterations of running the test and fixing my code.</p>
<p>The test finally passed, and I ran the entire suite of tests for the class. They all passed. The most appropriate word I can find to describe that moment is <em>epiphanic</em>. It was then that I truly understood and appreciated two of the benefits of TDD I have often heard:</p>
<ol>
<li>Practicing TDD can help ensure that only necessary code is implemented, since the goal of writing/updating the code is to make one test pass. Remember, I didn&#8217;t even need to write any code to make the first test pass.</li>
<li>Having a suite of unit tests &#8211; a byproduct of practicing TDD &#8211; can provide confidence that updates have not unintentionally changed existing behavior. The bonus is that unit tests are <strong>fast</strong>, so the feedback can be almost instantaneous. For example, the entire suite of 208 unit tests for the class I updated runs in under 1.5 seconds on my machine.</li>
</ol>
<p>Having an understanding of a practice is one thing; having experience implementing the practice is another. Upon reflection, I now find it odd that I could have advocated TDD without having tried it myself.</p>
<h3>Refactoring is more than just &#8220;Changing&#8221;</h3>
<p>I&#8217;m a bit embarrassed to admit this, but up until recently, I used the word &#8220;refactoring&#8221; as a substitute for &#8220;changing,&#8221; since I thought that&#8217;s what refactoring meant. I thought it was just a dev-ified word for &#8220;changing&#8221; or &#8220;improving.&#8221;</p>
<p>Once I submitted the first update to Bob Martin, I asked him for feedback. I was quite proud that the new feature took only about a dozen new and updated lines of code, but I wondered what I could have done better. Uncle Bob told me that since I had added a couple lines of code to an existing function, the function&#8217;s length was getting to the point where he&#8217;d want to extract some of the functionality &#8211; he suggested extracting a particular loop to a &#8220;method object.&#8221; I immediately Googled &#8220;extract to method object&#8221; and found information about it on <a href="http://www.refactoring.com/index.html" target="_blank">refactoring.com</a>. I quickly realized that refactoring actually encompasses specific techniques that address specific scenarios &#8211; refactoring is not just changing code.</p>
<p>I&#8217;m not as embarrassed to admit that I really had no clue how to execute &#8220;extract to method object.&#8221; I ruminated about it for a few days, and finally just told Uncle Bob that I didn&#8217;t know how to get started. He sent me the code, explained step-by-step how he got to the end result, but still allowed me to commit the change myself&#8230;which leads me to my last point.</p>
<h3>I think I know one reason why he&#8217;s called &#8220;Uncle&#8221; Bob</h3>
<p>There were many times throughout the last few weeks that I wondered when Uncle Bob would say to me &#8220;I&#8217;ll just do it myself &#8211; it&#8217;ll be faster that way.&#8221; That certainly would have been a true statement. Being that I am not &#8211; as I stated before &#8211; a developer by training or trade, I was surprised that he even supported the idea of me actually committing code changes when I first contacted him to suggest the new feature. It turns out that my fear and surprise were completely unfounded. Uncle Bob continually offered guidance and encouragement, and always ended his messages with &#8220;Let me know if you need any help.&#8221; Here&#8217;s the kicker: he meant it, too.</p>
<p>I really did feel like I was the lucky recipient of mentoring by a person who has literally &#8220;written the book&#8221; (multiple books, actually) about software craftsmanship.</p>
<p>I hope that some FitNesse users find the new feature valuable, and that I will be able to contribute to FitNesse again in the future. It was a great experience.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thetestingblog.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thetestingblog.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thetestingblog.wordpress.com/353/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=353&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thetestingblog.com/2010/01/04/contributing-to-fitnesse/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f5524b69490657d7297e7dc63c8cad62?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">marrrisa</media:title>
		</media:content>
	</item>
		<item>
		<title>First Day Follies</title>
		<link>http://thetestingblog.com/2009/11/17/first-day-follies/</link>
		<comments>http://thetestingblog.com/2009/11/17/first-day-follies/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 14:28:11 +0000</pubDate>
		<dc:creator>Marisa Seal</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://thetestingblog.com/?p=327</guid>
		<description><![CDATA[Ah, the first day of a new job&#8230;you&#8217;re in a smart new outfit, ready to conquer whatever is put on your plate. There are the cursory introductions, paperwork, and &#8212; for me &#8212; some kind of laughable gaffe. About 2 years ago, I realized that I had established a pattern of either making a fool [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=327&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ah, the first day of a new job&#8230;you&#8217;re in a smart new outfit, ready to conquer whatever is put on your plate. There are the cursory introductions, paperwork, and &#8212; for me &#8212; some kind of laughable gaffe. About 2 years ago, I realized that I had established a pattern of either making a fool of myself or doing something &#8220;bad&#8221; my first day.</p>
<h3>Aromas</h3>
<p>It actually starts with the very first job I ever held &#8211; a barista position at the <a href="http://www.sandiego.edu/dining/aromas.php" target="_blank">Aromas coffeehouse on the USD campus</a>. My aunt, who worked at the university, told me about the coffeehouse and put me in contact with the manager. I interviewed over the phone, was hired, and found out when to report for my first day on the job. Of course, I called my aunt and thanked her for the introduction. Realizing I had not asked what it is I should wear my first day, I asked my aunt. &#8220;Oh, why don&#8217;t you wear a nice dress?&#8221; she replied.</p>
<p>I showed up to work in a lovely frock, and the very kind manager complimented me on my dress. The sarcastic assistant manager, however, pulled a &#8220;get a load of this gal&#8221; move with the thumb-pointing and everything. I wasn&#8217;t able to train that day because people learning to use an espresso machine ought not to wear short dresses and risk spilling 200-degree espresso on themselves.</p>
<p><strong>Lesson Learned: Ask about dress code if unsure</strong></p>
<h3>First Testing Job</h3>
<p>Fast forward 4 years &#8211; I was an eager young woman fresh out of college, ready to start making some dough to pay off my student loan. I got my first full-time job at <a href="http://www.pacificlife.com/" target="_blank">Pacific Life Insurance Company</a> as a QA Analyst. After the introductions throughout the cube farm, my boss sat down with me in my cubicle and handed me a CD so that I could install the product I&#8217;d be testing. I took the CD and just sort of stared at my computer for a few seconds&#8230;I extended my hand out to the thingy under the monitor that had a lot of buttons on it but could not figure out how to open the dang CD drive. My boss said very slowly &#8220;Um&#8230;the CPU is under your desk.&#8221; Forehead smack! I wonder if my boss freaked out just a tiny bit in that moment after realizing that the person he hired to be a tester couldn&#8217;t &#8220;work the computer.&#8221; Now, of course I <em>could </em>work the computer&#8230;thanks to my grandpa, I&#8217;d been using one since I was about 7&#8230;I was just really nervous!</p>
<p><strong>Lesson Learned: Sometimes you just gotta laugh at yourself</strong></p>
<h3>First Agile Testing Job</h3>
<p>OK, fast forward another few years. I had over 6 years of software testing experience under my belt and was interviewing for a tester position at <a href="http://www.edfinancial.com/" target="_blank">Edfinancial Services</a>. My potential future boss asked me for my thoughts on bug documentation. I said very confidently, &#8220;I document EVERYTHING.&#8221;  The rest of the interview went well, and I got the job.</p>
<p>My first day, my new boss sat down with me for a discussion about testing in an agile environment. We got to talking about bug tracking and he said, &#8220;I think tracking bugs found during the sprint is a big waste of time.&#8221; My mind immediately zipped back to my proud statement about documenting EVERYTHING. Oops&#8230;</p>
<p><strong>Lesson Learned: Be prepared to change the way you&#8217;ve &#8220;always&#8221; done things!</strong></p>
<h3>My New Job</h3>
<p>And now we&#8217;re pretty much all caught up&#8230;well, wait a second &#8211; I did start a new job <em>yesterday</em>. I&#8217;m now a software tester for a small group, and I am stoked to be working with <a href="http://chrismcmahonsblog.blogspot.com/" target="_blank">Chris McMahon</a> in this gig. Anyway, Chris and I were going through tutorials about the online app we&#8217;ll be testing. One of the tutorials provided a link to a &#8220;sample&#8221; workspace. I started playing around in the sample workspace and had some questions&#8230;I posted my questions on the wiki. Chris, our trainer Marcus (he&#8217;s a project manager/developer), and I started chatting about the sample space and Marcus asked me for the URL of the sample space. I barely got the sub-domain out of my mouth and Marcus exclaimed &#8220;That&#8217;s production!&#8221;</p>
<p>Turns out that the tutorials need to be updated. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Lesson Learned*: Some day, you WILL accidentally do something on production</strong></p>
<p>*Actually, this was a reminder for me &#8211; I&#8217;ve already learned the lesson about messing around with production&#8230;brought a DB server completely down unknowingly once.</p>
<p>Well, there we have it. The pattern was not broken. The good news is that I really, really like the group of people I&#8217;m working with now, and hopefully won&#8217;t have to experience another first day on the job for a long while.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thetestingblog.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thetestingblog.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thetestingblog.wordpress.com/327/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=327&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thetestingblog.com/2009/11/17/first-day-follies/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f5524b69490657d7297e7dc63c8cad62?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">marrrisa</media:title>
		</media:content>
	</item>
		<item>
		<title>Wrapping my mind around Slim Query Tables</title>
		<link>http://thetestingblog.com/2009/09/18/slim-query-tables/</link>
		<comments>http://thetestingblog.com/2009/09/18/slim-query-tables/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 19:00:13 +0000</pubDate>
		<dc:creator>Marisa Seal</dc:creator>
				<category><![CDATA[test automation]]></category>

		<guid isPermaLink="false">http://thetestingblog.com/?p=222</guid>
		<description><![CDATA[I started using the Slim test framework (the .NET implementation) about two weeks ago, but had worked primarily with scenario, script , and decision tables up until yesterday. (Scenario tables ROCK btw and I will blog about them soon). Yesterday I started working on an automated test (or, if you prefer, collection of checks) that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=222&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I started using the <a href="http://fitnesse.org/FitNesse.UserGuide.SliM" target="_blank">Slim test framework</a> (the <a href="http://www.syterra.com/Slim.html" target="_blank">.NET implementation</a>) about two weeks ago, but had worked primarily with scenario, script , and decision tables up until yesterday. (Scenario tables ROCK btw and I will blog about them soon).</p>
<p>Yesterday I started working on an automated test (or, if you prefer, collection of checks) that needed to verify data in a result set, so I started learning about the <a href="http://fitnesse.org/FitNesse.UserGuide.SliM.QueryTable" target="_blank">Slim Query table</a>. The query table example and corresponding fixture code presented in the FitNesse user guide are fairly straightforward. The part that I really had to wrap my head around was the statement &#8220;The fixture class must have a <em>query</em> method that returns a list of rows.  Each row is a list of fields.  Each field is a two-element list composed of the <em>field name</em> and its string value.&#8221; Say whaaat?</p>
<p>Now, maybe for those of you who have more of a programming background than I do, you might have read that statement and immediately pictured what the Query results &#8220;look&#8221; like. I didn&#8217;t. I&#8217;m used to thinking of query results as a table, not as lists of lists. I had to create a visual.</p>
<p>Given this result set:</p>
<p><img class="alignnone size-full wp-image-225" title="SampleTable" src="http://thetestingblog.files.wordpress.com/2009/09/sampletable.png?w=291&#038;h=91" alt="SampleTable" width="291" height="91" /></p>
<p>Starting at the lowest level, we have &#8220;Each field is a two-element list comprised of the field name and its string value.&#8221; OK, so for row 0 column 0 we&#8217;d have:</p>
<p><img class="alignnone size-full wp-image-241" title="row0Col0" src="http://thetestingblog.files.wordpress.com/2009/09/row0col02.png?w=224&#038;h=34" alt="row0Col0" width="224" height="34" /></p>
<p>For row 0 column 1 we&#8217;d have:</p>
<p><img class="alignnone size-full wp-image-242" title="row0Col1" src="http://thetestingblog.files.wordpress.com/2009/09/row0col12.png?w=201&#038;h=38" alt="row0Col1" width="201" height="38" /></p>
<p>etc.</p>
<p>Let&#8217;s go up a level. &#8220;Each row is a list of fields.&#8221; That makes sense now. For row 0 we&#8217;d have:</p>
<p><img class="alignnone size-full wp-image-239" title="row0List" src="http://thetestingblog.files.wordpress.com/2009/09/row0list.png?w=693&#038;h=37" alt="row0List" width="693" height="37" /></p>
<p>Finally, the Query method &#8220;returns a list of rows.&#8221; Ohhh now it makes sense.</p>
<p><img class="alignnone size-full wp-image-243" title="listOfRowsOfColValPairs" src="http://thetestingblog.files.wordpress.com/2009/09/listofrowsofcolvalpairs.png?w=772&#038;h=198" alt="listOfRowsOfColValPairs" width="772" height="198" /></p>
<p>Hmm&#8230;but then I had to figure out how to translate a DataTable result set into the list of this format. It was actually pretty simple; iterate through the rows and columns to create what I call column-value pairs, collect each row&#8217;s column-value pairs into a list, then collect the rows into a list.</p>
<p>I&#8217;ve provided my solution below (sorry about the formatting &#8211; this theme&#8217;s code tag sucks).</p>
<p>It&#8217;s a method that takes a DataTable and creates the <em>list of lists of column-value pairs</em> that will work with Slim Query tables. So, in each Slim Query Fixture class, I just call off to the method and pass in the DataTable of results, then return the <em>list of lists of column-value pairs</em> from the Query() method.</p>
<p><code><br />
using System;<br />
using System.Collections.Generic;<br />
using System.Data;<br />
using System.Text;<br />
</code></p>
<p><code>namespace Your.Namespace.Here<br />
{<br />
public static class SlimQueryResultsHelper<br />
{<br />
// Convert a result set in DataTable format to the format required by the Slim Query test table<br />
public static List ConvertDataTableToObjectList(DataTable theTable)<br />
{<br />
List queryResults = new List();<br />
foreach (DataRow row in theTable.Rows)<br />
{<br />
List rowListOfColumnValuePairs = new List();<br />
</code><code>foreach (DataColumn col in theTable.Columns)<br />
{<br />
List columnValuePair = new List();<br />
object val = row[col];<br />
columnValuePair.Add(col.ColumnName);<br />
columnValuePair.Add(val == DBNull.Value ? "null" : val);<br />
rowListOfColumnValuePairs.Add(columnValuePair);<br />
}<br />
queryResults.Add(rowListOfColumnValuePairs);<br />
}<br />
return queryResults;<br />
}<br />
}<br />
}<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thetestingblog.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thetestingblog.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thetestingblog.wordpress.com/222/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=222&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thetestingblog.com/2009/09/18/slim-query-tables/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f5524b69490657d7297e7dc63c8cad62?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">marrrisa</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/09/sampletable.png" medium="image">
			<media:title type="html">SampleTable</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/09/row0col02.png" medium="image">
			<media:title type="html">row0Col0</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/09/row0col12.png" medium="image">
			<media:title type="html">row0Col1</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/09/row0list.png" medium="image">
			<media:title type="html">row0List</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/09/listofrowsofcolvalpairs.png" medium="image">
			<media:title type="html">listOfRowsOfColValPairs</media:title>
		</media:content>
	</item>
		<item>
		<title>Grid Interaction in Selenium Tests with XPath</title>
		<link>http://thetestingblog.com/2009/08/27/selenium-xpath/</link>
		<comments>http://thetestingblog.com/2009/08/27/selenium-xpath/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 07:47:50 +0000</pubDate>
		<dc:creator>Marisa Seal</dc:creator>
				<category><![CDATA[test automation]]></category>

		<guid isPermaLink="false">http://thetestingblog.com/?p=151</guid>
		<description><![CDATA[Even though I have been using SeleniumRC for a few years now, I never actually had the need to write xpath expressions. I knew that xpath was one option for locating UI controls in Selenium, but I was always able to use control IDs, names, or text&#8230;until recently. I&#8217;m working on automating tests for a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=151&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Even though I have been using <a href="http://seleniumhq.org/projects/remote-control/" target="_blank">SeleniumRC</a> for a few years now, I never actually had the need to write xpath expressions. I knew that xpath was one option for locating UI controls in Selenium, but I was always able to use control IDs, names, or text&#8230;until recently.</p>
<p>I&#8217;m working on automating tests for a web app that has a lot settings configuration features, and many settings are managed in the UI via interactive grid controls. As the details of this app are proprietary, I will of course use a fake example. Since I&#8217;m on a Beatles kick, let&#8217;s <em>imagine</em> (har  har sorry for the bad pun and yes I know that was Lennon solo) I&#8217;m testing an album ranking control that looks like this:</p>
<p><img class="alignnone size-full wp-image-162" title="SampleGrid" src="http://thetestingblog.files.wordpress.com/2009/08/samplegrid2.png?w=426&#038;h=203" alt="SampleGrid" width="426" height="203" /></p>
<p>If I record my interactions with the grid using Selenium IDE, the output is something like this:</p>
<p><img class="alignnone size-full wp-image-164" title="GridInteraction" src="http://thetestingblog.files.wordpress.com/2009/08/gridinteraction2.png?w=472&#038;h=68" alt="GridInteraction" width="472" height="68" /></p>
<p>Notice anything? I notice a couple things.</p>
<ol>
<li>Aside from the fact that I see &#8220;grdBeatlesAlbums&#8221; in the locator string, there is no context to the rest of it &#8211; &#8220;//tr[4]&#8221; doesn&#8217;t appear to correspond to <span style="text-decoration:underline;">Abbey Road</span> which was the album I was moving up in the ranks.</li>
<li>Yikes &#8211; am I really going to have to figure out the table row number for the album I want to act on in every test involving this grid?</li>
</ol>
<p>My first inclination was to write a method that would determine the row position of an album with a given name. Then I realized that would involve parsing HTML. Yuck. I thought to myself, there <em>has</em> to be an easier way.  I went back to the Selenium docs to read about control location strategies a little more closely and saw that xpath would probably do the trick.  As so succinctly put on <a href="http://www.w3schools.com/xpath/default.asp" target="_blank">w3school&#8217;s page</a>, &#8220;XPath is used to navigate through elements and attributes in an XML document.&#8221;</p>
<p>Now my problem was figuring out how to write an xpath expression that would locate a control in a column &#8220;next to&#8221; a given album name.</p>
<p>I wrote an almost-plain-English sentence to describe what I needed.</p>
<p>Version 1: Locate the &#8220;Move Up&#8221; link in the column <em>adjacent to</em> &#8220;Abbey Road.&#8221;</p>
<p>I thought &#8220;adjacent&#8221; would be a difficult concept but after Googling for a bit, I found information about the <em>following </em>and <em>preceding </em><a href="http://www.w3schools.com/xpath/xpath_axes.asp" target="_blank">xpath axes</a>.</p>
<p>Version 2: Locate the &#8220;Move Up&#8221; link <em>following </em>the cell containing the string &#8220;Abbey Road.&#8221;</p>
<p>OK, so now to translate this to xpath &#8211; the Move Up link is just an HTML link, a.k.a. an &#8220;a&#8221; element.</p>
<p><strong>a[.='Move Up']</strong> translates to: <em>a</em> element whose inner text exactly matches &#8216;<em>Move Up</em>&#8216;</p>
<p>And the cell containing &#8220;Abbey Road&#8221; &#8211; well, that&#8217;s just a table cell, or &#8220;td&#8221; element.</p>
<p><strong>td[.='Abbey Road']</strong> translates to: <em>td </em>element whose inner text exactly matches &#8216;<em>Abbey Road</em>&#8216;</p>
<p>Next step: relate the two.</p>
<p><strong>td[.='Abbey Road']/following::a[.='Move Up']</strong> translates to: <em>a</em> element whose inner text exactly matches &#8216;<em>Move Up</em>&#8216;, which follows a <em>td </em>element whose inner text exactly matches &#8216;<em>Abbey Road</em>&#8216;</p>
<p>We just need one more thing: since the td element is not the first element on the page, we need to prepend the statement with // to indicate that the entire document (page source) should be searched to find the element.</p>
<p><strong><strong>//</strong>td[.='Abbey Road']/following::a[.='Move Up']</strong></p>
<p>Even though the end result isn&#8217;t exactly plain English, it&#8217;s a lot more clear to me than &#8220;/tr[3]/td[4]/a&#8221; which is what the IDE recorded. It could also be reusable, providing the album name is passed via a variable instead of hard-coded.</p>
<p>Using xpath, you can also locate elements whose attributes (e.g. id or name) match certain criteria, and there are some handy functions like contains() to help in situations where a control&#8217;s full id or name is not known beforehand.</p>
<p>I&#8217;d still prefer the convenience of using control IDs, but there are just some situations where that either not possible or practical &#8211; xpath is now my fallback for tricky UI.</p>
<p><em><strong>Update 8/28/09 </strong></em></p>
<p>Since I didn’t include this originally, the way to write an expression to find an element based on attribute values is</p>
<p><strong>elementtype[@attributename='attribute value'] </strong></p>
<p>e.g. //table[@id='someTableID']</p>
<p>An example with contains():</p>
<p><strong>elementtype[contains(@attributename, 'attribute substring')]</strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thetestingblog.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thetestingblog.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thetestingblog.wordpress.com/151/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=151&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thetestingblog.com/2009/08/27/selenium-xpath/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f5524b69490657d7297e7dc63c8cad62?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">marrrisa</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/08/samplegrid2.png" medium="image">
			<media:title type="html">SampleGrid</media:title>
		</media:content>

		<media:content url="http://thetestingblog.files.wordpress.com/2009/08/gridinteraction2.png" medium="image">
			<media:title type="html">GridInteraction</media:title>
		</media:content>
	</item>
		<item>
		<title>Here it is. My first post. (a.k.a. Why automate sub-UI?)</title>
		<link>http://thetestingblog.com/2009/08/14/marisa-first-post/</link>
		<comments>http://thetestingblog.com/2009/08/14/marisa-first-post/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 05:21:21 +0000</pubDate>
		<dc:creator>Marisa Seal</dc:creator>
				<category><![CDATA[test automation]]></category>

		<guid isPermaLink="false">http://thetestingblog.com/?p=8</guid>
		<description><![CDATA[...all was going well until I said something (I thought to be) pretty benign - something along the lines of "Well, I'm hoping that the architecture of the app is such that most of these test actions and verifications can be performed sub-UI."

I heard brakes screech...

...Well, why DO we want to automate tests primarily at the sub-UI level?<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=8&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As someone who has extremely high standards for oneself, I have majorly procrastinated in writing my first post here on <a href="http://thetestingblog.com">thetestingblog.com</a>. Tonight I&#8217;ve decided to go ahead and do it already. If the information is not earth-shattering; if my wit and humor do not make you literally laugh out loud; if (gasp!) you do not agree with me &#8211; that&#8217;s OK. I have come to terms with that.</p>
<p>Now on to the real topic&#8230;I&#8217;ve been working with a software development team to guide them in their implementation of agile and automated testing techniques for about a month now. At the first sprint demo (yes &#8211; the team practices <a href="http://en.wikipedia.org/wiki/Scrum_%28development%29" target="_blank">Scrum</a>), I wanted to show the team a couple of examples of simple automated tests I had created for one of their applications. I demonstrated a GUI-driven test and a sub-GUI test. The demo went off without a hitch and the team seemed eager to start automating their tests in these manners.</p>
<p>The next day, I was to conduct a more detailed meeting with the testers regarding my suggestions for implementing automated tests to cover a particular application. Again, all was going well until I said something (I thought to be) pretty benign &#8211; something along the lines of &#8220;Well, I&#8217;m hoping that the architecture of the app is such that most of these test actions and verifications can be performed sub-UI.&#8221;</p>
<p>I heard brakes screech.</p>
<p>All of a sudden, a debate ensued about how driving the application some other way than through the UI was not a &#8220;real&#8221; acceptance test (after all, &#8220;real&#8221; users have no choice but to use the application via the UI). I stumbled and fumbled to explain; I was so used to automating 90% of a test suite at the sub-UI level that I actually had to stop and ask myself the question: &#8220;Well, why DO we want to automate test actions and verifications primarily at the sub-UI level?&#8221;</p>
<p>Here are my primary reasons:</p>
<ul>
<li>A verification being performed on the UI may not actually be verifying what the tester intended to verify.
<p>For example, if I want to verify that a folder monitoring process has swept a test file and read the data from the file correctly, verifying that the file name appears in a &#8220;Processed OK&#8221; list on a screen <strong>only tells me that the file name is appearing in that list</strong> &#8211; NOT that the file was processed correctly (whatever &#8220;correctly&#8221; means with respect to the AUT).</p>
<p>Ask yourself the question &#8220;How can I confirm that X action produced Y results?&#8221;</li>
<li>Verification that information and data are presented correctly in the UI <strong>doesn&#8217;t mean the data stored in the database is correct!</strong>
<p>I actually once found a bug where the UI populated the Last Name text box correctly, but this was because both the insert and retrieve stored procedures were referencing the Middle Name column. In other words, the Last Name data was being stored in and retrieved from the Middle Name column, so it &#8220;looked like&#8221; the Last Name data was being saved and retrieved correctly.</p>
<p>Ask yourself the question &#8220;Where are all of the &#8216;outputs&#8217; of action X?&#8221;</li>
<li>(Hopefully) it is not the UI&#8217;s job to &#8220;do&#8221; most of the application processing, but rather to transfer information to and fro the business logic layer.</li>
<p>Ask yourself the question: &#8220;Am I testing the code that&#8217;s actually responsible for action X?&#8221;</ul>
<p>There are other reasons commonly posited, such as:</p>
<ul>
<li>The UI is fragile and therefore UI tests are more likely to break</li>
<li>UI tests are much slower than sub-UI tests (and if we have a lot of slow tests, we&#8217;re less likely to want to run them)</li>
<li>If we have to automate a test via the UI, we have to wait until the UI is done, and typically the UI is the last component to be completed (even within a sprint/iteration)</li>
</ul>
<p>Do I still automate UI tests? Yes, but typically only to confirm that UI behavior is as expected &#8211; e.g. buttons are enabled/disabled given certain circumstances, fields or data are hidden for certain users, etc. I also automate 1 or 2 &#8220;all the way through&#8221; tests &#8211; from UI to backend &#8211; but leave detailed business logic tests for the sub-UI suite.</p>
<p>Those are most of the reasons why I typically prefer to automate most integration/acceptance tests at the sub-UI level &#8211; but don&#8217;t take my word for it &#8211; the Google Testing blog has a <a href="http://googletesting.blogspot.com/2007/10/automating-tests-vs-test-automation.html" target="_blank">thorough and interesting post</a> on this same topic.</p>
<p>There we have it. My first blog post. Ever. Please, respond to the poll if appropriate and comment as you wish (unless you disagree with me). Just kidding of course. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<a name="pd_a_1874268"></a><div class="PDS_Poll" id="PDI_container1874268" style="display:inline-block;"></div><script type="text/javascript" language="javascript" charset="utf-8" src="http://static.polldaddy.com/p/1874268.js"></script>
		<noscript>
		<a href="http://answers.polldaddy.com/poll/1874268/">View This Poll</a><br/><span style="font-size:10px;"><a href="http://polldaddy.com/features-surveys/">survey software</a></span>
		</noscript>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thetestingblog.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thetestingblog.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thetestingblog.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thetestingblog.com&amp;blog=8467555&amp;post=8&amp;subd=thetestingblog&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thetestingblog.com/2009/08/14/marisa-first-post/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f5524b69490657d7297e7dc63c8cad62?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">marrrisa</media:title>
		</media:content>
	</item>
	</channel>
</rss>