blob: 31035ccb218c9fe1851219a2dcb7974f61c7a5d7 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<org.eclipse.epf.uma:ContentDescription xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:org.eclipse.epf.uma="http://www.eclipse.org/epf/uma/1.0.4/uma.ecore"
xmlns:epf="http://www.eclipse.org/epf" epf:version="1.2.0" xmi:id="-jc10ie6UDWUJzSDfsQExjw"
name="test_driven_development_tdd,3.9254165491375454E-306" guid="-jc10ie6UDWUJzSDfsQExjw"
changeDate="2006-11-21T18:17:42.164-0500" version="1.0.0">
<mainDescription>&lt;a id=&quot;XE_xp__test_driven_development&quot; name=&quot;XE_xp__test_driven_development&quot;>&lt;/a>&lt;a id=&quot;XE_test_driven_development__in_xp&quot; name=&quot;XE_test_driven_development__in_xp&quot;>&lt;/a> &#xD;
&lt;h3>&#xD;
Topics&#xD;
&lt;/h3>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#WhatIs&quot;>What is TDD?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Java&quot;>A TDD Example in Java&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Benefits&quot;>What are the benefits of TDD?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Costs&quot;>What are the costs of TDD?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Principles&quot;>What testing principles should I employ?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#GUIS&quot;>How do I test GUIs?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Embedded&quot;>How do I test embedded systems?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Concurrency&quot;>How do I test concurrency?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Database&quot;>How do I test database transactions?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#Servlets&quot;>How do I test servlets?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;a href=&quot;#WebPages&quot;>How do I test web pages?&lt;/a>&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;WhatIs&quot; name=&quot;WhatIs&quot;>What is TDD?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
TDD is the practice of writing unit tests and production code concurrently and at a very fine level of granularity. A&#xD;
pair of programmers first write a small portion of a unit test, and then they write just enough production code to make&#xD;
that unit test compile and execute. Then they write a little bit more of the test and then add enough production code&#xD;
to make that new bit compile and pass. This cycle lasts somewhere between 30 seconds and five minutes. Rarely does it&#xD;
grow to ten minutes. In each cycle, the tests come first. Once a unit test is done, the pair goes on to the next test&#xD;
until they run out of tests for the task they are currently working on.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Java&quot; name=&quot;Java&quot;>A TDD Example in Java&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
What follows is a simple example of test-driven development. The program we are writing is a text formatter that can&#xD;
take arbitrary strings and can horizontally center them in a page. The first column shows the tests, and the second&#xD;
column shows the production code. The test is always written first and compiled. If the compile fails, then production&#xD;
code is added to make the compile succeed. Then the test is run to see if it passes. If the test fails, then production&#xD;
code is added to make the test pass. If the test passes, then a new test is added.&#xD;
&lt;/p>&#xD;
&lt;table width=&quot;100%&quot; border=&quot;1&quot;>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;font size=&quot;-1&quot;>&lt;i>&lt;b>First we write the test&lt;/b>&lt;/i>&lt;/font>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;font size=&quot;-1&quot;>&lt;i>&lt;b>Then we write the production code&lt;/b>&lt;/i>&lt;/font>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;tbody>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
public void testCenterLine(){ &#xD;
Formatter f = new Formatter();&#xD;
}&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#ff0000&quot; size=&quot;2&quot;>&#xD;
does not compile&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
class Formatter{&#xD;
}&#xD;
&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#008000&quot; size=&quot;2&quot;>&#xD;
compiles and passes&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
public void testCenterLine(){ &#xD;
Formatter f = new Formatter(); &#xD;
f.setLineWidth(10); &#xD;
assertEquals(&quot; word &quot;, f.center(&quot;word&quot;));&#xD;
}&#xD;
&#xD;
&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#ff0000&quot; size=&quot;2&quot;>&#xD;
does not compile&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
class Formatter{ &#xD;
public void setLineWidth(int width) { &#xD;
} &#xD;
&#xD;
&#xD;
public String center(String line) {&lt;br />&#xD;
&#xD;
return &quot;&quot;;&#xD;
}&#xD;
}&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#ff0000&quot; size=&quot;2&quot;>&#xD;
compiles and fails&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;font size=&quot;2&quot;>&amp;nbsp;&lt;/font>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
import java.util.Arrays;&#xD;
&#xD;
&#xD;
public class Formatter { &#xD;
private int width; &#xD;
private char spaces[]; &#xD;
&#xD;
public void setLineWidth(int width) { &#xD;
this.width = width; &#xD;
spaces = new char[width]; &#xD;
Arrays.fill(spaces, ' '); &#xD;
} &#xD;
&#xD;
&#xD;
public String center(String line) { &#xD;
StringBuffer b = new StringBuffer();&#xD;
int padding = width/2 - line.length(); &#xD;
b.append(spaces, 0, padding); &#xD;
b.append(line); &#xD;
b.append(spaces, 0, padding); &#xD;
return b.toString(); &#xD;
}&#xD;
}&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#ff0000&quot; size=&quot;2&quot;>&#xD;
compiles and unexpectedly fails&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;font size=&quot;2&quot;>&amp;nbsp;&lt;/font>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
public String center(String line) { &#xD;
StringBuffer b = new StringBuffer(); &#xD;
&lt;b>&#xD;
int padding = (width - line.length()) / 2;&lt;/b> &#xD;
b.append(spaces, 0, padding); &#xD;
b.append(line); &#xD;
b.append(spaces, 0, padding); &#xD;
return b.toString(); &#xD;
}&#xD;
&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#008000&quot; size=&quot;2&quot;>&#xD;
compiles and passes&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;tr>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
public void testCenterLine() {&#xD;
Formatter f = new Formatter(); &#xD;
f.setLineWidth(10); &#xD;
assertEquals(&quot; word &quot;, f.center(&quot;word&quot;));&#xD;
} &#xD;
&#xD;
&lt;b>&#xD;
public void testOddCenterLine() { &#xD;
Formatter f = new Formatter();&#xD;
f.setLineWidth(10); &#xD;
assertEquals( &quot; hello &quot;, f.center(&quot;hello&quot;));&#xD;
}&lt;/b>&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#ff0000&quot; size=&quot;2&quot;>&#xD;
compiles and fails&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;td>&#xD;
&lt;pre>&#xD;
&lt;font size=&quot;2&quot;>&#xD;
public String center(String line) { &#xD;
&lt;b>&#xD;
int remainder = 0;&lt;/b> &#xD;
StringBuffer b = new StringBuffer(); &#xD;
int padding = (width - line.length()) / 2;&#xD;
&lt;b>&#xD;
remainder = line.length() % 2;&lt;/b> &#xD;
b.append(spaces, 0, padding); &#xD;
b.append(line);&#xD;
b.append(spaces, 0, padding + &lt;b>&#xD;
remainder&lt;/b>); &#xD;
return b.toString(); &#xD;
}&#xD;
&#xD;
&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;div align=&quot;center&quot;>&#xD;
&lt;pre>&#xD;
&lt;font color=&quot;#008000&quot; size=&quot;2&quot;>&#xD;
compiles and passes&lt;/font>&#xD;
&lt;/pre>&#xD;
&lt;/div>&#xD;
&lt;/td>&#xD;
&lt;/tr>&#xD;
&lt;/tbody>&#xD;
&lt;/table>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Benefits&quot; name=&quot;Benefits&quot;>What are the benefits of TDD?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Test Coverage&lt;/b>. If you follow the rules of TDD, then virtually 100% of the lines of code in your production&#xD;
program will be covered by unit tests. This does not cover 100% of the paths through the code, but it does make&#xD;
sure that virtually every line is executed and tested.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Test Repeatability&lt;/b>. The tests can be run any time you like. This is especially useful after you've made a&#xD;
change to the production code. You can run the tests to make sure you haven't broken anything. Having the tests to&#xD;
back you up can give you the courage to make changes that would otherwise be too risky to make.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Documentation&lt;/b>. The tests describe your understanding of how the code should behave. They also describe the&#xD;
API. Therefore, the tests are a form of documentation. Unit tests are typically pretty simple, so they are easy to&#xD;
read. Moreover, they are unambiguous and executable. Finally, if the tests are run every time any change is made to&#xD;
the code, they will never get out of date.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>API Design&lt;/b>. When you write tests first, you put yourself in the position of a user of your program's API.&#xD;
This can only help you design that API better. Your first concern, as you write the tests, is to make it easy and&#xD;
convenient to use that API.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>System Design&lt;/b>. A module that is independently testable is a module that is decoupled from the rest of the&#xD;
system. When you write tests first, you automatically decouple the modules you are testing. This has a profoundly&#xD;
positive effect on the overall design quality of the system.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Reduced Debugging&lt;/b>. When you move in the tiny little steps recommended by TDD, it is hardly ever necessary to&#xD;
use the debugger. Debugging time is reduced enormously.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Your code worked a minute ago!&lt;/b> If you observe a team of developers who are practicing TDD, you will notice&#xD;
that every pair of developer had their code working a minute ago. It doesn't matter when you make the observation!&#xD;
A minute or so ago, each pair ran their code, and it passed all its tests. Thus, you are never very far away from&#xD;
making the system work.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Costs&quot; name=&quot;Costs&quot;>What are the costs of TDD?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
Programming in tiny cycles can seem inefficient. Programmers often find it frustrating to work in increments that&#xD;
are so small that they know the outcome of the test. It sometimes seems that such a tiny step is not worth&#xD;
taking.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
A lot of test code is produced. It is not uncommon for the bulk of test code to exceed the bulk of production code&#xD;
by a large amount. This code has to be maintained at a significant cost.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
A lot of time is spent keeping the tests in sync with the production code. Programmers sometimes feel that time&#xD;
spent on keeping the tests working and well structured is time that is not being spent on the customer's&#xD;
needs.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Principles&quot; name=&quot;Principles&quot;>What testing principles should I employ?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Isolation&lt;/b>. When writing a unit test for a module, consider whether you want that module to invoke other&#xD;
modules. If not, then isolate the module with interfaces. For example, suppose you are testing a module that&#xD;
interacts with the database. The test has nothing to do with the database; it simply tests the way that the module&#xD;
manipulates the database. So you isolate the module from the database by creating an interface that represents the&#xD;
database and that the module uses. Then, for the purposes of the test, you implement that interface with a test&#xD;
stub. This kind of isolation greatly decreases the amount of coupling in the overall system.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;p>&#xD;
&lt;img height=&quot;166&quot; alt=&quot;&quot; src=&quot;resources/xp_tdd_guid_database.jpg&quot; width=&quot;403&quot; />&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Simplicity&lt;/b>. Keep your edit/compile/test cycles extremely short: less than five minutes on average. Write&#xD;
only enough production code to make the current tests pass. Try not to write code that will make future tests pass.&#xD;
At every edit/compile/test cycle, keep the code as simple as it can be.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Increase Generality&lt;/b>. As you add test cases, the production code should become more and more general. Always&#xD;
try to increase generality. For example, consider the following test case:&lt;br />&#xD;
&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public testThreeSquared() { assertEquals(9, MyClass.square(3)); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
We might make this test pass by writing:&#xD;
&lt;/p>&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public class MyClass { public static int square(int n) { return 9; } }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
This conforms to the simplicity principle. If &lt;font size=&quot;3&quot;>&lt;tt>testThreeSquared&lt;/tt>&lt;/font> were the only test&#xD;
case that mattered, then this implementation would be correct. Of course, we know that it is incorrect, but in its&#xD;
current form it verifies that the test case actually passes when it is supposed to. Now suppose that we add a new&#xD;
test case:&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public testFourSquared() { assertEquals(16, MyClass.square(4)); } &#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
We could make this pass by changing the square function as follows:&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public static int square(int n) { if (n == 3) return 9; else return 16; }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
While this would pass the test, it violates the rule to make the code more general. To make the code more general,&#xD;
we have to return the square of the argument.&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public static int square(int n) { return n*n; }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
This solution passes all the tests, is simple, and increases the generality of the solution.&#xD;
&lt;/p>&#xD;
&lt;/blockquote>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Corner Cases and Boundary Conditions&lt;/b>. Corner cases and boundary conditions are implemented in the production&#xD;
code with if statements or other similar decision structures. Don't write these statements unless you have a unit&#xD;
test that is failing because they don't exist. For example, let's say you are calculating weekly pay for an hourly&#xD;
employee. &#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public void testHourlyPay() { double hourlyRate = 10.00; double hoursWorked = 8; Employee e = new Employee(hourlyRate); assertEquals(80.00, e.calculatePay(hoursWorked)); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
The code that makes this pass looks like this:&#xD;
&lt;/p>&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public class Employee { private double hourlyRate; public Employee(double hourlyRate) { this.hourlyRate = hourlyRate; } public double calculatePay(double hoursWorked) { return hourlyRate * hoursWorked; } }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
Now let's say we want to calculate overtime pay. Any hours over eight are charged at time-and-a-half. The first&#xD;
thing we do is add the new failing test case:&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public void testOvertime() { double hourlyRate = 10.00; double hoursWorked = 10; Employee e = new Employee(hourlyRate); assertEquals(110.00, e.calculatePay(hoursWorked); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
&lt;i>Then&lt;/i> we make the test case pass by changing the production code.&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public double calculatePay(double hoursWorked) { double overtimeRate = hourlyRate * 1.5; double normalHours = Math.min(hoursWorked, 8.0); double overtimeHours = hoursWorked ̵; normalHours; return (normalHours * hourlyRate) + (overtimeHours * overtimeRate); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
Avoid adding any &lt;font size=&quot;3&quot;>&lt;tt>if, while, for, do,&lt;/tt>&lt;/font> or any other type of conditional without a&#xD;
failing test case. Remember to add test cases for each such boundary condition.&#xD;
&lt;/p>&#xD;
&lt;/blockquote>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Test Anything That Could Possibly Break&lt;/b>. By the same token, don't bother to test things that cannot possibly&#xD;
break. For example, it is usually fruitless to test simple accessors and mutators. &#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public void testAccessorAndMutator() { X x = new X(); x.setField(3); assertEquals(3, x.getField()); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
Accessors and mutators cannot reasonably break. So there's no point in testing them. Judgment clearly has to be&#xD;
applied to use this rule. You will be tempted to avoid a necessary unit test by claiming that the code cannot&#xD;
possibly break. You'll know you've fallen into this habit when you start finding bugs in methods you thought&#xD;
couldn't break.&#xD;
&lt;/p>&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
&lt;b>Keep Test Data in the Code&lt;/b>. It is sometimes tempting to put test data into a file, especially when the input&#xD;
to a module is a file. However, the best place for test data is in the unit test code itself. For example, assume&#xD;
we have a function that counts the number of characters in a file. The signature for this function is: &#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public int count(String fileName).&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
In order to keep the test data in the unit test code, the test should be written this way:&#xD;
&lt;/p>&#xD;
&lt;/li>&#xD;
&lt;li style=&quot;LIST-STYLE-TYPE: none&quot;>&#xD;
&lt;blockquote>&#xD;
&lt;blockquote>&#xD;
&lt;pre>&#xD;
public testCount() { File testFile = new File(&quot;testFile&quot;); FileOutputStream fos = new FileOutputStream(testFile); PrintStream ps = new PrintStream(fos); ps.print(&quot;Oh, you Idiots!&quot;); ps.close(); assertEquals(15, FileUtil.count(&quot;testFile&quot;)); testFile.delete(); }&#xD;
&lt;/pre>&#xD;
&lt;/blockquote>&#xD;
&lt;/blockquote>&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;blockquote>&#xD;
&lt;p>&#xD;
This keeps all the data relevant to the test in one place.&#xD;
&lt;/p>&#xD;
&lt;/blockquote>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Test Pruning&lt;/b>. Sometimes you'll write tests that are useful for a time but become redundant as other tests&#xD;
take over their role. Don't be afraid to remove old redundant tests. Keep the test suite as small as possible&#xD;
without compromising coverage.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
&lt;b>Keep Test Time Short&lt;/b>. The effectiveness of the tests depends upon convenience. The more convenient it is to&#xD;
run the tests, the more often they will be run. Thus, it is very important to keep the test run time very short. In&#xD;
a large system, this means partitioning the tests.&lt;br />&#xD;
&lt;br />&#xD;
When working on a particular module, you'll want to choose the tests that are relevant to that module and the&#xD;
surrounding modules. Keep the test time well under a minute. Ten seconds is often too long.&lt;br />&#xD;
&lt;br />&#xD;
When checking in a module, run a test suite that tests the whole system but takes no more than 10 minutes to run.&#xD;
This may mean you'll have to pull out some of the longer running tests.&lt;br />&#xD;
&lt;br />&#xD;
Every night, run all the tests in the system. Keep the running time small enough so that they can be run more than&#xD;
once before morning just in case there is a problem that forces a rerun.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;GUIS&quot; name=&quot;GUIS&quot;>How do I test GUIs?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
The trick to writing unit tests for GUIs is separation and decoupling. Separate the GUI code into three layers,&#xD;
typically called &lt;b>Model&lt;/b>, &lt;b>View&lt;/b>, and &lt;b>Presenter&lt;/b>:&#xD;
&lt;/p>&#xD;
&lt;ul>&#xD;
&lt;li>&#xD;
The &lt;b>Model&lt;/b> understands the business rules of the items that are to be displayed on the screen. All relevant,&#xD;
business-related policies are implemented in this module. Therefore, this module is easy to test based solely on&#xD;
its inputs and outputs.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
The &lt;b>Presenter&lt;/b> understands how the data is to be presented and how the user will interact with that data. It&#xD;
knows that there are buttons, check boxes, text fields, etc. It knows that sometimes the buttons need to be&#xD;
disabled (grayed), and it knows sometimes text fields are not editable. It knows, at a mechanical level, how the&#xD;
data are displayed and how the interactions take place. However, it does not know anything about the actual GUI&#xD;
API. For example, if you are writing a Java Swing GUI, the Presenter does not use any of the swing classes. Rather,&#xD;
it sends messages to the View to take care of the actual display and interaction. Thus, the Presenter can be&#xD;
tested, again, based solely on its inputs from the Model and its outputs to the View.&lt;br />&#xD;
&lt;/li>&#xD;
&lt;li>&#xD;
The &lt;b>View&lt;/b> understands the GUI API. It makes no policy, selection, or validation decisions. It has virtually&#xD;
zero intelligence. It is simply a shim that ties the interface used by the Presenter to the GUI API. It can be&#xD;
tested by writing tests that check the wiring. The tests walk through the GUI data structures, making sure that the&#xD;
appropriate button, text fields, and check boxes have been created. The tests send events to the GUI widgets and&#xD;
make sure the appropriate callbacks are invoked.&#xD;
&lt;/li>&#xD;
&lt;/ul>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Embedded&quot; name=&quot;Embedded&quot;>How do I test embedded systems?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Some software is written to control hardware. You can test this software by writing a hardware simulator. The tests set&#xD;
the hardware simulator up into various states and then drive the system to manipulate that hardware. Finally, the tests&#xD;
query the simulation to ensure that the hardware was driven to the correct final state.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Concurrency&quot; name=&quot;Concurrency&quot;>How do I test concurrency?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Some software is reentrant or concurrent. Race conditions can make the software behavior non-deterministic. There are&#xD;
failure modes that can be both severe and strongly dependent upon timing and order of events. Software that works&#xD;
99.999% of the time can fail that last .001% of the time due to concurrency problems. Finding these problems is a&#xD;
challenge.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Usually exhaustive Monte Carlo testing is used to attempt to drive the system through as many states as possible.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Once concurrency problems are discovered, tests can be written that drive the system to the failure state and then&#xD;
prove the failure. Thereafter, the problem can be repaired, and the test remains in the test suite as a regression&#xD;
test.&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Database&quot; name=&quot;Database&quot;>How do I test database transactions?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Almost always the best way to do this is to create an interface that represents the database. Each test case can&#xD;
implement that interface and pretend to be the database, supplying its own data and interpreting the calls made by the&#xD;
module under test. This prevents test data from actually being written and read from the database. It also allows the&#xD;
test code to force failure conditions that are otherwise hard to simulate.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
See: &lt;a href=&quot;http://c2.com/cgi/wiki?MockObject &quot; target=&quot;_blank&quot;>http://c2.com/cgi/wiki?MockObject&lt;/a>&#xD;
&lt;/p>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;Servlets&quot; name=&quot;Servlets&quot;>How do I test Servlets?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
Servlets are simply pipes through which form data passes into a program and HTML passes out. The trick to testing a&#xD;
servlet is to separate the program from the pipe. Keep the servlet code as thin as possible. Put your program in plain&#xD;
old classes that don't derive from Servlet. Then you can test those plain old classes as usual. If the servlet itself&#xD;
is thin enough, it may be too simple to bother testing.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
Of course, you can also set up your own little servlet invoker or use one of the open source versions. These programs&#xD;
act like a web server and fire servlets for you. You pass the form data to them, and they pass the HTML back to you.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
See:&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;a href=&quot;http://c2.com/cgi/wiki?JunitServlet&quot; target=&quot;_blank&quot;>http://c2.com/cgi/wiki?JunitServlet&lt;/a>&lt;br />&#xD;
&lt;a href=&quot;http://c2.com/cgi/wiki?ServletTesting&quot; target=&quot;_blank&quot;>http://c2.com/cgi/wiki?ServletTesting&lt;/a>&lt;br />&#xD;
&lt;a href=&quot;http://strutstestcase.sourceforge.net/&quot; target=&quot;_blank&quot;>http://strutstestcase.sourceforge.net/&lt;/a>&#xD;
&lt;/blockquote>&#xD;
&lt;h3>&#xD;
&lt;a id=&quot;WebPages&quot; name=&quot;WebPages&quot;>How do I test web pages?&lt;/a>&#xD;
&lt;/h3>&#xD;
&lt;p>&#xD;
An HTML document is almost an XML document. There is a tool that allows you to query an HTML document as though it were&#xD;
an XML document. That tool is called HTTPUnit. Using this tool, you can write tests that inspect the innards of an HTML&#xD;
document without worrying about white space or formatting issues. Another tool called HTMLUnit also does something&#xD;
similar. HTMLUnit includes support for testing HTML pages with embedded JavaScript.&#xD;
&lt;/p>&#xD;
&lt;p>&#xD;
See:&#xD;
&lt;/p>&#xD;
&lt;blockquote>&#xD;
&lt;a href=&quot;http://httpunit.sourceforge.net/&quot; target=&quot;_blank&quot;>http://httpunit.sourceforge.net/&lt;/a>&lt;br />&#xD;
&lt;a href=&quot;http://htmlunit.sourceforge.net/&quot; target=&quot;_blank&quot;>http://htmlunit.sourceforge.net/&lt;/a>&lt;br />&#xD;
&lt;/blockquote>&#xD;
&lt;p>&#xD;
&lt;br />&#xD;
&amp;nbsp;&#xD;
&lt;/p></mainDescription>
</org.eclipse.epf.uma:ContentDescription>