<?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>Test Driven Databases</title>
	<atom:link href="http://www.testdrivendatabases.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.testdrivendatabases.com</link>
	<description></description>
	<lastBuildDate>Thu, 01 Mar 2012 17:43:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Thwarting Database Defects at SQLCambs 2011-11-21</title>
		<link>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlcambs-2011-11-21/</link>
		<comments>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlcambs-2011-11-21/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 19:15:22 +0000</pubDate>
		<dc:creator>theadmin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=168</guid>
		<description><![CDATA[When: Saturday, November 21st 18:00 &#8211; 21:00 GMT <p>Presenters: Sebastian Meine and Dennis Lloyd</p> <p>Topic: TDD – Thwarting Database Defects It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect [...]]]></description>
			<content:encoded><![CDATA[<h2><span style="font-size: 13px;font-weight: normal"><strong>When:</strong> Saturday, November 21st 18:00 &#8211; 21:00 GMT</span></h2>
<p><strong>Presenters:</strong> Sebastian Meine and Dennis Lloyd</p>
<p><strong>Topic: TDD – Thwarting Database Defects</strong><br />
It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect causes the end-user to make a bad decision. Database defects are far too costly and most testing practices do not adequately detect or prevent them. This presentation introduces <a title="tSQLt" href="http://tsqlt.org">tSQLt</a>, a framework for automated database unit testing. You’ll learn techniques to write SQL code that is resilient to defects and is easier to change and maintain.</p>
<p><strong>Location:</strong><br />
Red Gate Software Ltd.<br />
Newnham House<br />
Cambridge Business Park<br />
CB4 0WZ Cambridge<br />
United Kingdom </p>
<p><strong>More Details and Registration:</strong> <a title="Cambridgeshire SQL Server User Group" href="http://sqlcambs.org.uk/">Cambridgeshire SQL Server User Group</a></p>
<p>&nbsp;</p>
<p><strong>Resources:</strong></p>
<p>tSQLt Website: <a href="http://tSQLt.org">http://tSQLt.org</a></p>
<p>tSQLt Mailing List: <a href="http://groups.google.com/group/tsqlt">tsqlt@googlegroups.com</a></p>
<p>sqlity.net Webstie: <a href="http://sqlity.net">http://sqlity.net</a></p>
<p>Curiously Correct Website: <a href="http://curiouslycorrect.com">http://curiouslycorrect.com</a></p>
<p>&nbsp;<br />
Download course content here: <a href="http://www.curiouslycorrect.com/download/ThwartingDatabaseDefects.zip" title="Download Presentation Content">Thwarting Database Defects Class Distribution &#8211; Includes slides and examples</a><br />
&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlcambs-2011-11-21/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thwarting Database Defects at SQLSaturday #96 Washington DC 2011-11-05</title>
		<link>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlsaturday-96-washington-dc-2011-11-05/</link>
		<comments>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlsaturday-96-washington-dc-2011-11-05/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 15:57:37 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=156</guid>
		<description><![CDATA[When: Saturday, November 5th 12:00pm &#8211; 1:00pm <p>Presenters: Sebastian Meine and Dennis Lloyd</p> <p>Topic: TDD – Thwarting Database Defects It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect causes [...]]]></description>
			<content:encoded><![CDATA[<h2><span style="font-size: 13px;font-weight: normal"><strong>When:</strong> Saturday, November 5th 12:00pm &#8211; 1:00pm</span></h2>
<p><strong>Presenters:</strong> Sebastian Meine and Dennis Lloyd</p>
<p><strong>Topic: TDD – Thwarting Database Defects</strong><br />
It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect causes the end-user to make a bad decision. Database defects are far too costly and most testing practices do not adequately detect or prevent them. This presentation introduces <a title="tSQLt" href="http://tsqlt.org">tSQLt</a>, a framework for automated database unit testing. You’ll learn techniques to write SQL code that is resilient to defects and is easier to change and maintain.</p>
<p><strong>Location:</strong><br />
The Microsoft Technology Center<br />
5404 Wisconsin Ave, Suite 700<br />
Chevy Chase, MD, 20815</p>
<p><strong>More Details and Registration:</strong> <a title="SQLSaturday #96 Washington DC" href="http://www.sqlsaturday.com/96/eventhome.aspx">SQLSaturday #96 Washington DC</a></p>
<p>&nbsp;</p>
<p><strong>Resources:</strong></p>
<p>tSQLt Website: <a href="http://tSQLt.org">http://tSQLt.org</a></p>
<p>tSQLt Mailing List: <a href="http://groups.google.com/group/tsqlt">tsqlt@googlegroups.com</a></p>
<p>sqlity.net Webstie: <a href="http://sqlity.net">http://sqlity.net</a></p>
<p>Curiously Correct Website: <a href="http://curiouslycorrect.com">http://curiouslycorrect.com</a></p>
<p>&nbsp;<br />
Download course content here: <a href="http://www.curiouslycorrect.com/download/ThwartingDatabaseDefects.zip" title="Download Presentation Content">Thwarting Database Defects Class Distribution &#8211; Includes slides and examples</a><br />
&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/thwarting-database-defects-at-sqlsaturday-96-washington-dc-2011-11-05/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boundary Test Cases</title>
		<link>http://www.testdrivendatabases.com/boundary-test-cases/</link>
		<comments>http://www.testdrivendatabases.com/boundary-test-cases/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 20:44:41 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=125</guid>
		<description><![CDATA[<p>This is the first post on a series of test case heuristics. Test case heuristics patterns used to help decide the next test to write and ensure test coverage of requirements.</p> <p>&#160;</p> Definition: <p class="wp-caption-text">Checkered garden at Jardín Japonés in Buenos Aires Argentina</p> <p>The boundary test heuristic applies to requirements which specify different behavior [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first post on a series of <a href="http://www.testdrivendatabases.com/test-heuristics/" title="Test Case Heuristics">test case heuristics</a>. Test case heuristics patterns used to help decide the next test to write and ensure test coverage of requirements.</p>
<p>&nbsp;</p>
<h3>Definition:</h3>
<div class="wp-caption alignright" style="width: 510px"><img src="http://www.testdrivendatabases.com/wp-content/uploads/2011/10/BoundaryTesting.jpg" alt="BoundaryTesting Boundary Test Cases" width="500" height="375" title="Boundary Test Cases" /><p class="wp-caption-text">Checkered garden at Jardín Japonés in Buenos Aires Argentina</p></div>
<p>The boundary test heuristic applies to requirements which specify different behavior on either side of a particular value (called a boundary value) within a range of values.</p>
<p>For example, a requirement specifies that more inventory should be ordered if the number of units in the warehouse drops below 50. In this case, 50 is a boundary value.</p>
<p>A requirement often has several boundary values (see example below). The range of values on either side of a boundary value (or in between two boundary values) is called a partition.</p>
<p>The boundary test heuristic says that at least one test case should exist for each boundary value and each partition. It is useful to pick values very close to the boundary value to ensure that the code specifies the proper condition.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Purpose:</h3>
<p>Boundary testing helps:</p>
<ul>
<li>Clarify and identify gaps in the requirements</li>
<li>Provide coverage for conditional statements</li>
<li>Prevent mistakes arising from using the wrong comparison operator (e.g. coding “&lt;”, when “&lt;=” was intended).</li>
</ul>
<p>&nbsp;</p>
<h3>Example:</h3>
<p>The business sets the following discount structure to encourage higher sales:</p>
<ul>
<li>If the order total is between $50 and $100 then a 5% discount is applied.</li>
<li>If the order total is more than $100 and less than $200 then a 10% discount is applied.</li>
<li>If the order total is more than $200 than a 15% discount is applied.</li>
</ul>
<p>&nbsp;</p>
<p>This requirement specifies three boundaries: $50, $100, and $200. There are four partitions.</p>
<pre>&lt;--------------|-----------------|---------------|--------------&gt;
    par 1      50     par 2     100   part 3    200    par 4</pre>
<p>&nbsp;</p>
<p>As we choose certain test cases, we are forced to ask certain clarifying questions, such as:</p>
<ul>
<li>$49.99: What should happen when the order total is less than $50. The requirement didn&#8217;t say.</li>
<li>$50.00: When the requirement says “between”, did the they mean to include or exclude $50 and $100.00. The word “between” can mean different things in regards to including the end points.</li>
<li>$200.00: The requirement doesn&#8217;t say what happens if the order total is $200.</li>
</ul>
<p>&nbsp;</p>
<p>Notice that the number of decimal places is important. The value $49.99 was chosen above because we&#8217;re dealing with a monetary value. However, in another context, a different number of decimal places may be relevant.</p>
<p>&nbsp;</p>
<h3>Special Cases:</h3>
<p><strong>Null:</strong> While null is not truly a boundary value, it is a special value in most languages (particularly SQL).</p>
<p><strong>Relative boundaries:</strong> Many times a boundary is specified in terms of another input. For example, return (2 * x) if x &gt; y. In this case, y is a boundary value.</p>
<p><strong>Dates and times:</strong> Boundary testing for dates and times must take into account the precision of the value (e.g. Is it a date only? Are hours and minutes relevant? How about seconds or milliseconds?). Dates and times are often used with relative boundaries. For example, a citizen is allowed to vote if they are at least 18 years old; the boundary (18 years) is relative to the citizen&#8217;s date of birth.</p>
<p><strong>Boundaries on multiple inputs:</strong> Sometimes a requirement will specify boundary values on a variety of inputs. For example, a patient should be admitted if their respiratory rate is &gt;= 30 and their age is &gt;= 65. Combining boundary testing and all-pairs testing can be extremely valuable in coming up with appropriate tests when there are many inputs.</p>
<p><strong>Output boundaries:</strong> Sometimes boundaries will be specified as part of a required output. This is often the case for a non-deterministic process. For example, a player will receive a random prize between $50 and $100.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/boundary-test-cases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nine Ways to Prevent Defects</title>
		<link>http://www.testdrivendatabases.com/nine-ways-to-prevent-defects/</link>
		<comments>http://www.testdrivendatabases.com/nine-ways-to-prevent-defects/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 20:16:51 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=118</guid>
		<description><![CDATA[<p>As a quick treat for today, here&#8217;s a list of nine useful ways to prevent defects in applications.</p> Pair Programming and Testing: Two heads are better than one when writing software. Pairing enables programmers to discuss and react to potential defects as the code is being written. By combining their experience, the programmers are [...]]]></description>
			<content:encoded><![CDATA[<p>As a quick treat for today, here&#8217;s a list of nine useful ways to prevent defects in applications.</p>
<ol>
<li>Pair Programming and Testing: Two heads are better than one when writing software. Pairing enables programmers to discuss and react to potential defects as the code is being written. By combining their experience, the programmers are more likely to recognize a problem situation or an opportunity for a new test.</li>
<li>Test Driven Development (TDD): Creating tests and code in tandem results in substantially higher test coverage. TDD also helps evolve the code into smaller, more flexible modules.</li>
<li>Code Reviews: Pair Programming is one method of on-the-fly code review. Additional code reviews can be useful for knowledge sharing and defect prevention. This can be accomplished through on- or off-line code reviews, or by changing who you pair with throughout an iteration. I prefer to change who I work with throughout an iteration as it provides the opportunity to learn not just what others are working on, but how they approach problem solving.</li>
<li>Static Analysis: Static analysis tools automatically look for common defects by reading the code (instead of executing the code). Some defects are easier to find through static analysis than by testing (and vice-versus).</li>
<li>Stop-The-Line Mindset: The stop-the-line mindset says that once a defect is discovered, new production stops until the defect is understood, corrected and prevented from ever happening again. This involves creating tests around the fix, looking for similar problems in the application code and asking how this defect could be prevented in the future.</li>
<li>Exploratory Testing: Exploratory testing is not “random, hacking around in the system hoping to find a bug”. Instead, it is a process through which the tester maps the behavior of the system utilizing heuristics, knowledge of the system and intuition to discover both defects and opportunities for new features.</li>
<li>Risk Analysis: We want to look for areas where the code is most likely to have defects. There are several questions I consider when deciding where to look for defects:
<ol>
<li>What parts of the code are being updated for frequently for defects? Defects like to hang out together. If you find one, you&#8217;ll probably find several more. If there are areas of the code that are constantly being patched, these areas should get immediate attention.</li>
<li>What parts of the code are most complex? Complex code is a nesting ground for defects. It is harder to read, harder to test, and harder to make changes. Using a complexity metric can help identify risky areas.</li>
<li>What parts of the code are not currently well tested? Untested parts of the code are likely to have defects.</li>
</ol>
</li>
<li>Duplicate Code Detection: Duplicated code makes changes more difficult and defects more likely because it raises questions such as: “Are there any other places where I need to make this same change?”, “Is this change appropriate in all places that have this same code?”. Development teams will often forget or be unaware of all the places a change needs to be made. Tools exist for detecting duplicate code in many languages.</li>
<li>Continuous Integration: Building the entire code base and executing test suites on a frequent basis makes it harder to ignore or forget a defect.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/nine-ways-to-prevent-defects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thwarting Database Defects at NJ SQL Server Users Group 2011-10-18</title>
		<link>http://www.testdrivendatabases.com/thwarting-database-defects-at-nj-sql-server-users-group-2011-10-18/</link>
		<comments>http://www.testdrivendatabases.com/thwarting-database-defects-at-nj-sql-server-users-group-2011-10-18/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 15:49:44 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=76</guid>
		<description><![CDATA[When: Tuesday, October 18th 6:00pm &#8211; 8:30pm <p>Presenters: Sebastian Meine and Dennis Lloyd</p> <p>Topic: TDD – Thwarting Database Defects It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect causes [...]]]></description>
			<content:encoded><![CDATA[<h2><span style="font-size: 13px;font-weight: normal"><strong>When:</strong> Tuesday, October 18th 6:00pm &#8211; 8:30pm</span></h2>
<p><strong>Presenters:</strong> Sebastian Meine and Dennis Lloyd</p>
<p><strong>Topic: TDD – Thwarting Database Defects</strong><br />
It’s bad enough to spend hours finding and fixing database defects, explaining to the rest of the team what went wrong and trying to clean up the mess. It’s even worse when a defect causes the end-user to make a bad decision. Database defects are far too costly and most testing practices do not adequately detect or prevent them. This presentation introduces <a title="tSQLt" href="http://tsqlt.org">tSQLt</a>, a framework for automated database unit testing. You’ll learn techniques to write SQL code that is resilient to defects and is easier to change and maintain.</p>
<p><strong>Location:</strong><br />
SetFocus<br />
4 Century Drive<br />
Parsippany , NJ</p>
<p><strong>More Details and Registration:</strong> <a title="NJ SQL Server Users Group" href="http://njsql.org">njsql.org</a></p>
<p>&nbsp;</p>
<p><strong>Resources:</strong></p>
<p>tSQLt Website: <a href="http://tSQLt.org">http://tSQLt.org</a></p>
<p>tSQLt Mailing List: <a href="http://groups.google.com/group/tsqlt">tsqlt@googlegroups.com</a></p>
<p>sqlity.net Webstie: <a href="http://sqlity.net">http://sqlity.net</a></p>
<p>Curiously Correct Website: <a href="http://curiouslycorrect.com">http://curiouslycorrect.com</a></p>
<p>&nbsp;<br />
Download course content here: <a href="http://www.curiouslycorrect.com/download/ThwartingDatabaseDefects.zip" title="Download Presentation Content">Thwarting Database Defects Class Distribution &#8211; Includes slides and examples</a><br />
&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/thwarting-database-defects-at-nj-sql-server-users-group-2011-10-18/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Driven Development in the Database</title>
		<link>http://www.testdrivendatabases.com/test-driven-development-in-the-database/</link>
		<comments>http://www.testdrivendatabases.com/test-driven-development-in-the-database/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 15:59:36 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=64</guid>
		<description><![CDATA[<p> Test Driven Development (TDD) is an Agile development process which improves the overall design, quality and maintainability of software. At it&#8217;s simplest, TDD is the practice of: 1) writing a small test, 2) checking that it fails, 3) writing just enough code to make it pass, 4) improving the design of the code [...]]]></description>
			<content:encoded><![CDATA[<p>
Test Driven Development (TDD) is an Agile development process which improves the overall design, quality and maintainability of software. At it&#8217;s simplest, TDD is the practice of: 1) writing a small test, 2) checking that it fails, 3) writing just enough code to make it pass, 4) improving the design of the code and then, 5) starting over by writing the next test. This is sometimes referred to as the test-code-refactor cycle. It provides the ability to define requirements without vagueness, the ability to design software so that it is decoupled and flexible, and a framework for writing well tested code.
</p>
<p>
However, practitioners must understand that TDD does not solve all development problems and therefore should be implemented within a framework of supporting processes. TDD additionally affects the development process while gathering requirements, checking-in source code, creating software packages for deployment, testing the software, and deploying software to production.
</p>
<p>
Development teams often run into common problems when they first attempt to implement TDD in the database. Teams are more successful when they have an experienced coach to help them through the challenges. Among the challenges most often experienced are:
</p>
<ul>
<li>Creating test data in a way that is flexible and maintainable</li>
<li>Keeping test cases independent of one another</li>
<li>Dealing with database constraints such as checks and foreign keys</li>
<li>Keeping code clean, testable and fast</li>
<li>Knowing the limits of TDD and the supporting skills to make it work</li>
<li>Avoiding defaulting back to non-TDD practices when the pressure to deliver rises</li>
<li>Understanding how to get started with TDD when software already exists</li>
<li>Fitting TDD into the overall development process, especially in terms of its affects on requirements elicitation and quality assurance</li>
<li>Implementing and testing data migrations</li>
</ul>
<p>
These challenges are surmountable. We have been there and have helped teams succeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/test-driven-development-in-the-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Identifying Test Cases #3</title>
		<link>http://www.testdrivendatabases.com/identifying-test-cases-3/</link>
		<comments>http://www.testdrivendatabases.com/identifying-test-cases-3/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:21:49 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=10</guid>
		<description><![CDATA[<p>Review In the previous two posts, we discussed some ways to look at code and pick out the test cases. These included finding the boundary test cases, input and output classes and special value testing. This time we&#8217;re going to take a departure and discuss specific practices which will help you creatively find more [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Review</strong><br />
In the  previous two posts, we discussed some ways to look at code and pick out  the test cases. These included finding the boundary test cases, input  and output classes and special value testing. This time we&#8217;re going to  take a departure and discuss specific practices which will help you  creatively find more test cases. When used with existing code, many of  them can quickly flush out defects. When used while writing code, they  can dramatically reduce the number of defects from being written in the  first place.</p>
<p><strong>Pairing</strong><br />
Pairing is  the practice of two people collaborating on a single task, together and  at the same time. Working side-by-side and at the same time is important  as it greatly increases the richness and efficiency of communication.</p>
<p>With two minds focused on the work, a  creative conversation ensues as the pair identifies test cases. Working  with a pair can not just double the number of test cases found, but can  uncover brand new directions in which to test. Pairing can take the form  of pair-programming, pair-testing or even be used during requirements  elicitation. By mixing and matching who you pair with, you can learn a  great deal about finding new test cases, the functionality and design of  the system, and the desired system behavior.</p>
<p>While pairing, remember to keep an  open-mind about new approaches and be willing to share your take on the  solution. It is important for both members to remain engaged in the work  being performed. So eliminate distractions by turning off e-mail and  cell phones and making sure you each have a period of dedicated time in  which to work.</p>
<p>For an additional perspective on pairing  for testing, check out this article by Jonathan Kohl which was  published in Better Software:<a href="http://www.kohl.ca/articles/pairtesting.html">&#8220;Pair Testing: How I Brought Developers into the Test Lab&#8221;</a></p>
<p><strong>Test-storming and the testing notebook</strong><br />
At  the beginning of a programming or testing session, I like to discuss  with my pair what we&#8217;re about to build or test. I then suggest we enter  into brain-storming mode about potential test cases. During development,  this gives us a better understanding of what we&#8217;re going to build and  creates awareness of corner cases and exceptions as we code. In  exploratory testing sessions, this serves to give a little structure and  planning to the session. In both development and testing, we reserve  the right to deviate from the plan created by this initial  test-storming. The purpose of test-storming is to generate  understanding, initiate some creative thinking and have a mini-plan of  attack.</p>
<p>Test-storming ideas are recorded in a  notebook (or on index cards) so that we don&#8217;t loose the ideas, and can  refer back during the session. I don&#8217;t use any particular format or  standard for this as different problem spaces benefit from different  note taking styles. For example, some times I test-storm with a truth  table, a time line, a decision tree or a diagram. Often I use a few of  these in combination during each session. I practice no particular  formality to this &#8211; any ceremony defeats the point of quickly generating  test scenarios.</p>
<p>I keep the notebook handy throughout the  session. If a new test case comes to mind while pairing, I quietly  write it down until there is an appropriate time to bring it up. This  keeps the flow going without loosing any good test case ideas.</p>
<p><strong>Test Driven Design</strong><br />
Test-driven development is a technique which follows this micro-process:<br />
1. Write a failing test case &#8211; the smallest, simplest one<br />
2. Write just enough code to make it pass &#8211; and no more<br />
3. Refactor &#8211; improve the code while keeping all the tests passing<br />
4. Repeat at #1</p>
<p>By creating a failing test case first  and only writing enough code to make it pass, we ensure that our code is  fully covered by tests. Furthermore, by writing these automated tests,  we encourage our design to be modular. It is difficult to create a test  case for code that has many hard-coded dependencies. By creating the  test first, we&#8217;ve designed part of the programming interface and the  result will typically be more flexible and extensible. Finally, by  having code which is well-covered by automated tests, we have much  greater confidence in our refactoring.</p>
<p>It is important to realize that the  automated unit tests created by TDD are alone not sufficient for all  software testing. Other approaches are still required in tandem, such as  performance and scalability testing, usability tests, integration  testing and other various forms of testing.</p>
<p>For a deeper discussion of TDD, see <a href="http://www.agiledata.org/essays/tdd.html">Introduction to Test Driven Design (TDD)</a> by Scott Ambler.</p>
<p><strong>All-pairs (also called pairwise testing)</strong><br />
All-pairs  testing is quite different than pair testing. All-pairs testing is a  method of generating test case inputs. Consider, for example, a function  for specifying a car to be purchased with three parameters: color (red,  green, blue, black, white, or silver), transmission (automatic or  manual), and trim (sport, luxury, standard, or special edition). We can  generate test cases by creating various combinations of these  parameters, such as a red-manual-sport or white-manual-standard.</p>
<p>The simplest defects are caused by  coding problems involving a single parameter, while the next simplest  involve the combination of two parameters. All-pairs testing uses an  algorithm to generate test case inputs which include all possible  pairings of the inputs. This is different than generating all possible  combinations of all the inputs. Generating each possible pairing yields  significantly fewer test cases than generating each combination, while  still giving a decent amount of coverage through the code.</p>
<p>It is useful to use a program to  generate the pairwise inputs automatically. James Bach provides a simple  to use all-pairs tool at: <a href="http://www.satisfice.com/tools.shtml">All Pairs Testing Tool</a>. The included .rtf file in the download does an excellent job at describing what the program does and how Allpairs works.</p>
<p><strong>Flash Review</strong><br />
At the  end of a session, I review with my pair what we&#8217;ve covered from our test  notebook. Test cases which we&#8217;ve completed (preferably as automated  tests) are crossed out. We highlight what we need to do next and if we  missed any cases. We think back over what we&#8217;ve just accomplished and  look to see if anything is missing or if there are more test cases to  go. Often we&#8217;ll ask the question &#8211; &#8220;how else can we try to break this  thing?&#8221;. Having a point where we consciously perform a review is useful  because it tends to solidify what we&#8217;ve learned and to discover a few  new things to test.</p>
<p><strong>Wrap-up</strong><br />
So I&#8217;ve  discussed in this post some practices I follow while developing and  testing. These techniques, when combined, have served as a robust way of  preventing and detecting defects.</p>
<p>Now, for homework:<br />
1. Get a test notebook and put it on your desk so that it&#8217;s ready for your next coding or testing session.<br />
2. Try out test-storming and flash review by yourself and with a pair. Note what pairing added to these practices.<br />
3. Get a copy of the All-pairs tool mentioned above and try it out for a few problems which you need to test.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/identifying-test-cases-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pre-populated Test Databases – Part 3</title>
		<link>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-3/</link>
		<comments>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-3/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:19:58 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=40</guid>
		<description><![CDATA[<p>In the first post in this series, I presented several reasons to not us a database pre-populated with data for unit testing. The second post, presented an alternative approach to using a pre-populated database. This post will address the common concerns with the approach.</p> <p>Concern: If we fake the table, we&#8217;re not testing the [...]]]></description>
			<content:encoded><![CDATA[<p>In the first post in this series, I presented several reasons to not us a database pre-populated with data for unit testing. The second post, presented an alternative approach to using a pre-populated database. This post will address the common concerns with the approach.</p>
<p><strong>Concern:</strong> If we fake the table, we&#8217;re not testing the real thing. <strong>The reality:</strong> “Not testing the real thing” is a common argument against any mock framework. Remember, we&#8217;re talking about unit testing – pinpointing a small, specific piece of functionality to exercise. Other forms of testing will cover the entire system as it is integrated together. By focusing on small units, you can achieve higher test coverage. You will also establish a safety-net for refactoring.</p>
<p><strong>Concern: </strong>Constraints need to be tested too. <strong>The reality: </strong>I completely agree. While unit testing, you can write test cases against the constraints. After faking a table, you can re-apply the constraints which you&#8217;d like to test. This actually improves your ability to test the constraints, as you can do so in isolation of other functionality.</p>
<p><strong>Concern: </strong>We need realistic data that we got from the customer. <strong>The reality:</strong> There are times and places to use such data if you  have it. Unit testing is not it. This type of data is better utilized during integration, usability, and performance testing. Using customer data during unit testing will prevent you from thinking about scenarios which don&#8217;t occur now in the data, but may occur later. Defects will hide among those untested scenarios.</p>
<p>&nbsp;</p>
<p>As you become experienced with this approach to unit testing, you will also find the following benefits:</p>
<ol>
<li>Code is less 	coupled.</li>
<li>It is easier 	to test date and time based scenarios.</li>
<li>Your tests 	are not slowed down by having a large amount of data in the 	database.</li>
<li>It is easier 	to version control everything needed for unit testing.</li>
<li>You&#8217;ll 	prevent more defects before integrating the code.</li>
</ol>
<p>&nbsp;</p>
<h2>Other Posts in this Series:</h2>
<p><a title="Pre-populated Test Databases – Part 1" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-1/">Pre-populated Test Databases – Part 1</a></p>
<p><a title="Pre-populated Test Databases – Part 2" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-2/">Pre-populated Test Databases – Part 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pre-populated Test Databases – Part 2</title>
		<link>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-2/</link>
		<comments>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-2/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:18:42 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=26</guid>
		<description><![CDATA[<p>In the previous post on this topic, I gave you some very good reasons to not pre-populate your unit test database. So, the burning question is, where should test data come from?</p> <p>The test data should be inside the test case. This keeps everything together. You know exactly what data is important to the [...]]]></description>
			<content:encoded><![CDATA[<p>In the previous post on this topic, I gave you some very good reasons to not pre-populate your unit test database. So, the burning question is, where should test data come from?</p>
<p><strong>The test data should be inside the test case.</strong> This keeps everything together. You know exactly what data is important to the test case by reading the test case. The first step of the test case generally inserts the data it needs into the database (part of the Assemble-Act-Assert pattern).</p>
<p><strong>Only data needed for the test should be included in the test case.</strong> By inserting only the data you need in the test case, you create focus. There is much less chance that unrelated schema changes will break your tests and that the test will actually validate the small piece of code you are targeting.</p>
<p><strong>Tables should be faked.</strong> The biggest problem with inserting test data inside the test case is that there are constraints on the tables. To solve this problem, we can borrow a unit testing practice from object-oriented languages, that is creating a fake version of a dependency. For example, if we&#8217;re testing a stored procedure which reads data from a table, the stored procedure is dependent upon the table. We can replace the real table with a fake table which does not have the constraints. This allows us to easily insert data in the test case.</p>
<p>In tSQLt, tables are faked using the tSQLt.FakeTable procedure. This procedure renames the original table and puts a new one in its place. The new table contains the same columns with the same data-types, but does not have the constraints including primary keys, foreign keys, checks or null restrictions. Let&#8217;s look at an example of a test case that fakes a table:</p>
<pre><span style="color: #0000ff;"><span style="font-size: x-small;">EXEC</span></span><span style="color: #000000;"><span style="font-size: x-small;"> tSQLt</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">NewTestClass</span></span><span style="color: #0000ff;"><span style="font-size: x-small;"> </span></span><span style="color: #ff0000;"><span style="font-size: x-small;">'OrderReportTests'</span></span><span style="color: #808080;"><span style="font-size: x-small;">;</span></span>
<span style="color: #0000ff;"><span style="font-size: x-small;">GO</span></span>

<span style="color: #0000ff;"><span style="font-size: x-small;">CREATE</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">PROCEDURE</span></span><span style="color: #000000;"><span style="font-size: x-small;"> OrderReportTests</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">[test: OrderReport works for several customers]</span></span>
<span style="color: #0000ff;"><span style="font-size: x-small;">AS</span></span>
<span style="color: #0000ff;"><span style="font-size: x-small;">BEGIN</span></span>
    <span style="color: #0000ff;"><span style="font-size: x-small;">EXEC</span></span><span style="color: #000000;"><span style="font-size: x-small;"> tSQLt</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">FakeTable</span></span><span style="color: #0000ff;"><span style="font-size: x-small;"> </span></span><span style="color: #ff0000;"><span style="font-size: x-small;">'dbo'</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #ff0000;"><span style="font-size: x-small;">'Orders'</span></span><span style="color: #808080;"><span style="font-size: x-small;">;
</span></span>

<span style="color: #000000;">    </span><span style="color: #0000ff;"><span style="font-size: x-small;">INSERT</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">INTO</span></span><span style="color: #000000;"><span style="font-size: x-small;"> dbo</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">Orders</span></span><span style="color: #808080;"><span style="font-size: x-small;">(</span></span><span style="color: #000000;"><span style="font-size: x-small;">OrderId</span></span><span style="color: #808080;"><span style="font-size: x-small;">, </span></span><span style="color: #000000;"><span style="font-size: x-small;">CustomerId</span></span><span style="color: #808080;"><span style="font-size: x-small;">)</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">
    VALUES </span></span><span style="color: #808080;"><span style="font-size: x-small;">(</span></span><span style="color: #000000;"><span style="font-size: x-small;">1</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">13</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">2</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">13</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">3</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">42</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">4</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">73</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">5</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">73</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">6</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">73</span></span><span style="color: #808080;"><span style="font-size: x-small;">);</span></span>
<span style="color: #000000;">  </span><span style="color: #0000ff;"> </span>
<span style="color: #0000ff;"><span style="font-size: x-small;">    SELECT</span></span><span style="color: #000000;"><span style="font-size: x-small;"> CustomerId</span></span><span style="color: #808080;"><span style="font-size: x-small;">, </span></span><span style="color: #000000;"><span style="font-size: x-small;">Cnt </span></span>
<span style="color: #000000;">     </span><span style="color: #0000ff;"><span style="font-size: x-small;"> INTO</span></span><span style="color: #000000;"><span style="font-size: x-small;"> #actual</span></span>
<span style="color: #000000;">     </span><span style="color: #0000ff;"><span style="font-size: x-small;"> FROM</span></span><span style="color: #000000;"><span style="font-size: x-small;"> dbo</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">CustomerReport</span></span><span style="color: #808080;"><span style="font-size: x-small;">;</span></span>
<span style="color: #000000;"> </span>
<span style="color: #000000;">    </span><span style="color: #0000ff;"><span style="font-size: x-small;">SELECT</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">TOP</span></span><span style="color: #808080;"><span style="font-size: x-small;">(</span></span><span style="color: #000000;"><span style="font-size: x-small;">0</span></span><span style="color: #808080;"><span style="font-size: x-small;">)</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #808080;"><span style="font-size: x-small;">*</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">INTO</span></span><span style="color: #000000;"><span style="font-size: x-small;"> #expected </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">FROM</span></span><span style="color: #000000;"><span style="font-size: x-small;"> #actual</span></span><span style="color: #808080;"><span style="font-size: x-small;">;</span></span>
<span style="color: #000000;"> </span>
<span style="color: #000000;">    </span><span style="color: #0000ff;"><span style="font-size: x-small;">INSERT</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">INTO</span></span><span style="color: #000000;"><span style="font-size: x-small;"> #expected</span></span><span style="color: #808080;"><span style="font-size: x-small;">(</span></span><span style="color: #000000;"><span style="font-size: x-small;">CustomerId</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">Cnt</span></span><span style="color: #808080;"><span style="font-size: x-small;">)</span></span><span style="color: #000000;"><span style="font-size: x-small;"> </span></span><span style="color: #0000ff;"><span style="font-size: x-small;">VALUES </span></span><span style="color: #808080;"><span style="font-size: x-small;">(</span></span><span style="color: #000000;"><span style="font-size: x-small;">42</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">1</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">13</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">2</span></span><span style="color: #808080;"><span style="font-size: x-small;">),(</span></span><span style="color: #000000;"><span style="font-size: x-small;">73</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">3</span></span><span style="color: #808080;"><span style="font-size: x-small;">);</span></span>
<span style="color: #000000;"> </span>
<span style="color: #000000;">    </span><span style="color: #0000ff;"><span style="font-size: x-small;">EXEC</span></span><span style="color: #000000;"><span style="font-size: x-small;"> tSQLt</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">AssertEqualsTable</span></span><span style="color: #0000ff;"><span style="font-size: x-small;"> </span></span><span style="color: #000000;"><span style="font-size: x-small;">#expected</span></span><span style="color: #808080;"><span style="font-size: x-small;">,</span></span><span style="color: #000000;"><span style="font-size: x-small;">#actual</span></span><span style="color: #808080;"><span style="font-size: x-small;">;</span></span>
<span style="color: #0000ff;"><span style="font-size: x-small;">END</span></span>
<span style="color: #0000ff;"><span style="font-size: x-small;">GO</span></span>

<span style="color: #0000ff;"><span style="font-size: x-small;">EXEC</span></span><span style="color: #000000;"><span style="font-size: x-small;"> tSQLt</span></span><span style="color: #808080;"><span style="font-size: x-small;">.</span></span><span style="color: #000000;"><span style="font-size: x-small;">Run</span></span><span style="color: #0000ff;"><span style="font-size: x-small;"> </span></span><span style="color: #ff0000;"><span style="font-size: x-small;">'OrderReportTests'</span></span><span style="color: #808080;"><span style="font-size: x-small;">;</span></span></pre>
<p>&nbsp;</p>
<p>In this example, we fake the Orders table. The CustomerReport view depends on only the OrderId and CustomerId columns from the Orders table. We only need to insert those two columns into the Orders table, even though it has several other <em>&#8216;not null&#8217;</em> columns. The rest of the test validates that the records returned by CustomerReport view are the expected values. The documentation of the AssertEqualsTable feature in tSQLt discusses this technique in more detail.</p>
<p><strong>Tests should be executed in transactions which are rolled-back after each test.</strong> In order for test cases to be independent, anything that happens during the test case must be undone. The easiest way of doing this in a database is to create a transaction and roll it back when the test is complete. SQL Server conveniently rolls back schema changes also, so a faked table is rolled back.</p>
<p><strong>The tests should be written in parallel with the code.</strong> The best way to achieve test coverage of your code is to only write enough code to make a failing test pass. This is a critical component of test driven development and will be discussed in great detail on this website. Writing test cases this way will improve the ability to make changes down stream because you will be confident that there is adequate test coverage. Furthermore, knowledge of test case identification heuristics will help you discover the correct tests to write and which test to write next.</p>
<p><strong>Pre-populated databases are still useful in other areas of application development.</strong> They are especially useful for performance and scalability testing. Usability testing and prototyping also benefit from pre-populated databases. They&#8217;re also necessary for data-mining and discover tasks, and development of data dependent certain algorithms. However, they get in your way when you&#8217;re writing unit tests.</p>
<p>In the final post in this series, I&#8217;ll counter some of the criticisms of this approach to database unit testing.</p>
<p>&nbsp;</p>
<h2>Other Posts in this Series:</h2>
<p><a title="Pre-populated Test Databases – Part 1" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-1/">Pre-populated Test Databases – Part 1</a></p>
<p><a title="Pre-populated Test Databases – Part 3" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-3/">Pre-populated Test Databases – Part 3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pre-populated Test Databases – Part 1</title>
		<link>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-1/</link>
		<comments>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-1/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:01:14 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.testdrivendatabases.com/?p=23</guid>
		<description><![CDATA[<p>&#160;</p> <p>This post discusses pre-populating a database for database unit tests.</p> <p>Your tests need data to work with. There are several approaches to supplying test data for unit tests. One approach is to use a pre-populated test database. The data in this database could be obtained from an existing customer or generated in some [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>This post discusses pre-populating a database for <a title="About Database Unit Testing" href="http://www.testdrivendatabases.com/about-database-unit-testing/">database unit tests</a>.</p>
<p>Your tests need data to work with. There are several approaches to supplying test data for unit tests. One approach is to use a pre-populated test database. The data in this database could be obtained from an existing customer or generated in some way. This series of posts discuss why you should NOT use a pre-populated test database for unit testing and how you should actually go about creating test data.</p>
<h2>Why Not?</h2>
<p>There are several reasons to not pre-populate test data for unit testing. Primarily these are: it makes test cases harder to read, more expensive to maintain, and limits the types of tests you can create. Let&#8217;s look at these claims in more detail:</p>
<h3><strong>Obscurity</strong></h3>
<p>First, the test data is in a separate place than the test case. By this, I don&#8217;t simply mean that the test data lives in a separate folder or in another database. The test data helps express the intent of the test. For example, if a test is validating a calculation based on the data, then the specific values used are an important part of the test. When reading the test case, if you have to look somewhere else to find out the intent of the test case, then you&#8217;re going to slow yourself down considerably.</p>
<p>As a consequence, tests often contain “magic” values which refer to special records in the test database. Trying to keep track of the meaning of special test case records is particularly difficult. For example, you&#8217;re likely to end up with a record for “Joe Smith” and everyone on the team needs to remember that Joe Smith was the customer who bought 50 widgets at a total cost of $500 but doesn&#8217;t have a credit limit (as opposed to the record for “Johnny Wilkenson” who has the same data, but has a sufficient credit limit, and so on).</p>
<h3>Interdependency</h3>
<p>If all (or even some) of the test cases share the same data set, then you will find that test cases become more difficult to maintain.</p>
<p>Let&#8217;s look at an example: Suppose you&#8217;re system contains several reports which provide different ways of considering the same data. The first report you write displays the name of each customer who ordered your most expensive product and the total order value. Your pre-populated test database has the following records in it:</p>
<table border="1" cellspacing="0" cellpadding="4" width="158">
<col width="64"></col>
<col width="76"></col>
<tbody>
<tr>
<td colspan="2" width="148" valign="TOP"><strong>Orders</strong></td>
</tr>
<tr valign="TOP">
<td width="64">OrderId</td>
<td width="76">Customer</td>
</tr>
<tr valign="TOP">
<td width="64">1</td>
<td width="76">Frank</td>
</tr>
<tr valign="TOP">
<td width="64">2</td>
<td width="76">Bill</td>
</tr>
<tr valign="TOP">
<td width="64">3</td>
<td width="76">Sue</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table border="1" cellspacing="0" cellpadding="4" width="158">
<col width="61"></col>
<col width="79"></col>
<tbody>
<tr>
<td colspan="2" width="148" valign="TOP"><strong>OrderItems</strong></td>
</tr>
<tr valign="TOP">
<td width="61">OrderId</td>
<td width="79">ItemId</td>
</tr>
<tr valign="TOP">
<td width="61">1</td>
<td width="79">101</td>
</tr>
<tr valign="TOP">
<td width="61">1</td>
<td width="79">102</td>
</tr>
<tr valign="TOP">
<td width="61">2</td>
<td width="79">201</td>
</tr>
<tr valign="TOP">
<td width="61">3</td>
<td width="79">101</td>
</tr>
<tr valign="TOP">
<td width="61">3</td>
<td width="79">302</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table border="1" cellspacing="0" cellpadding="4" width="251">
<col width="53"></col>
<col width="67"></col>
<col width="106"></col>
<tbody>
<tr>
<td colspan="3" width="241" valign="TOP"><strong>Items</strong></td>
</tr>
<tr valign="TOP">
<td width="53">ItemId</td>
<td width="67">ItemPrice</td>
<td width="106">ItemName</td>
</tr>
<tr valign="TOP">
<td width="53">101</td>
<td width="67">$50.00</td>
<td width="106">Table</td>
</tr>
<tr valign="TOP">
<td width="53">102</td>
<td width="67">$25.00</td>
<td width="106">Chair</td>
</tr>
<tr valign="TOP">
<td width="53">201</td>
<td width="67">$12.00</td>
<td width="106">Book</td>
</tr>
<tr valign="TOP">
<td width="53">301</td>
<td width="67">$7.00</td>
<td width="106">Hanging Folders</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>So you&#8217;re first test expects to see the following results:</p>
<table border="1" cellspacing="0" cellpadding="4" width="353" rules="ROWS" height="98">
<col width="153"></col>
<col width="153"></col>
<tbody>
<tr>
<td colspan="2" width="314" valign="TOP"><strong>Customers who ordered the most expensive item</strong></td>
</tr>
<tr valign="TOP">
<td width="153">Customer</td>
<td width="153">Order Total</td>
</tr>
<tr valign="TOP">
<td width="153">Frank</td>
<td width="153">$75.00</td>
</tr>
<tr valign="TOP">
<td width="153">Sue</td>
<td width="153">$57.00</td>
</tr>
</tbody>
</table>
<p>Now, it&#8217;s a month later and the next report must be written. In the meantime, the business has started selling more expensive items. This report will display all the items in the catalog costing more than $100. If you change the price of an existing item or add a new order with a new item, you&#8217;ll break the tests for the first report.</p>
<p>In this simple example, you might not be concerned with the amount of work to fix the first test. However, in a large system with many tests, continually fixing your existing tests just because you&#8217;ve added new functionality is painful. What normally happens when developers face this pain is they stop writing tests.</p>
<h3>Impossible Tests</h3>
<p>If your test database is already populated, the data in there may prevent you from writing certain tests. Consider if, for example, the code has special functionality if one of the tables is empty. You won&#8217;t be able to test this functionality if the table is populated. An alternative example is when the code is supposed to do something if data in the database meets some condition and do something else if the data does not meet that condition. Two mutually exclusive conditions are impossible to test when using a pre-populated test database.</p>
<p>A commonly used solution to this is to have some of the test cases modify the database for their special need and then undo the modification after the test. However, this leads to some tests containing the test data and the rest of the test data somewhere else. This means that you need to go to multiple places to update the data when schema changes are made or to get a clear picture of what is happening.</p>
<h3>Limited Thinking</h3>
<p>The final point I&#8217;d like to expose about using pre-populated test data is that it often leads to limited thinking about test cases. If there&#8217;s a lot of data already populated in the database, it is easy to assume that every important case is covered by the existing data. This is almost never true. The data in the database now is not necessarily a good reflection of the data that will be put in the database in the future from the perspective of unit testing. Writing unit tests requires you consider exception scenarios, inputs that don&#8217;t exist yet and varying the combinations of inputs.</p>
<p>Furthermore, it is more difficult to see if the important edge cases have been considered if the data is heaped into one large data set. Modifying the test data to support a new test may inadvertently remove an important condition needed for an existing test.</p>
<h2>The Results</h2>
<p>Unfortunately, when faced with these problems, many developers will either give up on database unit testing, or instead miss important test cases. Both of these outcomes lead to reduced code quality and makes me unhappy.</p>
<p>The next post in this series will propose an approach that solves these problems, and the final post will address the common concerns of the proposed approach.</p>
<p>&nbsp;</p>
<h2>Other Posts in this Series:</h2>
<p><a title="Pre-populated Test Databases – Part 2" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-2/">Pre-populated Test Databases – Part 2</a></p>
<p><a title="Pre-populated Test Databases – Part 3" href="http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-3/">Pre-populated Test Databases – Part 3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.testdrivendatabases.com/pre-populated-test-databases-%e2%80%93-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
