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

<channel>
	<title>Google Data &#187; dastels</title>
	<atom:link href="/author/dastels/feed/" rel="self" type="application/rss+xml" />
	<link>https://googledata.org</link>
	<description>Everything Google: News, Products, Services, Content, Culture</description>
	<lastBuildDate>Wed, 18 Mar 2015 21:09:38 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.7.5</generator>
	<item>
		<title>Fast exploratory tests with IFrames</title>
		<link>https://googledata.org/google-testing/fast-exploratory-tests-with-iframes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fast-exploratory-tests-with-iframes</link>
		<comments>https://googledata.org/google-testing/fast-exploratory-tests-with-iframes/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 17:49:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[by Håvard Rast BlokWhile working with a search quality development team, I was asked to collect information from their result pages across all the supported languages. The aim was to quickly get an overview, and then manually look through them for irr...]]></description>
				<content:encoded><![CDATA[<b>by Håvard Rast Blok</b><br /><br /><p>While working with a search quality development team, I was asked to collect information from their result pages across all the supported languages. The aim was to quickly get an overview, and then manually look through them for irregularities. One option would have been to grab the pages using tools like Selenium or WebDriver. However, this would have been complex and expensive. Instead, I opted for a much simpler solution: Display each language variation in a separate IFrame within the same HTML page.</p><br /><br /><p>An example of how this looks, <a href="http://code.google.com/testing/iframe_example.html">can be seen here</a>, where the Google Search page is shown in 43 different languages. There are also some links for other Google sites, or you can type in your own link, and the query attribute for language, <i>"hl="</i>, will be appended at the end.</p><br /><br /><p>(Warning: Do not try this with YouTube, as 43 Flash windows on the same pages will crash your browser. Also, Firefox 2 is known to be slow, while Firefox 3 works fine.)</p><br /><br /><h3>The JavaScript Code</h3><br /><br /><p>Creating the IFrames is easy using JavaScript, as can be seen in the example below. I assume that the array of languages to iterate over is retrieved by the function <i>getLanguages()</i>. Then a simple loop uses <i>document.write(...)</i> to dynamically add the IFrames. It is worth mentioning that this method seemed to be the best way of dynamically creating them; using the <i>document.createElement(...)</i> resulted in some complex race condition issues when adding the IFrames and their content at the same time.</p><br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">var languages = getLanguages();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">for (var lang, i = 0; lang = languages[i]; i++) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;document.write('&lt;hr&gt;&lt;a name="' + lang + '"/&gt;' +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'&lt;h2&gt;' + lang + '&lt;/h2&gt;&lt;center&gt;' +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'<b>&lt;iframe src="' + url + lang</b> +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'" width="' + queryMap['width'] +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'" height="' + queryMap['height'] +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'"&gt;&lt;/iframe&gt;' +</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/center&gt;&lt;br/&gt;&lt;br/&gt;');</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br /><p>The rest of the source code, can be seen <a href="http://code.google.com/testing/iframe_example.html">in this example</a>. Nothing else is needed to get the overview.</p><br /><br /><h3>Conclusion</h3><br /><p>The example in this article shows that a very simple and inexpensive solution can be useful for exploratory testing of web pages; especially when quickly looking over the same pages in multiple languages. The small amount of code required, makes it easy to customize for any project or page, and the fact that the requests are done dynamically, gives a view which is always up to date.</p><br /><br /><p>Of course, this type of overview lends itself best to very simple stateless pages, which do not require complex navigation. It would for example be more difficult to get the same list of IFrames for Gmail, or other complex applications. Also, as the IFrames are loaded dynamically, no history is kept, so tracking when a potential bug was introduced in the page under test might prove more tedious.</p><br /><br /><p>Furthermore, it should be noted that the overview only simplifies a manual process of looking at the pages. In some situations, this might be very beneficial, and enough for the developer, while in other projects more automated tests might be designed. E.g., it could be difficult to automate tests for aesthetic issues, but easy to spot them manually, while it may prove more beneficial to automate checks for English terms in other languages.</p><br /><br /><p>Finally, a word on the issue of translations and language skills. The overview in this example, quickly highlights issues like incorrect line wrapping, missing strings, etc. in all variations of the page. Also, it was easy to spot strings not already translated in some of the languages, like Japanese, and in fact I reported a bug against the Search front page for this. However, for other issues, more language specific skills are necessary to spot and file bugs: E.g. should the Arabic page show <a href="http://commons.wikimedia.org/wiki/Image:EgyptphoneKeypad.jpg">Eastern or Western Arabic numerals</a>? And have the Danes picked the English term for "Blogs", while the Norwegians and Swedish prefer a localized term? I don't know.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-3367940811882911721?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/fast-exploratory-tests-with-iframes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Partial Mocks using Forwarding Objects</title>
		<link>https://googledata.org/google-testing/tott-partial-mocks-using-forwarding-objects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-partial-mocks-using-forwarding-objects</link>
		<comments>https://googledata.org/google-testing/tott-partial-mocks-using-forwarding-objects/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 18:44:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[A Partial Mock is a mock that uses some behavior from a real object and some from a mock object. It is useful when you need bits of both. One way to implement this is often a Forwarding Object (or wrapper) which forwards calls to a delegate.For example...]]></description>
				<content:encoded><![CDATA[A <b><span style="color:#800000;"><i>Partial Mock</i></span></b> is a mock that uses <b><span style="color:#800000;">some behavior from a real object</span></b> and <b><span style="color:#800000;">some from a mock object</span></b>. It is useful when you need bits of both. One way to implement this is often a <b><span style="color:#800000;">Forwarding Object</span></b> (or wrapper) which <b><span style="color:#800000;">forwards calls to a delegate</span></b>.<br /><br />For example, when writing an Olympic swimming event for ducks, you could create a simple forwarding object to be used by multiple tests:<br /><br /><p style="BORDER-RIGHT: #808080 1px solid; PADDING-RIGHT: 0.1in; BORDER-TOP: #808080 1px solid; PADDING-LEFT: 0.1in; BACKGROUND: #e6f5ff 0% 50%; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.39in; BORDER-LEFT: #808080 1px solid; MARGIN-RIGHT: 0.39in; PADDING-TOP: 0.1in; BORDER-BOTTOM: #808080 1px solid"><span style="font-family:courier new, monospace;font-size:100%;">interface Duck {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">Point getLocation();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">void quack();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">void swimTo(Point p);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style="font-family:courier new, monospace;font-size:100%;">class ForwardingDuck implements Duck {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">private final Duck d;</span><br /><span style="font-family:courier new, monospace;font-size:100%;">ForwardingDuck(Duck delegate) {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">this.d = delegate;</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">public Point getLocation() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">return d.getLocation();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">public void quack() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">d.quack();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">public void swimTo(Point p) {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">d.swimTo(p);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />And then create a test that uses all of the real <tt><b>OlympicDuck</b></tt> class's behavior except quacking.<br /><br /><p style="BORDER-RIGHT: #808080 1px solid; PADDING-RIGHT: 0.1in; BORDER-TOP: #808080 1px solid; PADDING-LEFT: 0.1in; BACKGROUND: #e6f5ff 0% 50%; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.39in; BORDER-LEFT: #808080 1px solid; MARGIN-RIGHT: 0.39in; PADDING-TOP: 0.1in; BORDER-BOTTOM: #808080 1px solid"><span style="font-family:courier new, monospace;font-size:100%;">public void testDuckCrossesPoolAndQuacks() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">final Duck mock = EasyMock.createStrictMock(Duck.class); </span><br /><span style="font-family:courier new, monospace;font-size:100%;">mock.swimTo(FAR_SIDE);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">mock.quack(); // quack after the race</span><br /><span style="font-family:courier new, monospace;font-size:100%;">EasyMock.replay(mock);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">Duck duck = OlympicDuck.createInstance();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">Duck partialDuck = new ForwardingDuck(duck) { </span><br /><span style="font-family:courier new, monospace;font-size:100%;">@Override public void quack() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">mock.quack();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">@Override public void swimTo(Point p) {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">mock.swimTo(p);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">super.swimTo(p);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><span style="font-family:courier new, monospace;font-size:100%;">// no need to @Override “Point getLocation()”</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style="font-family:courier new, monospace;font-size:100%;">OlympicSwimmingEvent.createEventForDucks()</span><br /><span style="font-family:courier new, monospace;font-size:100%;">.withDistance(ONE_LENGTH)</span><br /><span style="font-family:courier new, monospace;font-size:100%;">.sponsoredBy(QUACKERS_CRACKERS)</span><br /><span style="font-family:courier new, monospace;font-size:100%;">.addParticipant(partialDuck)</span><br /><span style="font-family:courier new, monospace;font-size:100%;">.doRace();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">MatcherAssert.assertThat(duck.getLocation(), is(FAR_SIDE));</span><br /><span style="font-family:courier new, monospace;font-size:100%;">EasyMock.verify(mock);</span><br /><span style="font-family:courier new, monospace;font-size:100%;"></span><br /></p><br /><br /><tt><b>partialDuck</b></tt> is a complex example of a partial mock – it combines real and mock objects in three different ways: <ul><br /><li><tt><b>quack()</b></tt> <b><span style="color:#800000;">calls the mock object</span></b>. It verifies that the duck doesn't promote the sponsor (by quacking) until after the race. (We skip the real quack() method so that our continuous build doesn't drive us crazy.)</li><br /><li><tt><b>getLocation()</b></tt> <b><span style="color:#800000;">calls the real object</span></b>. It allows us to use the OlympicDuck's location logic instead of rewriting/simulating the logic from that implementation.</li><br /><li><tt><b>swimTo(point)</b></tt> <b><span style="color:#800000;">calls both objects</span></b>. It allows us to verify the call to the real duck before executing it.</li><br /></ul><br />There is some debate about whether you should forward to the real or mock Duck by default. If you use the mock duck by default, any new calls to the mock will break the test, making them brittle. If you use the real duck, some very sensitive calls like <tt><b>submitToDrugTest()</b></tt> might get called by your test if your duck happens to win.<br /><br />Consider using a <b><span style="color:#800000;">Partial Mock in tests</span></b> when you need to leverage the implementation of the real object, but want to <b><span style="color:#800000;">limit, simulate or verify method calls</span></b> using the power of a mock object.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2009-02-19.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-4389787452849979676?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-partial-mocks-using-forwarding-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Be an MVP of GUI Testing</title>
		<link>https://googledata.org/google-testing/tott-be-an-mvp-of-gui-testing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-be-an-mvp-of-gui-testing</link>
		<comments>https://googledata.org/google-testing/tott-be-an-mvp-of-gui-testing/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 17:54:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[With all the sport drug scandals of late, it's difficult to find good role models these days. However, when your role model is a Domain Model (object model of the business entities), you don't need to cheat to be an MVP--Use Model-View-Presenter!MVP is...]]></description>
				<content:encoded><![CDATA[With all the sport drug scandals of late, it's difficult to find good role models these days. However, when your role model is a Domain Model (object model of the business entities), you don't need to cheat to be an MVP--Use Model-View-Presenter!<br /><br />MVP is very similar to MVC (Model-View-Controller). <b><span style="color:#800000;">In MVC, the presentation logic is shared by Controller and View</span></b>, as shown in the diagram below. The View is usually derived directly from visible GUI framework component, observing the Model and presenting it visually to the user. The Controller is responsible for deciding how to translate user events into Model changes. <b><span style="color:#800000;">In MVP, presentation logic is taken over entirely by a Supervising Controller, also known as a Presenter</span></b>.<br /><br /><p align="center">MVC</p><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lUDLhPj-dyg/SYsof7ALGrI/AAAAAAAAABs/et_TtfwT8fE/s1600-h/mvc.png"><img id="BLOGGER_PHOTO_ID_5299373915410995890" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 277px; CURSOR: hand; HEIGHT: 161px; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_lUDLhPj-dyg/SYsof7ALGrI/AAAAAAAAABs/et_TtfwT8fE/s400/mvc.png" border="0" /></a><br /><br /><p align="center">MVP</p><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lUDLhPj-dyg/SYsogEymUWI/AAAAAAAAAB0/CSSLkHiRTMo/s1600-h/mvp.png"><img id="BLOGGER_PHOTO_ID_5299373918038413666" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 312px; CURSOR: hand; HEIGHT: 214px; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_lUDLhPj-dyg/SYsogEymUWI/AAAAAAAAAB0/CSSLkHiRTMo/s400/mvp.png" border="0" /></a><br /><br />The View becomes passive, delegating to the Presenter.<br /><br /><p style="BORDER-RIGHT: #808080 1px solid; PADDING-RIGHT: 0.1in; BORDER-TOP: #808080 1px solid; PADDING-LEFT: 0.1in; BACKGROUND: #e6f5ff 0% 50%; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.39in; BORDER-LEFT: #808080 1px solid; MARGIN-RIGHT: 0.39in; PADDING-TOP: 0.1in; BORDER-BOTTOM: #808080 1px solid"><span style="font-family:courier new, monospace;font-size:100%;">public CongressionalHearingView() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  testimonyWidget.addModifyListener(</span><br /><span style="font-family:courier new, monospace;font-size:100%;">    new ModifyListener() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">      public void modifyText(ModifyEvent e) {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">        presenter.onModifyTestimony(); // presenter decides action to take</span><br /><span style="font-family:courier new, monospace;font-size:100%;">      }});</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />The Presenter fetches data from the Model and updates the View.<br /><br /><p style="BORDER-RIGHT: #808080 1px solid; PADDING-RIGHT: 0.1in; BORDER-TOP: #808080 1px solid; PADDING-LEFT: 0.1in; BACKGROUND: #e6f5ff 0% 50%; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.39in; BORDER-LEFT: #808080 1px solid; MARGIN-RIGHT: 0.39in; PADDING-TOP: 0.1in; BORDER-BOTTOM: #808080 1px solid"><span style="font-family:courier new, monospace;font-size:100%;">public class CongressionalHearingPresenter {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  public void onModifyTestimony() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">    model.parseTestimony(view.getTestimonyText()); // manipulate model</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  }</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  public void setWitness(Witness w) {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">    view.setTestimonyText(w.getTestimony()); // update view</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  }</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />This separation of duties allows for <b><span style="color:#800000;">more modular code</span></b>, and also <b><span style="color:#800000;">enables easy unit testing of the Presenter and the View</span></b>.<br /><br /><p style="BORDER-RIGHT: #808080 1px solid; PADDING-RIGHT: 0.1in; BORDER-TOP: #808080 1px solid; PADDING-LEFT: 0.1in; BACKGROUND: #e6f5ff 0% 50%; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.39in; BORDER-LEFT: #808080 1px solid; MARGIN-RIGHT: 0.39in; PADDING-TOP: 0.1in; BORDER-BOTTOM: #808080 1px solid"><span style="font-family:courier new, monospace;font-size:100%;">public void testSetWitness() {</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  spyView = new SpyCongressionalHearingView();</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  presenter = new CongressionalHearingPresenter(spyView);</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  presenter.setWitness(new Witness(“Mark McGwire”, “I didn't do it”));</span><br /><span style="font-family:courier new, monospace;font-size:100%;">  assertEquals( “I didn't do it”, spyView.getTestimonyText());</span><br /><span style="font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />Note that this makes use of a perfectly legal injection -- Dependency Injection.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2009-02-05.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-2901128092268975004?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-be-an-mvp-of-gui-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>TotT: Keep Your Fakes Simple</title>
		<link>https://googledata.org/google-testing/tott-keep-your-fakes-simple/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-keep-your-fakes-simple</link>
		<comments>https://googledata.org/google-testing/tott-keep-your-fakes-simple/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 17:40:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[When scientists in California tried to raise condors in captivity, they ran into a problem.  The chicks wouldn't eat from the researchers' hands; they wanted a mother condor to feed them. So the scientists got a puppet.  To the chicks, it looked like t...]]></description>
				<content:encoded><![CDATA[When scientists in California tried to raise condors in captivity, they ran into a problem.  The chicks wouldn't eat from the researchers' hands; they wanted a mother condor to feed them. So the scientists got a puppet.  To the chicks, it looked like their mother's head was feeding them—but inside was the same scientist's hand.<br /><br />Consider a contrived example based on that:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST_F(BabyCondorTest, EatsCarrion) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;FakeCondor mother;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;scoped_ptr<Carrion> carrion;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;BabyCondor* pchick = &chick_;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;mother.Imprint(vector<BabyCondor*>(&pchick, &pchick + 1));  // just one chick</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;while(!chick_.HasFood()) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;mother.Eat();  // disposes of any food the mother kept for herself</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;mother.Scavenge(carrion.reset(new FakeCarrion));  // finds new food</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;mother.RandomlyDistributeFoodAmongYoungAndSelf();  // feeds baby or mom</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;chick_.Eat();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_TRUE(carrion->WasEaten());</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />Something is wrong here—that was <b><span style="color:#800000;">a lot of setup!</span></b>  The general-purpose FakeCondor <b><span style="color:#800000;">replicates too much functionality</span></b> from the full class.  The researchers' puppet didn't scavenge its own carrion, so why should ours? We just want to test that the baby Eats.  We condense various motherhood behaviors, such as giving food, into single method calls by <b><span style="color:#800000;">extracting a role interface</span></b>.  (If we couldn't change Condor, we would also write an adapter.)<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">class CondorMotherhoodRoleInterface {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;public:</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;virtual Carrion* GiveFood() = 0;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;virtual SomeReturnTypes* OtherMomBehaviors() = 0;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /></p><br /><br />Then we write a <b><span style="color:#800000;">single-use fake</span></b> which provides <b><span style="color:#800000;">only behaviors we need for this particular test</span></b>.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">class CondorFeedingPuppet: public CondorMotherhoodRoleInterface {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;public:</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;virtual Carrion* GiveFood() { return test_carrion_; }</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;virtual SomeReturnTypes* OtherMomBehaviors() { return NULL; } </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Carrion* test_carrion_;  // public var is tolerable in a one-off object</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST_F(BabyCondorTest, EatsCarrion) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;CondorFeedingPuppet mother;  FakeCarrion test_carrion;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;mother.test_carrion_ = &test_carrion;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;chick_.ReceiveFood(&mother);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;chick_.Eat();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_TRUE(test_carrion.WasEaten());</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />This <b><span style="color:#800000;">highly-focused fake</span></b> is <b><span style="color:#800000;">easy and quick to write</span></b>, and makes the test much <b><span style="color:#800000;">simpler</span></b> and <b><span style="color:#800000;">more readable</span></b>.   Don't overestimate the complexity of your dependencies!  Often a very simple fake is the best.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2009-01-22.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-2569411505886306059?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-keep-your-fakes-simple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Use EasyMock</title>
		<link>https://googledata.org/google-testing/tott-use-easymock/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-use-easymock</link>
		<comments>https://googledata.org/google-testing/tott-use-easymock/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 17:48:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Welcome back!  We trust you all had a good holiday season and are ready for more TotTs -- DaveMost of us are aware that mock and stub objects can make testing easier by isolating the class under test from external dependencies.  This goes hand-in-hand ...]]></description>
				<content:encoded><![CDATA[<span style="font-style:italic;">Welcome back!  We trust you all had a good holiday season and are ready for more TotTs -- Dave</span><br /><hr><br />Most of us are aware that mock and stub objects can make testing easier by isolating the class under test from external dependencies.  This goes hand-in-hand with dependency injection.  Writing all these classes can be a pain though. <br /><br />EasyMock provides an alternative. It dynamically implements an interface which records and replays your desired behavior. Let's say you want to model an <span style=" ;font-family:courier new, monospace;font-size: 120%;">ATM</span> interface: <br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public interface Atm { </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;boolean enterAccount(String accountNumber); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;boolean enterPin(String pin); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;boolean enterWithdrawalAmount(int dollars); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />It is pretty easy to mock this interface.  Still, every mock has to implement all three methods, even if you only need one.  You also need a separate mock for each set of inputs.  With EasyMock, you can create  mocks as you need them, <b><span style="color:#800000;">recording and replaying</span></b> your expectations:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public void testAtmLogin() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Atm mockAtm = createMock(Atm.class);       // 1</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EasyMock.expect(mockAtm.enterAccount("MyAccount")).andReturn(true);  // 2</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EasyMock.expect(mockAtm.enterPin("1234")).andReturn(true);  // 3</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EasyMock.replay(mockAtm);         // 4</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Account account = new Account();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;account.login(mockAtm);        // 5</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;assertTrue(account.isLoggedIn());</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EasyMock.verify(mockAtm);        // 6</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">} </span><br /></p><br /><br />We tell EasyMock to create a dynamic proxy implementing <span style=" ;font-family:courier new, monospace;font-size:120%;">Atm</span> (1), which starts in record mode.  Then we record two method calls along with the expected results (2 and 3).  The <span style=" ;font-family:courier new, monospace;font-size: 120%;">replay()</span> call tells EasyMock to stop recording (4).  After that, calls on the object return the set values.  If it gets a call it does not expect, it throws an Exception to fail fast.  <span style=" ;font-family:courier new, monospace;font-size: 120%;">Account</span> now uses the mock as if it were the real thing (5).  The <span style=" ;font-family:courier new, monospace;font-size: 120%;">verify()</span> method checks to see if the mock actually received all the calls you expect (6).  It really is that simple.  If we want to simulate failure, we can set up another test to return <span style=" ;font-family:courier new, monospace;font-size: 120%;">false</span> from one of the method calls.<br /><br />EasyMock has lots more capabilities as well.  It can throw exceptions.   It also can record multiple calls to the same method returning the same or different results.  You also can create <b><span style="color:#800000;">stub</span></b> expectations and <b><span style="color:#800000;">nice</span></b> mocks so you don't have to record every expected call.  You also can create several mocks, and even nest them to test classes with complex dependencies.  Beware, though, this often creates brittle tests, and is a sign the class under test needs refactoring. <br /><br />Basic EasyMock only mocks interfaces, but there is an EasyMockClassExtension that mocks non-final classes when you really must.  See the EasyMock documentation at the link below for details.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-12-04.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-7300358077337411660?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-use-easymock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Mockers of the (C++) World, Delight!</title>
		<link>https://googledata.org/google-testing/tott-mockers-of-the-c-world-delight/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-mockers-of-the-c-world-delight</link>
		<comments>https://googledata.org/google-testing/tott-mockers-of-the-c-world-delight/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 14:27:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sorry folks, this was a duplicate post. Please see the original here: http://googletesting.blogspot.com/2008/12/mockers-of-c-world-delight.html]]></description>
				<content:encoded><![CDATA[Sorry folks, this was a duplicate post. Please see the original here: <div><div style="text-align: center;"><a href="http://googletesting.blogspot.com/2008/12/mockers-of-c-world-delight.html">http://googletesting.blogspot.com/2008/12/mockers-of-c-world-delight.html</a><br /></div><div><br /></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-1464453472592187747?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-mockers-of-the-c-world-delight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Testing of the Turkey</title>
		<link>https://googledata.org/google-testing/tott-testing-of-the-turkey/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-testing-of-the-turkey</link>
		<comments>https://googledata.org/google-testing/tott-testing-of-the-turkey/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 21:11:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[No TotT post today.Happy Thanksgiving to all our North American readers.]]></description>
				<content:encoded><![CDATA[No TotT post today.<br /><br />Happy Thanksgiving to all our North American readers.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-6027039835792478810?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-testing-of-the-turkey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Finding Data Races in C++</title>
		<link>https://googledata.org/google-testing/tott-finding-data-races-in-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-finding-data-races-in-c</link>
		<comments>https://googledata.org/google-testing/tott-finding-data-races-in-c/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 18:32:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[If you've got some multi-threaded code, you may have data races in it. Data races are hard to find and reproduce – usually they will not occur in testing but will fire once a month in production.For example, you ask each of your two interns to bring ...]]></description>
				<content:encoded><![CDATA[If you've got some <b><span style="color:#800000;">multi-threaded code</span></b>, you may have <b><span style="color:#800000;">data races</span></b> in it. Data races are <b><span style="color:#800000;">hard to find and reproduce</span></b> – usually they will not occur in testing but will fire once a month in production.<br /><br />For example, you ask each of your two interns to bring you a bottle of beer. This will usually result in your getting two bottles (perhaps empty), but in a rare situation that the interns collide near the fridge, you may get fewer bottles.<br /> <br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;4 int <b><span style="color:#800000;">bottles_of_beer</span></b> = 0;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;5 void Intern1() { <b><span style="color:#800000;">bottles_of_beer++</span></b>; }  // Intern1 <b><span style="color:#800000;">forgot to use Mutex</span></b>.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;6 void Intern2() { <b><span style="color:#800000;">bottles_of_beer++</span></b>; }  // Intern2 copied from Intern1.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;7 int main() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;8   // Folks, bring me <b><span style="color:#800000;">one bottle of beer each</span></b>, please.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;9   ClosureThread intern1(NewPermanentCallback(Intern1)),</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">10                 intern2(NewPermanentCallback(Intern2));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">11   intern1.SetJoinable(true); intern2.SetJoinable(true);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">12   intern1.Start();           intern2.Start();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">13   intern1.Join();            intern2.Join();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">14   CHECK_EQ(<b><span style="color:#800000;">2, bottles_of_beer</span></b>) << "<b><span style="color:#800000;">Who didn't bring me my beer!?</span></b>";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">15 }</span><br /></p><br /><br />Want to <b><span style="color:#800000;">find data races in your code</span></b>? Run your program under <b><span style="color:#800000;">Helgrind</span></b>!<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">$ <b><span style="color:#800000;">helgrind</span></b> path/to/your/program</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;"><b><span style="color:#800000;">Possible data race</span></b> during read of size 4 at 0x5429C8<br />   at 0x400523: <b><span style="color:#800000;">Intern2() tott.cc:6</span></b></span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;by 0x400913: _FunctionResultCallback_0_0<false, void>::Run() ...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;by 0x4026BB: ClosureThread::Run() ...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Location 0x5429C8 has never been protected by any lock</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Location 0x5429C8 is 0 bytes inside global var "<b><span style="color:#800000;">bottles_of_beer</span></b>"</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;declared at tott.cc:4</span><br /></p><br /><br /><b><span style="color:#800000;">Helgrind</span></b> will also detect <b><span style="color:#800000;">deadlocks</span></b> for you. <br /><br /><b><span style="color:#800000;">Helgrind</span></b> is a tool based on <b><span style="color:#800000;">Valgrind</span></b>. Valgrind is a binary translation framework which has other useful tools such as a memory debugger and a cache simulator. Related TotT episodes will follow.<br /><br /><i><small>No beer was wasted in the making of this TotT.</small></i><br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-11-13.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-4509990705301500889?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-finding-data-races-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Contain Your Environment</title>
		<link>https://googledata.org/google-testing/tott-contain-your-environment/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-contain-your-environment</link>
		<comments>https://googledata.org/google-testing/tott-contain-your-environment/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 17:31:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Many modules must access elements of their environment that are too heavyweight for use in tests, for example, the file system or network.  To keep tests lightweight, we mock out these elements.  But what if no mockable interface is available, or the e...]]></description>
				<content:encoded><![CDATA[Many modules must access elements of their environment that are too heavyweight for use in tests, for example, the file system or network.  To keep tests lightweight, we mock out these elements.  But what if no mockable interface is available, or the existing interfaces pull in extraneous dependencies?  In such cases we can introduce a mediator interface that's directly associated with your module (usually as a public inner class).  We call this mediator an "Env" (for environment); this name helps readers of your class recognize the purpose of this interface. <br /><br />For example, consider a class that cleans the file system underlying a storage system:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">// Deletes files that are no longer reachable via our storage system's</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">// metadata.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">class FileCleaner {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public:</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;class Env {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public:</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;virtual bool MatchFiles(const char* pattern, vector<string>* filenames) = 0;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;virtual bool BulkDelete(const vector<string>& filenames) = 0;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;virtual MetadataReader* NewMetadataReader() = 0; </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;virtual ~Env();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;};</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// Constructs a FileCleaner.  Uses “env” to access files and metadata.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;FileCleaner(Env* env, QuotaManager* qm);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// Deletes files that are not reachable via metadata.  </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// Returns true on success.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;bool CleanOnce();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /></p><br /><br />FileCleaner::Env lets us test FileCleaner without accessing the real file system or metadata.  It also  makes it easy to <b><span style="color:#800000;">simulate various kinds of failures</span></b>, for example, of the file system:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">class NoFileSystemEnv : public FileCleaner::Env {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;virtual bool MatchFiles(const char* pattern, vector<string>* filenames) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;match_files_called_ = true;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;return false;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(FileCleanerTest, FileCleaningFailsWhenFileSystemFails) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;NoFileSystemEnv* env = new NoFileSystemEnv();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;FileCleaner cleaner(env, new MockQuotaManager());</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_FALSE(cleaner.CleanOnce());</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_TRUE(env->match_files_called_);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />An Env object is particularly useful for <b><span style="color:#800000;">restricting access</span></b> to other modules or systems, for example, when those modules have overly-wide interfaces.  This has the additional benefit of reducing your class's dependencies. However, be careful to <b><span style="color:#800000;">keep the “real” Env implementation simple</span></b>, lest you  introduce hard-to-find bugs in the Env.  The methods of your “real” Env implementation should just delegate to other, well-tested methods.<br /><br />The most important benefits of an Env are that it <b><span style="color:#800000;">documents how your class accesses its environment</span></b> and it <b><span style="color:#800000;">encourages future modifications to your module to keep tests small</span></b> by extending and mocking out the Env.<br /><br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-10-30.pdf" >this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-5201892493604377893?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-contain-your-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Floating-Point Comparison</title>
		<link>https://googledata.org/google-testing/tott-floating-point-comparison/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-floating-point-comparison</link>
		<comments>https://googledata.org/google-testing/tott-floating-point-comparison/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 17:45:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[If your code manipulates floating-point values, your tests will probably involve floating-point values as well.When comparing floating-point values, checking for equality might lead to unexpected results. Rounding errors can lead to a result that is cl...]]></description>
				<content:encoded><![CDATA[If your code manipulates <b><span style="color:#800000;">floating-point</span></b> values, your tests will probably involve <b><span style="color:#800000;">floating-point</span></b> values as well.<br /><br />When comparing floating-point values, checking for equality might lead to unexpected results. Rounding errors can lead to a result that is close to the expected one, but not equal. As a consequence, an assertion might fail when checking for equality of two floating-point quantities even if the program is implemented correctly.<br /><br />The Google C++ Testing Framework provides functions for comparing two floating-point quantities up to a given precision.<br /><br />In C++, you can use the following macros:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">ASSERT_FLOAT_EQ(expected, actual);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ASSERT_DOUBLE_EQ(expected, actual);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">EXPECT_FLOAT_EQ(expected, actual);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">EXPECT_DOUBLE_EQ(expected, actual);</span><br /></p><br /><br />In Java, JUnit overloads Assert.assertEquals for floating-point types:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(float expected, float actual, float delta);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(double expected, double actual, double delta);</span><br /></p><br /><br />An example (in C++):<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(SquareRootTest, CorrectResultForPositiveNumbers) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_FLOAT_EQ(2.0f, FloatSquareRoot(4.0f));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_FLOAT_EQ(23.3333f, FloatSquareRoot(544.44444f));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_DOUBLE_EQ(2.0, DoubleSquareRoot(4.0));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_DOUBLE_EQ(23.33333333333333, DoubleSquareRoot(544.44444444444444));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;// the above succeeds</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_EQ(2.0, DoubleSquareRoot(4.0));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;// the above fails</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_EQ(23.33333333333333, DoubleSquareRoot(544.44444444444444));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p> <br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-10-16.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-2972514787565931490?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-floating-point-comparison/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Simulating Time in jsUnit Tests</title>
		<link>https://googledata.org/google-testing/tott-simulating-time-in-jsunit-tests/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-simulating-time-in-jsunit-tests</link>
		<comments>https://googledata.org/google-testing/tott-simulating-time-in-jsunit-tests/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 17:12:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sometimes you need to test client-side JavaScript code that uses setTimeout() to do some work in the future. jsUnit contains the Clock.tick() method, which simulates time passing without causing the test to sleep.For example, this function will set up ...]]></description>
				<content:encoded><![CDATA[Sometimes you need to test client-side JavaScript code that uses <b><span style="color:#800000;">setTimeout()</span></b> to do some work in the future. <b><span style="color:#800000;">jsUnit</span></b> contains the <b><span style="color:#800000;">Clock.tick()</span></b> method, which simulates time passing without causing the test to sleep.<br />For example, this function will set up some callbacks to update a status message over the course of four seconds:<br /><br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">function showProgress(status) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;status.message = "Loading"; </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;for (var time = 1000; time <= 3000; time+= 1000) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;// Append a '.' to the message every second for 3 secs.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;setTimeout(function() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status.message += ".";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;}, time);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;setTimeout(function() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;// Special case for the 4th second.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;status.message = "Done";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}, 4000);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />The jsUnit test for this function would look like this:<br /><br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">function testUpdatesStatusMessageOverFourSeconds() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Clock.reset();  // Clear any existing timeout functions on the event queue.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;var status = {};</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;showProgress(status);  // Call our function.</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;assertEquals("Loading", status.message);</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Clock.tick(2000);  // Call any functions on the event queue that have been</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// scheduled for the first two seconds.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;assertEquals("Loading..", status.message);</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;Clock.tick(2000);  // Same thing again, for the next two seconds.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;assertEquals("Done", status.message);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />This test will run very quickly - it does not require four seconds to run. <br /><br />Clock supports the functions setTimeout(), setInterval(), clearTimeout(), and clearInterval(). The Clock object is defined in jsUnitMockTimeout.js, which is in the same directory as jsUnitCore.js.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-10-02.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-3262048785040147751?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-simulating-time-in-jsunit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Mockin Ur Objectz</title>
		<link>https://googledata.org/google-testing/tott-mockin-ur-objectz/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-mockin-ur-objectz</link>
		<comments>https://googledata.org/google-testing/tott-mockin-ur-objectz/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 02:57:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[[A light hearted episode this week... but still with a serious message.  Enjoy.  -Dave]HALP!  Mah unit tests be doin' too much I/O!  Testin' this lil' codes uses MOAR RESOURCES!GIMME lol_io LIKE LOLIOSO IM LIKE PROCESSIN WIT DATAZ OK?&#160;&#160;GIMME ...]]></description>
				<content:encoded><![CDATA[<span style="font-style:italic;">[A light hearted episode this week... but still with a serious message.  Enjoy.  -Dave]</span><br /><br />HALP!  Mah unit tests be doin' too much I/O!  Testin' this lil' codes uses MOAR RESOURCES!<br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">GIMME lol_io LIKE LOLIO</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">SO IM LIKE PROCESSIN WIT DATAZ OK?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;GIMME EACH BUCKET IN UR DATAZ OK?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;BUCKET OWN FUBARRED?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;N CAN HAS NONE</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;NOPE?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;N CAN HAS 1</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;KTHXBYE N</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">IZ __name__ KINDA LIKE “__main__”?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;UR PROCESSIN WIT LOLIO OWN GET_SOME_DATAZ</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;BTW, GET_SOME_DATAZ USES UR INTERNETS LOL</span><br /></p><br />Oh NOES!  Usin' internets in ur unit testz?  Don't clog the tubes!  Is not big truck!  Mock the LOLIO thingy.  No moar tubes!<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">GIMME mock_lol_io LIKE LOLIO</span><br /> <br /><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, GIMME THING TO TEST</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, TEST THE THING NOW KTHX</span><br /></p><br />Now ur test runs fast!  You can use mock_lol_io for killin' nondeterminism, too like for  exceptions n stuff.  Is fun, makes ur code execute pathz it nevar seen b4.  Wit dis, you can see wut happens when theres a OH NOES like the tubez bein clogged.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, SOMETIMES THEY BE CALLIN DIS DEPENDENCY INJECTION ROFL</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, YOU CAN UZE MOCKZ N STUF FER DIS LOOK:</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">IN MAI library GIMME mock_filesystem LIKE LOL_FAKE_FILEYSTEM</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, NOW U CAN USE LOL_FAKE_FILESYSTEM TO MAKE FAKE FILEZ IN MEMORY N STUFF</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">BTW, IS FASTER THAN OPENIN FILEZ ON TEST SERVAR</span><br /> </p><br />Now U know the sekrit for faster tests.  Shh, don't tell Microsawft or the Yahew.  They might be in our base, stealin our tech!<br /><br />KTHXBYE!<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-09-18.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-9004881427552468679?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-mockin-ur-objectz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Data Driven Traps!</title>
		<link>https://googledata.org/google-testing/tott-data-driven-traps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-data-driven-traps</link>
		<comments>https://googledata.org/google-testing/tott-data-driven-traps/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 22:54:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[When writing a unit test, it is tempting to exercise many scenarios by writing a data-driven test. For example, to test the function IsWord, you could write (ARRAYSIZE is a macro that returns the number of elements in an array):const struct {const char...]]></description>
				<content:encoded><![CDATA[When writing a unit test, it is tempting to exercise many scenarios by writing a data-driven test. For example, to test the function IsWord, you could write (ARRAYSIZE is a macro that returns the number of elements in an array):<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">const struct {const char* word; bool is_word;} test_data[] = {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;{"milk", true}, {"centre", false}, {"jklm", false},</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(IsWordTest, TestEverything) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;for (int i = 0; i &lt; ARRAYSIZE(test_data); i++)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;EXPECT_EQ(test_data[i].is_word, IsWord(test_data[i].word));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />This keeps the test code short and makes it easy to add new tests but makes it hard to identify a failing test assertion (and to get the debugger to stop in the right place). As your code grows the test data tends to grow <b><span style="color:#800000;">faster than linearly</span></b>. For example, if you add a parameter called locale to IsWord, the test could become:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;"> Locale LOCALES[] = { Word::US, Word::UK, Word::France, ... };</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">const struct {const char* word; bool is_word[NUM_LOCALES];} data[] = {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;{"milk", {true, true, false, ...}},  // one bool per language</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;{"centre", {false, true, true, ...}}, </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;{"jklm", {false, false, false, ...}}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /> <br /><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(IsWordTest, TestEverything) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;for (int i = 0; i &lt; ARRAYSIZE(data); i++) </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;for (int j = 0; j &lt; ARRAYSIZE(LOCALES); j++) </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXPECT_EQ(data[i].is_word[j], IsWord(data[i].word, LOCALES[i]));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />The change was relatively easy to make: change the data structure, fill in the boolean values for other locales and add a loop to the test code. But even this small changed has made the test harder to read and slower as it repeats potentially unnecessary checks. In addition, both the test AND the code have changed. How do you know the test is not broken? (Actually, it is broken. Can you see the bug?)  By contrast, <b><span style="color:#800000;">keeping the data in the test</span></b> gives us:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;"> TEST(IsWordTest, IsWordInMultipleLocales) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_TRUE(IsWord("milk", Word::UK)); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_TRUE(IsWord("milk", Word::US));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_FALSE(IsWord("milk", Word::France));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(IsWordTest, IsWordWithNonExistentWord) {   // 'jklm' test is not repeated </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_FALSE(IsWord("jklm", Word::US));            // as it uses the same code path</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />The difference between these two code snippets is minor but real-life data-driven tests quickly become <b><span style="color:#800000;">unmanageable</span></b>. A complete example would not fit on this page but if you look at your code base, you will find a few specimens lurking in some (not-so) forgotten test classes. They can be identified by their large size, vague names and the fact that they provide little to no information about why they fail.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-09-04.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-3860966436609827508?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-data-driven-traps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Sleeping != Synchronization</title>
		<link>https://googledata.org/google-testing/tott-sleeping-synchronization/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-sleeping-synchronization</link>
		<comments>https://googledata.org/google-testing/tott-sleeping-synchronization/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 19:54:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[You've got some code that uses threads, and it's making your tests flaky and slow. How do you fix it? First, most of the code is probably still single-threaded: test those parts separately. But how to test the threading behavior itself?Often, threaded ...]]></description>
				<content:encoded><![CDATA[You've got some code that uses threads, and it's making your tests flaky and slow. How do you fix it? First, most of the code is probably still single-threaded: test those parts separately. But how to test the <b><span style="color:#800000;">threading behavior</span></b> itself?<br /><br />Often, threaded tests start out using sleeps to wait for something to happen. This test is trying to verify that DelegateToIntern spawns its work argument into a parallel thread and invokes a callback when it's done.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">def testInternMakesCoffee(self):</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.caffeinated = False</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;def DrinkCoffee(): self.caffeinated = True</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;DelegateToIntern(work=Intern().MakeCoffee, callback=DrinkCoffee)</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.assertFalse(self.caffeinated, "I watch YouTubework; intern brews")</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;<span style="color:#800000;">time.sleep(60)</span>  # 1min should be long enough to make coffee, right?</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.assertTrue(self.caffeinated, "Where's mah coffee?!?")</span><br /></p><br /><br />Aside from abusing your intern every time you run the test, this test takes a minute longer than it needs to, and it may even fail when the machine (or intern!) is loaded in odd ways. You should always <b><span style="color:#800000;">be skeptical of sleep statements</span></b>, especially in tests. How can we make the test more reliable?<br /><br />The answer is to explicitly control when things happen within DelegateToIntern with a <b><span style="color:#800000;">threading.Event</span></b> in Python, a <b><span style="color:#800000;">Notification</span></b> in C++, or a <b><span style="color:#800000;">CountDownLatch(1)</span></b> in Java.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">def testInternMakesCoffee(self):</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;is_started, can_finish, is_done = Event(), Event(), Event()</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;def FakeCoffeeMaker():</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#800000;">is_started.set()</span>  # Allow is_started.wait() to return.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;# Wait up to 1min for can_finish.set() to be called. The timeout</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;# prevents failures from hanging, but doesn't delay a passing test.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#800000;">can_finish.wait(timeout=60)</span>  # .await() in Java</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;DelegateToIntern(work=FakeCoffeeMaker, callback=lambda:is_done.set())</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;is_started.wait(timeout=60)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.assertTrue(is_started.isSet(), "FakeCoffeeMaker should have started")</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.assertFalse(is_done.isSet(), "Don't bug me before coffee's made")</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;can_finish.set()  # Now let FakeCoffeeMaker return.</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;is_done.wait(timeout=60)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;self.assertTrue(is_done.isSet(), "Intern should ping when coffee's ready")</span><br /></p><br /><br />Now we're guaranteed that no part of the test runs faster than we expect, and the test passes very quickly. It could run slowly when it fails, but you can easily lower the timeouts while you're debugging it.<br /><br />We'll look at testing for race conditions in a future episode.<br /><br /><span style=" ;font-size:80%;">No interns were harmed in the making of this TotT.</span><br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-08-21.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-3721082174834740883?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-sleeping-synchronization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: 100 and counting</title>
		<link>https://googledata.org/google-testing/tott-100-and-counting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-100-and-counting</link>
		<comments>https://googledata.org/google-testing/tott-100-and-counting/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 14:51:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[(This week, TotT issued our 100th internally published episode. That's more than have been published to this Testing Blog -- after all, the internal episodes had an 8-month head start, and many  would make no sense to readers outside our own stalls -- ...]]></description>
				<content:encoded><![CDATA[<span style="font-style:italic;">(This week, TotT issued our 100th internally published episode. That's more than have been published to this Testing Blog -- after all, the internal episodes had an 8-month head start, and many  would make no sense to readers outside our own stalls -- but we thought you'd still enjoy reading about the history and future of TotT.)</span><br /><br />Did you know <b><span style="color:#800000;">there was a time before Testing on the Toilet</span></b>? It's true! 19.3% of Googlers remember back before TotT's weekly entertainment and testing advice. In this 100th episode, let's reminisce a bit, then look toward our future ... and how you can help keep our toilets humorous and informative.<br /><br />After our first episode (May 2, 2006), <b><span style="color:#800000;">TotT was met with some skepticism</span></b> from Googlers and others, including Slashdot.org, who said "It [is] faintly reminiscent of a cult." But <b><span style="color:#800000;">soon Google embraced TotT</span></b>. A few weeks later, someone complained on a mailing list: "Why wasn't I informed of this [new testing] technique at my nearby toilet?" <b><span style="color:#800000;">Nooglers eagerly sign up to distribute episodes</span></b> with our motto: “Debugging sucks. Testing rocks!”<br /><br /> Some mottos that didn't make the cut:<br />   "Testing on the Toilet: it's not just for pregnancy anymore!"<br />   "Make software testing your number one priority!"<br />   "Testing: you can't just wash your hands of it."<br /><br />Now, <b><span style="color:#800000;">TotT appears weekly</span></b>:<ul><li>In hundreds of stalls in 30 Google offices  </li><li>With episodes covering many programming languages and application domains</li><li>Written by volunteer authors from offices worldwide. </li><li>TotT is also published to fans outside our walls on Google's public Testing Blog.</li></ul><br />It's all <b><span style="color:#800000;">done by a volunteer, grassroots effort</span></b> of dedicated, passionate Googlers. This bottom-up activism – engineers making other engineers' lives better – is <b><span style="color:#800000;">a hallmark of Google culture</span></b>. <br /><br /><b><span style="color:#800000;">Other grouplets have adopted TotT's techniques</span></b> to effectively spread their own messages in flyers like Hiring on the Table, and “TotT Presents” guest spots have shown items such as Production on the Potty.<br /><br /><img style="display:block; margin:0px auto 10px; text-align:center;" src="http://3.bp.blogspot.com/_lUDLhPj-dyg/SKRHAUej0cI/AAAAAAAAABc/kYxH39e3Xsw/s320/kangaroograph.png" border="0" alt="" /><br /><br />Little known fact: TotT's testing advocacy is a leading factor in the recovery of the red kangaroo population, due to the drop in demand for “build red” phosphorus.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-08-14.pdf">this special episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-425908255506392382?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-100-and-counting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>TotT: A Matter of Black and White</title>
		<link>https://googledata.org/google-testing/tott-a-matter-of-black-and-white/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-a-matter-of-black-and-white</link>
		<comments>https://googledata.org/google-testing/tott-a-matter-of-black-and-white/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 20:01:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[The progressive developer knows that in this complex modern world, things aren't always black-and-white, even in  testing. Sometimes we know the software won't return the best answer, or even a correct answer, for all input. You may be tempted to write...]]></description>
				<content:encoded><![CDATA[<p>The progressive developer knows that in this complex modern world, things aren't always <b><span style="color:#800000;">black-and-white</span></b>, even in  testing. Sometimes we know the software won't return the best answer, or even a correct answer, for all input. You may be tempted to write only test cases that your software can pass. After all, we can't have automated tests that fail in even one instance. But, this would miss an opportunity.</p><br /><p>Speaking of black-and-white, take decoding of <b><span style="color:#800000;">two-dimensional barcodes, like QR Codes</span></b>. From a blurry, skewed, rotated image of a barcode, software has to pick it out, transform it, and decode it:</p><br /><p><img style="display:block; margin:0px auto 10px; text-align:center;" src="http://big.corp.google.com:80/~dastels/tott-staging/NeoOfficeScreenSnapz001-770183.png" border="0" alt="" /></p><br /><p> <img style="display:block; margin:0px auto 10px; text-align:center;" src="http://big.corp.google.com:80/~dastels/tott-staging/NeoOfficeScreenSnapz002-710260.png" border="0" alt="" /></p><br /><p><center><b>http://google.com/gwt/n?u=bluenile.com</b></center></p><br /><p>Even the best software can't always find that barcode. What should tests for such software do?</p><br /><p>We have some answers, from experience testing such software. We have two groups of black-box tests that verify that images decode correctly: <b><span style="color:#800000;">must-have</span></b> and <b><span style="color:#800000;">nice-to-have</span></b>. Tests verify that the must-have set – the easy images – definitely decode correctly. This is what traditional tests would include, which typically demand a 100% pass rate. But we also see how well we do on the more difficult nice-to-have set. We might verify that 50% of them decode, and fail otherwise.</p><br /><p>The advantage? We can include tougher test cases in unit tests, instead of avoiding them. We can observe small changes – improvements as well as degradations – in decode accuracy over time. It doubles as a crude quality evaluation framework.</p><br /><p>Where can this progressive thinking be applied? Maybe when your code...</p><br /><p><b><span style="color:#800000;">Only needs to be correct in most cases.</span></b> As here, write tests to verify easy cases work, but also that some hard cases pass too.</p><br /><p><b><span style="color:#800000;">Needs to be fast.</span></b> You write unit tests that verify it runs "fast enough" on simple input. How about writing tests that make sure it runs "fast enough" on most of some larger inputs too?</p><br /><p><b><span style="color:#800000;">Is heuristic.</span></b> You write unit tests that verify that the answer is “really close” to optimal on simple input, but also that it's “kind of close” on difficult input.</p><br /><p>By the way, did we mention project <b><span style="color:#800000;">ZXing</span></b>, Google's open-source decoder project? Or that <b><span style="color:#800000;">Print Ads</span></b> is already helping clients place these two-dimensional barcodes in the New York Times? Or that there are other formats like <b><span style="color:#800000;">Data Matrix</span></b>? or that you can put <b><span style="color:#800000;">more than just a URL</span></b> in these barcodes? This is a technology going global, so, time to read up on it.</p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-08-07.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-8051214618321974691?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-a-matter-of-black-and-white/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Testing Against Interfaces</title>
		<link>https://googledata.org/google-testing/tott-testing-against-interfaces/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-testing-against-interfaces</link>
		<comments>https://googledata.org/google-testing/tott-testing-against-interfaces/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 17:53:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[To quell a lingering feeling of inadequacy, you took the time to build your own planetary death ray, a veritable rite of passage in the engineering profession. Congratulations. And you were feeling pretty proud until the following weekend, when you pur...]]></description>
				<content:encoded><![CDATA[To quell a lingering feeling of inadequacy, you took the time to build your own planetary death ray, a veritable rite of passage in the engineering profession. Congratulations. And you were feeling pretty proud until the following weekend, when you purchased the limited-edition Star Wars trilogy with Ewok commentary, and upon watching the Death Star destroy Alderaan, you realized that you had made a bad decision: Your planetary death ray has a blue laser, but green lasers look so much cooler. But it's not a simple matter of going down to Radio Shack to purchase a green laser that you can swap into your existing death ray. You're going to have to build another planetary death ray from the ground-up to have a green laser, which is fine by you because owning two death rays instead of one will only make the neighbors more jealous.<br /><br />Both your planetary death rays should interoperate with a variety of other bed-wettingly awesome technology, so it's natural that they export the same Java API:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public interface PlanetaryDeathRay {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void aim(double xPosition, double yPosition);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public boolean fire();  /* call this if she says the rebel</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base is on Dantooine */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class GreenLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /></p><br /><br />Testing both death rays is important so there are no major malfunctions, like destroying Omicron Persei VIII instead of Omicron Persei VII. You want to run the same tests against both implementations to ensure that they exhibit the same behavior – something you could easily do if you only once defined tests that run against any <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation. Start by writing the following abstract class that extends <span style="font-family:Courier New, monospace;">junit.framework.TestCase</span>:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public abstract class PlanetaryDeathRayTestCase</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends TestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay deathRay;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void setUp() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void tearDown() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = null;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected abstract PlanetaryDeathRay createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* create the PlanetaryDeathRay to test */</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testAim() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.aim() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testFire() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.fire() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />Note that the setUp method gets the particular <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation to test from the abstract <span style="font-family:Courier New, monospace;">createDeathRay</span> method. A subclass needs to implement only this method to create a complete test: the <span style="font-family:Courier New, monospace;">testAim</span> and <span style="font-family:Courier New, monospace;">testFire</span> methods it inherits will be part of the test when it runs:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRayTest</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends PlanetaryDeathRayTestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay createDeathRay() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return new BlueLaserPlanetaryDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />You can easily add new tests to this class to test functionality specific to <span style="font-family:Courier New, monospace;">BlueLaserPlanetaryDeathRay</span>.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-07-24.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-1425671639485176679?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-testing-against-interfaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: EXPECT vs. ASSERT</title>
		<link>https://googledata.org/google-testing/tott-expect-vs-assert/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-expect-vs-assert</link>
		<comments>https://googledata.org/google-testing/tott-expect-vs-assert/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 21:05:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Because the Google C++ Testing Framework was opensourced last week, there will be episodes focusing on it published here in the future.  Watch for them.  I've reshuffled the schedule to get one out this week.Google C++ Testing Framework supports two fa...]]></description>
				<content:encoded><![CDATA[<p><i>Because the <a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> was opensourced last week, there will be episodes focusing on it published here in the future.  Watch for them.  I've reshuffled the schedule to get one out this week.</i></p><br /><br /><center><br /><img style="margin:0 10px 10px 0;" src="http://2.bp.blogspot.com/_lUDLhPj-dyg/SHZ59-lqLJI/AAAAAAAAAA8/UXB1MWRaxR0/s320/frame-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221494923662601362" /><br /><img style="margin:0 10px 10px 0;" src="http://3.bp.blogspot.com/_lUDLhPj-dyg/SHZ59xHHIPI/AAAAAAAAABE/psUkoAxowsk/s320/frame-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221494920044814578" /><br /><img style="margin:0 10px 10px 0;" src="http://4.bp.blogspot.com/_lUDLhPj-dyg/SHZ5-IffwxI/AAAAAAAAABM/mMNOWZTC2Lk/s320/frame-3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221494926321107730" /><br /><img style="margin:0 10px 10px 0;" src="http://3.bp.blogspot.com/_lUDLhPj-dyg/SHZ5-HGaLdI/AAAAAAAAABU/jkuavVNLujQ/s320/frame-4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5221494925947448786" /><br /></center><br /><p><a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> supports two families of assertions with the same interface:</p><ul><li><b>ASSERT</b>: Fails fast, aborting the current function.</li><li><b>EXPECT</b>: Continues after the failure.</li></ul><br /><p>As Moka the code monkey has shown Uni the testing robot, EXPECT is often more appropriate because it:  reveals more failures in a single run, and allows more to be fixed in a single edit/compile/run-tests cycle.  Example:<p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(WordStemmerTest, StemsPluralSuffixes) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("jump", stemmer->Stem("jumps"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("pixi", stemmer->Stem("pixies"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("prioriti", stemmer->Stem("priorities"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// etc ...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Use ASSERT when it doesn't make sense to continue.  Example:</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(FileGeneratorTest, CreatesFileContainingSequenceOfChars) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_TRUE(fp = fopen(path, "r"))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "Failed to open " << path;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_EQ(10, fread(buffer, 1, 10, fp))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is too small";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;buffer[10] = '\0';</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("123456789", buffer)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is corrupted";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-07-10.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-8870154328391757476?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-expect-vs-assert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Defeat &quot;Static Cling&quot;</title>
		<link>https://googledata.org/google-testing/defeat-static-cling/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defeat-static-cling</link>
		<comments>https://googledata.org/google-testing/defeat-static-cling/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 16:43:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[You're pair programming and, as many brilliant people are apt to do, talking out loud.  "I'll make a mock, inject it, and rerun the test. It should pa- ...D'OH"   Your partner notices the exception "ConnectionFactory not initialized".  "What?" she says...]]></description>
				<content:encoded><![CDATA[You're pair programming and, as many brilliant people are apt to do, talking out loud.  "I'll make a mock, inject it, and rerun the test. It should pa- ...D'OH"   Your partner notices the exception <i>"ConnectionFactory not initialized"</i>.  "What?" she says, "Something is using the database? Dang, and this was supposed to be a small test."<br /><br />Upon inspection you find that your class is calling a <b><font color=#800000>static</font></b> method on some other class.  You've got <b><font color=#800000>Static Cling</font></b>! If you're (ab)using a data persistence layer that generates code which relies on static methods, <i>and weren't careful</i>, your code might look something like this:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">public class MyObject {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public int doSomething(int id) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return TheirEntity.selectById(id).getSomething();</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><br />As a result, you can't call doSomething without calling <font face="Courier New, monospace">TheirEntity</font>'s static method. This code is hard to test because static methods are <b><font color=#800000>impossible</font></b> to mock in Java.<br /><br />So, how do you get rid of this form of Static Cling and get that small test to pass?  You can use a technique sometimes known as the <b><font color=#800000>Repository Pattern</font></b>, a form of Abstract Factory.  Create an interface and an implementation with the unmockable static method calls:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">interface TheirEntityRepository {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;TheirEntity selectById(int id);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;// other static methods on TheirEntity can be</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;// represented here too</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">public class TheirEntityStaticRepository</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;implements TheirEntityRepository {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public TheirEntity selectById(int id) { // non-static</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return TheirEntity.selectById(id);    // calls static method</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><br />Next, inject a <font face="Courier New, monospace">TheirEntityRepository</font> into <font face="Courier New, monospace">MyObject</font> and use it instead of calls to the static method:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">public class MyObject {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;private final TheirEntityRepository repository;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public MyEntity(TheirEntityRepository arg) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;this.repository = arg;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public int doSomething(int id) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return repository.selectById(id).getSomething();</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><br />You can do this even if you don't have access to source code for <font face="Courier New, monospace">TheirEntity</font>, since you're not changing the source itself, but merely encapsulating its static methods in an injectable interface.  The techniques shown here generalize to the case where a static method acts as a Factory of objects.<br /><br />Now you can inject different implementations of the repository for different tests, such as "never finds anything," "always throws an exception," "only returns a <font face="Courier New, monospace">TheirEntity</font> if the id is a prime," and so forth.  These kinds of tests would've been impossible before this refactoring.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-06-26.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-4591414625061290830?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/defeat-static-cling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Friends You Can Depend On</title>
		<link>https://googledata.org/google-testing/tott-friends-you-can-depend-on/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-friends-you-can-depend-on</link>
		<comments>https://googledata.org/google-testing/tott-friends-you-can-depend-on/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 16:51:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[When you want to test code that depends on something that is too difficult or slow to use in a test environment, swap in a test double for the dependency.A Dummy passes bogus input values around to satisfy an API.Item item = new Item(ITEM_NAME);Shoppin...]]></description>
				<content:encoded><![CDATA[<p>When you want to test code that depends on something that is too difficult or slow to use in a test environment, swap in a test double for the dependency.<br />A Dummy passes bogus input values around to satisfy an API.</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">Item item = new Item(ITEM_NAME);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ShoppingCart cart = new ShoppingCart();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.add(item, QUANTITY);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(QUANTITY, cart.getItem(ITEM_NAME));  </span></p><br /><p>A Stub overrides the real object and returns hard-coded values. Testing with stubs only is state-based testing; you exercise the system and then assert that the system is in an expected state.  </p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">ItemPricer pricer = new ItemPricer() { <br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public BigDecimal getPrice(String name){ return PRICE; }</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">};</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ShoppingCart cart = new ShoppingCart(pricer);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.add(dummyItem, QUANTITY);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(QUANTITY*PRICE, cart.getCost(ITEM_NAME));</span></p><br /><p>A Mock can return values, but it also cares about the way its methods are called (“strict mocks” care about the order of method calls, whereas “lenient mocks” do not.)  Testing with mocks is interaction-based testing; you set expectations on the mock, and the mock verifies the expectations as it is exercised.  This example uses JMock to generate the mock (EasyMock is similar):</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">Mockery context = new Mockery();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">final ItemPricer pricer = context.mock(ItemPricer.class);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">context.checking(new Expectations() {{</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;one(pricer).getPrice(ITEM_NAME);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;will(returnValue(PRICE));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}});</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ShoppingCart cart = new ShoppingCart(pricer);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.add(dummyItem, QUANTITY);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.getCost(ITEM_NAME);    </span>    <br /><span style=" ;font-family:courier new, monospace;font-size:100%;">context.assertIsSatisfied();</span></p><br /><p>A Spy serves the same purpose as a mock: returning values and recording calls to its methods.  However, tests with spies are state-based rather than interaction-based, so the tests look more like stub style tests. </p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TransactionLog log = new TransactionLogSpy();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ShoppingCart cart = new ShoppingCart(log);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.add(dummyItem, QUANTITY);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(1, logSpy.getNumberOfTransactionsLogged()); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(QUANTITY*PRICE, log.getTransactionSubTotal(1));</span></p><br /><p>A Fake swaps out a real implementation with a simpler, fake implementation. The classic example is implementing an in-memory database. </p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">Repository<Transaction> repo = new InMemoryRepository<Transaction>();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">ShoppingCart cart = new ShoppingCart(repo);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">cart.add(dummyItem, QUANTITY);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(1, repo.getTransactions(cart).Count); </span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">assertEquals(QUANTITY, repo.getById(cart.id()).getQuantity(ITEM_NAME));</span></p><br /><p>While this episode used Java for its examples, all of the above “friends” certainly exist in C++, Python, JavaScript, and probably in YOUR favorite language as well.</p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-06-12.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-7184144255017647866?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-friends-you-can-depend-on/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: The Invisible Branch</title>
		<link>https://googledata.org/google-testing/tott-the-invisible-branch/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-the-invisible-branch</link>
		<comments>https://googledata.org/google-testing/tott-the-invisible-branch/#comments</comments>
		<pubDate>Wed, 28 May 2008 22:19:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Full statement coverage may be necessary for good testing coverage, but it isn't sufficient. Two places where statement coverage will be inadequate are branches and loops. In this episode, we'll look at branches, and specifically the differences betwee...]]></description>
				<content:encoded><![CDATA[<p>Full statement coverage may be necessary for good testing coverage, but it isn't sufficient. Two places where statement coverage will be inadequate are branches and loops. In this episode, we'll look at branches, and specifically the differences between <b><font color=#800000>statement coverage</font></b> and <b><font color=#800000>branch coverage</font></b>.</p><br /><p>Let's consider a case where branch coverage and statement coverage aren't the same.  Suppose we test the following snippet.  We can get complete statement coverage with a single test by using a berserk EvilOverLord:</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">bool DeathRay::ShouldFire(EvilOverLord& o, Target& t) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;double accumulated_rage = 0.0;</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;if (o.IsBerserk())</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;accumulated_rage += kEvilOverlordBerserkRage;</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;accumulated_rage += o.RageFeltTowards(t);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;return (accumulated_rage > kDeathRayRageThreshold);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><p>But what if DeathRay should fire at this Target even with a non-berserk Overlord?  Well, we need another test for that.  What should the test be?  Let's rewrite the code a little bit.  We would never see code like this in the real world, but it'll help us clarify an important point.</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">bool DeathRay::ShouldFire(EvilOverLord& o, Target& t) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;double accumulated_rage = 0.0;</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;if (o.IsBerserk()) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;accumulated_rage += kEvilOverlordBerserkRage;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;} else {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;accumulated_rage += o.RageFeltTowards(t);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;return (accumulated_rage > kDeathRayRageThreshold);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><p>Why do we add an else clause if it doesn't actually do anything?  If you were to <b><font color=#800000>draw a flowchart</font></b> of both snippets (left as an exercise – and we recommend against using the paper provided), the flowcharts would be identical.  The fact that the else isn't there in the first snippet is simply a convenience for us as coders – we generally don't want to write code to do nothing special – but <b><font color=#800000>the branch still exists</font></b>...  put another way, <b><font color=#800000>every <i>if</i> has an <i>else</i></font></b>.  Some of them just happen to be invisible.</p><br /><p>When you're testing, then, it isn't enough to cover all the statements – you should <b><font color=#800000>cover all the the edges in the control flow graph</font></b> – which can be even more complicated with loops and nested ifs.  In fact, part of the art of large-scale white-box testing is finding the minimum number of tests to cover the maximum number of paths.  So the lesson here is, just because you can't see a branch doesn't mean it isn't there – or that you shouldn't test it.</p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-05-29.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-7408541936845962351?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-the-invisible-branch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Using Dependancy Injection to Avoid Singletons</title>
		<link>https://googledata.org/google-testing/tott-using-dependancy-injection-to-avoid-singletons/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-using-dependancy-injection-to-avoid-singletons</link>
		<comments>https://googledata.org/google-testing/tott-using-dependancy-injection-to-avoid-singletons/#comments</comments>
		<pubDate>Fri, 16 May 2008 06:16:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[It's hard to test code that uses singletons.   Typically, the code you want to test is coupled strongly with the singleton instance.  You can't control the creation of the singleton object because often it is created in a static initializer or static m...]]></description>
				<content:encoded><![CDATA[<b><font color=#800000>It's hard to test code that uses singletons.</font></b>   Typically, the code you want to test is coupled strongly with the singleton instance.  You can't control the creation of the singleton object because often it is created in a static initializer or static method.  As a result, you also can't mock out the behavior of that Singleton instance.<br /><br />If changing the implementation of a singleton class is not an option, but changing the <b><font color=#800000>client</font></b> of a singleton is, a simple refactoring can make it easier to test.  Let's say you had a method that uses a <font face="Courier New, monospace">Server</font> as a singleton instance:<br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">public class Client {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public int process(Params params) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;Server server = Server.getInstance();</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;Data data = server.retrieveData(params);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;...</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br />You can refactor <font face="Courier New, monospace">Client</font> to use <b><font color=#800000>Dependency Injection</font></b> and avoid its use of the singleton pattern altogether.  You have not lost any functionality, and have also not lost the requirement that only a singleton instance of <font face="Courier New, monospace">Server</font> must exist.  The only difference is that instead of getting the <font face="Courier New, monospace">Server</font> instance from the static <font face="Courier New, monospace">getInstance</font> method, <font face="Courier New, monospace">Client</font> receives it in its constructor.  You have made the class easier to test!<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">public class Client {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;private final Server server;</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public Client(Server server) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;this.server = server;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;public int process(Params params){</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;Data data = this.server.retrieveData(params);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;...</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br />When testing, you can create a mock <font face="Courier New, monospace">Server</font> with whatever expected behavior you need and pass it into the <font face="Courier New, monospace">Client</font> under test:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">public void testProcess() {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;Server mockServer = createMock(Server.class);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;Client c = new Client(mockServer);</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;assertEquals(5, c.process(params));</span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-05-15.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-3417901443265400654?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-using-dependancy-injection-to-avoid-singletons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Testable Contracts Make Exceptional Neighbors</title>
		<link>https://googledata.org/google-testing/tott-testable-contracts-make-exceptional-neighbors/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-testable-contracts-make-exceptional-neighbors</link>
		<comments>https://googledata.org/google-testing/tott-testable-contracts-make-exceptional-neighbors/#comments</comments>
		<pubDate>Thu, 01 May 2008 17:06:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Consider the following function, which modifies a client-supplied object:bool SomeCollection::GetObjects(vector* objects) const {&#160;&#160;objects->clear();&#160;&#160;typedef vector::const_iterator Iterator;&#160;&#160;for (Iterator i = collection_....]]></description>
				<content:encoded><![CDATA[Consider the following function, which modifies a client-supplied object:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;"><b>bool</b> SomeCollection::<b>GetObjects(vector<Object*>* objects)</b> const {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>objects->clear();</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;typedef vector<Object*>::const_iterator Iterator;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;for (Iterator i = collection_.begin(); </span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i != collection_.end(); </span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++i) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<b>if ((*i)->IsFubarred()) return false;</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<b>objects->push_back(*i);</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>return true;</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><br />Consider when <font face="Courier New, monospace">GetObjects()</font> is called.  What if the caller doesn't check the return value, and assumes the data is in a valid state when it actually is not?  If the caller does check the return value, <b><font color=#800000>what can it assume about the state of its objects in the failure case</font></b>?  When <font face="Courier New, monospace">GetObjects()</font> fails, it would be much better if either all the objects were collected or none of them.  This can help avoid introducing hard to find bugs.<br /><br />By using good design contracts and a solid implementation, it is reasonably easy to make functions like <font face="Courier New, monospace">GetObjects()</font> behave like transactions.  By following Sutter's rule of <b><font color=#800000>modifying externally-visible state only after completing all operations which could possibly fail</font></b> [1], and mixing in Meyers's “swap trick” [2], we move from the realm of undefined behavior to what Abrahams defines as the strong guarantee [3]:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;"><b>bool</b> SomeCollection::<b>GetObjects(vector<Object*>* objects)</b> const {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>vector<Object*> known_good_objects;</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;typedef vector<Object*>::const_iterator Iterator;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;for (Iterator i = collection_.begin(); </span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i != collection_.end(); </span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++i) {</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;if ((*i)->IsFubarred()) return false;</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<b>known_good_objects->push_back(*i);</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>objects->swap(known_good_objects);</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>return true;</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">}</span><br /></p><br /><br />At the cost of one temporary and a pointer swap, we've strengthened the contract of our interface such that, at best, the caller received a complete, new collection of valid objects; at worst, the state of the caller's objects remains unchanged.   The caller might not verify the return value, but will not suffer from undefined results.  This allows us to reason much more clearly about the program state, making it much easier to verify the intended outcome with automated tests as well as recreate, pinpoint, and banish bugs with regression tests.<br /><br /><ol><li><a href="http://www.gotw.ca/publications">http://www.gotw.ca/publications</a></li><li>Scott Meyers, Effective C++</li><li><a href="http://www.boost.org/more/generic_exception_safety.html">http://www.boost.org/more/generic_exception_safety.html</a></li></ol><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-05-01.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-8794245154286217763?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-testable-contracts-make-exceptional-neighbors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Avoiding Flakey Tests</title>
		<link>https://googledata.org/google-testing/tott-avoiding-flakey-tests/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-avoiding-flakey-tests</link>
		<comments>https://googledata.org/google-testing/tott-avoiding-flakey-tests/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 16:05:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Flaky tests make your life more difficult. You get failure notifications that aren't helpful. You might become numb to failures and miss an actual failure condition. Your changes might get unfairly blamed for causing a flaky test to fail. Unfortunately...]]></description>
				<content:encoded><![CDATA[Flaky tests make your life more difficult. You get failure notifications that aren't helpful. You might become numb to failures and miss an actual failure condition. Your changes might get unfairly blamed for causing a flaky test to fail. <br /><br />Unfortunately, <b><font color=#800000>a myriad of factors can make a test flaky</font></b>. Today, we tackle a simple example: file access from a unit test. Take this function and its test:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">def CreateGapLease(self):</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;data_file = open('/leases/gap', 'w+')</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;data_file.write(contract_data)</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;data_file.close()</span><br /><br /><span style="font-family:courier new, monospace; font-size:100%;">def testCreateGapLease(self):</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;contract_writer.CreateGapLease()</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;self.assertEqual(ReadFileContents('/leases/gap'),</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contract_data)</span><br /></p><br /><br />What if <font face="Courier New, monospace">/leases/gap</font> already exists and contains some data? <font face="Courier New, monospace">testCreateGapLease</font> will fail. This is a general problem where preconditions are assumed to be correct. This could just as easily happen by assuming a database contains the proper information (or no information). <b><font color=#800000>What if another test that uses that file was running concurrently?</font></b> <br /><br />If you really want to test your code using live resources, always check your assumptions. In this case, clearing the file at the start of the test can reduce its brittleness:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">def testCreateGapLease(self):</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>if os.path.exists(lease_file):</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;<b>RemoveFile(lease_file)</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;...</span><br /></p><br /><br />Unfortunately, this doesn't completely eliminate the flakiness of our test. If <font face="Courier New, monospace">/leases/gap</font> is an NFS path or can be written to by a different test, our test can still fail unexpectedly. It's better for the test to use a unique resource. This can be accomplished with a small refactoring of <font face="Courier New, monospace">CreateGapLease</font>:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">def CreateGapLease(self<b>, lease_path=None</b>):</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;if lease_path is None:</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;lease_path = '/leases/gap'</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;...</span><br /></p><br /><br />The callers of <font face="Courier New, monospace">CreateGapLease</font> can continue invoking it as usual, but the unit test can pass in a different path: <br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:100%;">def testCreateGapLease(self):</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;<b>lease_file = os.path.join(FLAGS.test_tmpdir, 'gap')</b></span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;contract_writer.CreateGapLease(lease_path=lease_file)</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;self.assertEqual(ReadFileContents(lease_file),</span><br /><span style="font-family:courier new, monospace; font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contract_data)</span><br /></p><br /><br />Of course, to make your test as fast as possible, it would be better to forgo disk access altogether by using a mock file system.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-04-17.pdf">this episode</a> of Testing on the Toilet and post it in your office.<br /><br /><i>Due to illness availability of the PDF will be slightly delayed</i><br /><br /><i><b>The PDF is now available at the above link</b></i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-4366529983057271760?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-avoiding-flakey-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Time is Random</title>
		<link>https://googledata.org/google-testing/tott-time-is-random/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-time-is-random</link>
		<comments>https://googledata.org/google-testing/tott-time-is-random/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 05:56:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[How can a method be well tested when it's inputs can't be clearly identified? Consider this method in Java:/** Return a date object representing the start of the next minute from now */public Date nextMinuteFromNow() {&#160;&#160;long nowAsMillis = Sys...]]></description>
				<content:encoded><![CDATA[<b><font color=#800000>How can a method be well tested when it's inputs can't be clearly identified?</font></b> Consider this method in Java:<br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">/** Return a date object representing the start of the next minute from now */</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">public Date <b>nextMinuteFromNow()</b> {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;<b>long nowAsMillis = System.currentTimeMillis()</b>;</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;Date then = new Date(nowAsMillis + 60000);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;then.setSeconds(0);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;then.setMilliseconds(0);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;return then;</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /></p><br />There are two barriers to effectively testing this method:<br /><ol><li>There is no easy way to test corner cases; you're at the mercy of the system clock to supply input conditions.</li><br /><li>When <b><font face="courier new, monospace">nextMinuteFromNow()</font></b> returns, the time has changed. This means the test will not be an assertion, it will be a guess, and may generate low-frequency, hard-to-reproduce failures... <b><font color=#800000>flakiness!</font></b> Class loading and garbage collection pauses, for example, can influence this.</li></ol><br /><b><font color=#800000>Is <font face="courier new, monospace">System.currentTimeMillis()</font>, starting to look a bit like a random number provider?</font></b> That's because it is! The current time is yet another source of <i>non-determinism</i>; the results of <b><font face="courier new, monospace">nextMinuteFromNow()</font></b> cannot be easily determined from its inputs. Fortunately, this is easy to solve: make the current time an input parameter which you can control.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">public Date <b>minuteAfter(Date now)</b> {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;Date then = new Date(<b>now.getTime()</b> + 60000);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;then.setSeconds(0);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;then.setMilliseconds(0);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;return then;</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">// Retain original functionality</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;"><b>@Deprecated</b> public Date <b>nextMinuteFromNow()</b> {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;return <b>minuteAfter(new Date(System.currentTimeMillis()))</b>;</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /></p><br />Writing tests for <b><font face="courier new, monospace">minuteAfter()</font></b> is a much easier task than writing tests for <b><font face="courier new, monospace">nextMinuteFromNow()</font></b>:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:80%;">public void testMinuteAfter () {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size: 80%;">&nbsp;&nbsp;Date now = stringToDate("2012-12-22 11:59:59.999PM");</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size: 80%;">&nbsp;&nbsp;Date then = minuteAfter(now);</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size: 80%;">&nbsp;&nbsp;assertEquals("2012-12-23 12:00:00.000AM", dateToString(then));</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size: 80%;">}</span></span><br /></p><br />This is just one way to solve this problem. Dependency Injection and mutable Singletons can also be used.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-04-03.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-248730134593915045?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-time-is-random/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: TestNG on the Toilet</title>
		<link>https://googledata.org/google-testing/tott-testng-on-the-toilet/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-testng-on-the-toilet</link>
		<comments>https://googledata.org/google-testing/tott-testng-on-the-toilet/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 16:34:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Recently, somewhere in the Caribbean Sea, you implemented the PirateShip class. You want to test the cannons thoroughly in preparation for a clash with the East India Company. This requires that you run the crucial testFireCannonDepletesAmmunition() me...]]></description>
				<content:encoded><![CDATA[Recently, somewhere in the Caribbean Sea, you implemented the PirateShip class. You want to test the cannons thoroughly in preparation for a clash with the East India Company. This requires that you run the crucial <font face="courier new, monospace"><b>testFireCannonDepletesAmmunition()</font></b> method many times with many different inputs. <br /><br /><b><font color=#800000>TestNG</font></b> is a test framework for Java unit tests that offers <b><font color=#800000>additional power and ease of use</font></b> over JUnit. Some of TestNG's features will help you to write your PirateShip tests in such a way that you'll be well prepared to take on the Admiral. First is the <font face="courier new, monospace" color=#800000><b>@DataProvider</font></b> annotation, which allows you to add parameters to a test method and provide argument values to it from a data provider.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size:80%;">public class PirateShipTest {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;<b><font color=#800000>@Test(dataProvider = "cannons")</font></b></span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;public void testFireCannonDepletesAmmunition(int ballsToLoad,</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ballsToFire,</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int expectedRemaining) {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;PirateShip ship = new PirateShip("The Black Pearl");</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;ship.loadCannons(ballsToLoad);</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < ballsToFire; i++) {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ship.fireCannon();</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(ship.getBallsRemaining(), expectedRemaining);</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;<b><font color=#800000>@DataProvider(name = "cannons")</font></b></span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;public Object[][] getShipSidesAndAmmunition() {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;// Each 1-D array represents a single execution of a @Test that</span> <br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;// refers to this provider. The elements in the array represent</span> <br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;// parameters to the test call.</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;return new Object[] {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{5, 1, 4}, {5, 5, 0}, {5, 0, 5}</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;&nbsp;&nbsp;};</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;}</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">}</span><br /></p><br />Now let's focus on making the entire test suite run faster. An old, experienced pirate draws your attention to TestNG's capacity for running tests in parallel. You can do this in the definition of your test suite (described in an XML file) with the <font face="courier new, monospace" color=#800000><b>parallel</b></font> and <font face="courier new, monospace" color=#800000><b>thread-count</b></font> attributes.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size: 80%;">&lt;suite name="PirateShip suite" <b><font color=#800000>parallel="methods" thread-count="2"</font></b>&gt;</span><br /></p><br />A great pirate will realize that this parallelization can also help to expose race conditions in the methods under test.<br />Now you have confidence that your cannons fired in parallel will work correctly. But you didn't get to be a Captain by slacking off! You know that it's also important for your code to fail as expected. For this, TestNG offers the ability to specify those exceptions (and only those exceptions) that you expect your code to throw.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace; font-size: 80%;"><b><font color=#800000>@Test(expectedExceptions = { NoAmmunitionException.class })</font></b></span><br /><span style="font-family:courier new, monospace; font-size: 80%;">public void testFireCannonEmptyThrowsNoAmmunitionException() {</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;PirateShip ship = new PirateShip("The Black Pearl");</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">&nbsp;&nbsp;ship.fireCannon();</span><br /><span style="font-family:courier new, monospace; font-size: 80%;">}</span><br /></p><br /><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-03-20.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-2600172139710705749?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-testng-on-the-toilet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Understanding Your Coverage Data</title>
		<link>https://googledata.org/google-testing/tott-understanding-your-coverage-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-understanding-your-coverage-data</link>
		<comments>https://googledata.org/google-testing/tott-understanding-your-coverage-data/#comments</comments>
		<pubDate>Thu, 06 Mar 2008 16:17:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Code coverage (also called test coverage) measures which lines of source code have been executed by tests. A common misunderstanding of code coverage data is the belief that:My source code has a high percentage of code coverage; therefore, my code is w...]]></description>
				<content:encoded><![CDATA[<b><font color=#800000>Code coverage</font></b> (also called test coverage) measures which lines of source code have been executed by tests. A <b><font color=#800000>common misunderstanding</font></b> of code coverage data is the belief that:<br /><br /><center><i><font color=#800000>My source code has a high percentage of code coverage; therefore, my code is well-tested.</font></i></center><br /><br />The above statement is <b><font color=#800000>FALSE</font></b>! High coverage is a necessary, but not sufficient, condition.<br /><br /><center><p><b><font color=#800000>Well-tested code&nbsp;=======&gt;&nbsp;High coverage</font></b>   <br /><b><font color=#800000>Well-tested code&nbsp;&lt;===X===&nbsp;High coverage</font></b></p></center><br />The most common type of coverage data collected is statement coverage. It is the least expensive type to collect, and the most intuitive. Statement coverage measures whether a particular line of code is ever reached by tests. Statement coverage does not measure the percentage of unique execution paths exercised.<br /><br /><b><font color=#800000>Limitations of statement coverage</font></b>:<br /><ul><br /><li>It does not take into account all the possible data inputs. Consider this code:<br /> <br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">int a = b / c;</span></span><br /></p><br />This could be covered with <font face="Courier New, monospace">b = 18</font> and <font face="Courier New, monospace">c = 6</font>, but never tested where <font face="Courier New, monospace">c = 0</font>.</li><br /><li>Some tools do not provide fractional coverage. For instance, in the following code, when condition a is true, the code already has 100% coverage. Condition b is not evaluated.<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">if (a || b) {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;// do something</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /></p></li><br /><li>Coverage analysis can only tell you how the code that exists has been exercised. It cannot tell you how code that <i>ought</i> to exist would have been executed. Consider the following:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">error_code = FunctionCall();</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:80%;">// returns kFatalError, kRecoverableError, or kSuccess</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">if (error_code == kFatalError) {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;// handle fatal error, exit</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">} else {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;// assume call succeeded</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /></p><br /><br />This code is only handling two out of the three possible return values (a bug!). It is missing code to do error recovery when <font face="Courier New, monospace">kRecoverableError</font> is returned. With tests that generate only the values <font face="Courier New, monospace">kFatalError</font> and <font face="Courier New, monospace">kSuccess</font>, you will see 100% coverage. The test case for <font face="Courier New, monospace">kRecoverableError</font> does not increase coverage, and appears “redundant” for coverage purposes, but it exposes the bug!<br /></li></ul><br />So the <b><font color=#800000>correct way to do coverage analysis</font></b> is:<br /><ol><br /><li>Make your tests as comprehensive as you can, without coverage in mind. This means writing as many test case as are necessary, not just the minimum set of test cases to achieve maximum coverage.</li><br /><li>Check coverage results from your tests. Find code that's missed in your testing. Also look for unexpected coverage patterns, which usually indicate bugs.</li><br /><li>Add additional test cases to address the missed cases you found in step 2.</li><br /><li>Repeat step 2-3 until it's no longer cost effective. If it is too difficult to test some of the corner cases, you may want to consider refactoring to improve testability.</li><br /></ol><br /><i><span stype="font-size:50%;">Reference for this episode: <a href="http://www.testing.com/writings/coverage.pdf">How to Misuse Code Coverage</a> by Brian Marick from Testing Foundations.</span></i><br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-03-06.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-1056315837586430730?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-understanding-your-coverage-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: Too Many Tests</title>
		<link>https://googledata.org/google-testing/tott-too-many-tests/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-too-many-tests</link>
		<comments>https://googledata.org/google-testing/tott-too-many-tests/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 17:58:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[In the movie Amadeus, the Austrian Emperor criticizes Mozart's music as having “too many notes.” How many tests are “too many” to test one function?Consider the method decide:public void decide(int a, int b, int c, int d, &#160;&#160;&#160;&#038;nbs...]]></description>
				<content:encoded><![CDATA[In the movie <i><b>Amadeus</b>,</i> the Austrian Emperor criticizes Mozart's music as having “too many notes.” How many tests are “too many” to test one function?<br /><br />Consider the method <font face="Courier New, monospace">decide</font>:<br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">public void decide(int a, int b, int c, int d, </span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int e, int f) {</span ><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;if (a &gt; b || c &gt; d || e &gt; f) {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;DoOneThing();</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;} else {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;DoAnother();</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;} // One-letter variable names are used here only</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;because of limited space.</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">} // You should use better names. Do as I say, not</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as I do. :-)</span></span><br /></p><br />How many tests could we write? Exercising the full range of int values for each of the variables would require <b><font color=#800000>2<sup>192</sup> tests</font></b>. We'd have googols of tests if we did this all the time! <b><font color=#800000>Too many tests.</font></b> <br /><br />What is the fewest number of tests we could write, and still get every line executed? This would achieve 100% <font color=#000000><b>line coverage</b></font>, which is the criterion most code-coverage tools measure. <b><font color=#800000>Two tests</font></b>. One where <font face="courier new, monospace">(a &gt; b || c &gt; d || e &gt; f)</font> is true; one where it is false. <b><font color=#800000>Not enough tests to detect most bugs</font></b> or unintentional changes in the code.<br /><br />How many tests to test the logical expression and its sub-expressions? If you write a test of <font face="Courier New, monospace">decide</font> where <font face="Courier New, monospace">a == b</font>, you might find that the sub-expression <font face="Courier New, monospace">a &gt; b</font> was incorrect and the code should have been <font face="Courier New, monospace">a &gt;= b</font>. And it might make sense to also run tests where <font face="Courier New, monospace">a &lt; b</font> and  <font face="Courier New, monospace">a &gt; b</font>. So that's three tests for <font face="Courier New, monospace">a</font> compared to <font face="Courier New, monospace">b</font>. For all of the parameters, that would <b><font color=#800000>3 * 3 * 3 = 27 tests. That's probably too many.</font></b><br /><br />How many tests to test the logical expression and its sub-expressions independently? Consider another version of <font face="Courier New, monospace">decide</font>, where the logical sub-expressions have been extracted out:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style="font-family:courier new, monospace;"><span style="font-size:100%;">public void decide(int a, int b, int c, int d,</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int e, int f) {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;if (tallerThan(a, b)</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| harderThan(c, d)</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| heavierThan(e, f)) {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;DoOneThing();</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;} else {</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;DoAnother();</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;}</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">}</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">boolean tallerThan(int a, int b) { return a &gt; b; }</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Note “package scope”</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">boolean harderThan(int c, int d) { return c &gt; d; }</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// rather than public; JUnit</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">boolean heavierThan(int e, int f) { return e &gt; f; }</span></span><br /><span style="font-family:courier new, monospace;"><span style="font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// tests can access these.</span></span><br /></p><br /><br />We can write four tests for <font face="Courier New, monospace">decide</font>.  One where <font face="courier new, monospace">tallerThan</font> is true. One where <font face="courier new, monospace">harderThan</font> is true. One where <font face="courier new, monospace">heavierThan</font> is true. And one where they are all false. We could test each of the extracted functions with two tests, so the total would be <b><font color=#800000>4 + 2 * 3 = 10 tests</font></b>. This would be  <b><font color=#800000>just enough tests</font></b> so that most unintentional changes will trigger a test failure. Exposing the internals this way trades <b><font color=#800000>decreased encapsulation</font></b> for <b><font color=#800000>increased testability.</font></b> Limit the exposure by controlling scope appropriately, as we did in the Java code above.<br /><br />How many tests is too many? The answer is “It depends.” It depends on how much confidence the tests can provide in the face of changes made by others. Tests can detect whether a programmer changed some code in error, and can serve as examples and documentation. <b><font color=#800000>Don't write redundant tests, and don't write too few tests.</font></b><br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-02-21.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-5013773056033739556?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-too-many-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TotT: The Stroop Effect</title>
		<link>https://googledata.org/google-testing/tott-the-stroop-effect/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tott-the-stroop-effect</link>
		<comments>https://googledata.org/google-testing/tott-the-stroop-effect/#comments</comments>
		<pubDate>Thu, 07 Feb 2008 08:00:00 +0000</pubDate>
		<dc:creator><![CDATA[dastels]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[How quickly can you...  ...read all 25 words out loud: RED, GREEN, BLUE, ...  (Try it now!) ...say all 25 colors out loud: GREEN, YELLOW, WHITE... (Try it now!) Did the second task require more time and effort? If so, you're experiencing the Stroop Eff...]]></description>
				<content:encoded><![CDATA[<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lUDLhPj-dyg/R6q9nJ4xiwI/AAAAAAAAAAU/Qjunuuzo8QE/s1600-h/The_Stoop_Effect.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_lUDLhPj-dyg/R6q9nJ4xiwI/AAAAAAAAAAU/Qjunuuzo8QE/s400/The_Stoop_Effect.gif" alt="" id="BLOGGER_PHOTO_ID_5164148403100289794" border="0" /></a><br />How quickly can you... <ol> <li>...read all 25 <b>words</b> out loud: RED, GREEN, BLUE, ...  (Try it now!) </li><br /><li>...say all 25 <b>colors</b> out loud: GREEN, YELLOW, WHITE... (Try it now!)</li> </ol><br />Did the second task require more time and effort? If so, you're experiencing the <b>Stroop Effect</b>, which roughly says that when a <i>label</i> (in this case, the word) is in the same domain as its <i>content</i> (the color) with a conflicting meaning, the label interferes with your ability to comprehend the content.<br /><br />What does this have to do with testing? Consider the following code:<br /><br /><p style="border: 1px solid rgb(128, 128, 128); padding: 0.1in; background: rgb(255, 255, 204) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 0.39in; margin-right: 0.39in; margin-bottom: 0pt;"><span style="font-family:courier new,monospace;"><span style="font-size:80%;">public void testProtanopiaColorMatcherIsDistinguishable() {</span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:80%;">&nbsp;&nbsp;ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA);</span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:80%;">&nbsp;&nbsp;<b>assertFalse(“BLUE and VIOLET are indistinguishable”,</b></span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:80%;">&nbsp;&nbsp;&nbsp;&nbsp;<b>colorMatcher.isDistinguishable(Color.BLUE, Color.VIOLET));</b></span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:80%;">}</span></span></p><br />When this test fails, it produces a message like this:<br /><br /><p style="border: 1px solid rgb(128, 128, 128); padding: 0.1in; background: rgb(255, 255, 204) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 0.39in; margin-right: 0.39in; margin-bottom: 0pt;"><span style="font-family:courier new,monospace;"><span style="font-size:75%;"><b>Failure: testProtanopiaColorMatcherIsDistinguishable:</b></span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:75%;"><b>Message: BLUE and VIOLET are indistinguishable</b></span></span><br /></p><br />Quick: what caused this error? Were BLUE and VIOLET indistinguishable, or not? If you're hesitating, that's the Stroop Effect at work! The <i>label</i> (the message) expresses a truth condition, but the <i>content</i> (in <i><span style="font-size:100%;"><span style="font-family:courier new,monospace;">assertFalse</span></span></i>) expresses a false condition. Is the ColorMatcher doing the wrong thing, or is the test condition bogus? This message is wasting your valuable time! Now consider this slight alteration to the test name and test message:<br /><br /><p style="border: 1px solid rgb(128, 128, 128); padding: 0.1in; background: rgb(255, 255, 204) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 0.39in; margin-right: 0.39in; margin-bottom: 0pt;"><span style="font-family:courier new,monospace;"><span style="font-size:75%;"><b>Failure: testProtanopiaColorMatcherCannotDistinguishBetweenCertainPairsOfColors</b></span></span><br /><span style="font-family:courier new,monospace;"><span style="font-size:75%;"><b>Message: BLUE and VIOLET should be indistinguishable</b></span></span><br /></p><br />Do you find this clearer? Protanopia (reduced sensitivity to the red spectrum) causes certain pairs of colors to be indistinguishable. BLUE and VIOLET <i>should</i> have been indistinguishable, but <i>weren't</i>.<br /><br />Here are some things to keep in mind when writing your tests:<br /><ul><li> When someone breaks your test – will your test name and message be useful to them?</li><br /><li>Opinionated test names like <i><span style="font-family:courier new,monospace;">testMethodDoesSomething</span></i> can be more helpful than <i><span style="font-family:courier new,monospace;">testMethod</span></i>.</li><br /><li>Great test messages not only identify the actual behavior,but also the expected behavior.</li><br /><li><b>Should</b> is a handy word to use in messages – it clarifies what <b>expected</b> behavior didn't <b>actually</b> happen.</li><br /></ul><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-02-07.pdf">this episode</a> of Testing on the Toilet and post it in your office.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15045980-1552441790570539967?l=googletesting.blogspot.com' alt='' /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/tott-the-stroop-effect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
	</channel>
</rss>
