<?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>The Cafes &#187; Testing</title>
	<atom:link href="http://cafe.elharo.com/category/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://cafe.elharo.com</link>
	<description>Longer than a blog; shorter than a book</description>
	<lastBuildDate>Sat, 30 Mar 2013 11:51:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Harold&#8217;s Corollary to Knuth&#8217;s Law</title>
		<link>http://cafe.elharo.com/testing/harolds-corollary-to-knuths-law/</link>
		<comments>http://cafe.elharo.com/testing/harolds-corollary-to-knuths-law/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 15:12:02 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/?p=246</guid>
		<description><![CDATA[Lately I&#8217;ve found myself arguing about the proper design of unit tests. On my side I&#8217;m claiming: Unit tests should only touch the public API. Code coverage should be as near 100% as possible. It&#8217;s better to test the real thing than mock objects. The goal is to make sure that the tests are as [...]]]></description>
				<content:encoded><![CDATA[<p>Lately I&#8217;ve found myself arguing about the proper design of unit tests. On my side I&#8217;m claiming:</p>
<ol>
<li>Unit tests should only touch the public API. </li>
<li>Code coverage should be as near 100% as possible.</li>
<li>It&#8217;s better to test the real thing than mock objects.</li>
</ol>
<p>The goal is to make sure that the tests are as close to actual usage as possible. This means that  problems are more likely to be detected and false positives are less likely. Furthermore, the discipline of testing through the public API when attempting to achieve 100% code coverage tends to reveal a lot about how the code really works. It routinely highlights dead code that can be eliminated. It reveal paths of optimization. It teaches me things about my own code I didn&#8217;t know. It shows patterns in the entire system that makes up my product.</p>
<p>By contrast some programmers advocate that tests should be method-limited. Each test should call the method as directly as possible, perhaps even making it public or non-private and violating encapsulation to enable this. Any external resources that are necessary to run the method such as databases or web servers should be mocked out. At the extreme, even other classes a test touches should be replaced by mock implementations.</p>
<p>This approach may sometimes let the tests be written faster; but not always. There&#8217;s a non-trivial cost to designing mock objects to replace the real thing; and sometimes that takes longer. This approach will still tend to find most bugs in the method being tested. However it stops there. It will not find code in the method that should be eliminated because it&#8217;s unreachable from the public API. Thus code tested with this approach is likely to be larger, more complex, and slower since it has to handle conditions that can&#8217;t happen through the public API. More importantly, such a test starts and stops with that one method. It reveals nothing about the interaction of the different parts of the system. It teaches nothing about how the code really operates in the more complex environment of the full system. It misses bugs that can emerge out of the mixture of multiple different methods and classes even when each method is behaving correctly in isolation according to its spec. That is, it often fails to find flaws in the specifications of the individual methods. Why then are so many programmers so adamant about breaking access protection and every other rule of good design as soon as they start testing?</p>
<p>Would you believe performance?<br />
<span id="more-246"></span></p>
<p>For instance consider <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=126923">this proposal</a> from Michael Feathers:</p>
<blockquote>
<p>A test is not a unit test if:</p>
<ul>
<li><i>It talks to the database<br />
</i></li>
<li><i>It communicates across the network<br />
</i></li>
<li><i>It touches the file system<br />
</i></li>
<li><i>It can&#8217;t run at the same time as any of your other unit tests<br />
</i></li>
<li><i>You have to do special things to your environment (such as editing<br />
config files) to run it.</i></li>
</ul>
<p>Tests that do these things aren&#8217;t bad. Often they are worth writing, and they can be written in a unit test harness. However, it is important to be able to separate them from true unit tests so that we can keep a set of tests that we can run fast whenever we make our changes.</p>
</blockquote>
<p>More than 30 years ago Donald Knuth first published what would come to be called Knuth&#8217;s law: &#8220;premature optimization is the root of all evil in programming.&#8221; <cite>(Knuth, Donald. Structured Programming with go to Statements, ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.)</cite> But some developers still haven&#8217;t gotten the message. </p>
<p>Are there some tests that are so slow they contribute to not running the test suite? Yes. We&#8217;ve all seen them, but there&#8217;s no way to tell which tests they are in advance. In my test suite for <a href="http://www.xom.nu/">XOM</a>, I have numerous tests that communicate across the network,  touch the filesystem, and access third party libraries. However, almost all these tests run like a bat out of hell, and take no noticeable time. The <a href="https://xom.dev.java.net/source/browse/xom/src/nu/xom/tests/EncodingTest.java?rev=1.27&amp;view=log">slowest test in the suite</a>? It&#8217;s one that operates completely in memory on byte array streams with no network access, does not touch the file system, uses no APIs beyond what&#8217;s in Java 1.2 and XOM itself, and there&#8217;s no database anywhere in sight. I do omit that test from my standard suite because it takes too long to run. I&#8217;ll run it explicitly once or twice before releasing a new version, but not every time I make a change. </p>
<p>I am now proposing Harold&#8217;s corollary to Knuth&#8217;s law: <em>premature optimization is the root of all evil in testing</em>. It is absolutely essential to make sure that your test suite runs fast enough to run after every change to the code and before every check in. I&#8217;m even willing to put a number on &#8220;fast enough&#8221;, and that number is <a href="http://cafe.elharo.com/ui/the-90-second-rule/">90 seconds</a>. However, you simply cannot tell which tests are likely to be too slow to run routinely in advance of actual measurement. Castrating and contorting your tests to fit some imagined idea of what will and will not be slow limits their usefulness. </p>
<p>Tests should be designed for the ideal scenario: a computer that is infinitely fast with infinite memory and a network with zero latency and infinite bandwidth. Of course, that ideal computer doesn&#8217;t exist; and you&#8217;ll have to profile, optimize, and as a last resort cut back on your tests. However, I&#8217;ve never yet met a programmer who could reliably tell which tests (or other code) would and would not be fast enough in advance of actual measurements. Blanket rules that unit tests should not do X or talk to Y because it&#8217;s likely to be slow needlessly limits what we can learn from unit tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/testing/harolds-corollary-to-knuths-law/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Testing</title>
		<link>http://cafe.elharo.com/testing/testing/</link>
		<comments>http://cafe.elharo.com/testing/testing/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 03:17:55 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Refactoring HTML]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/testing/testing/</guid>
		<description><![CDATA[Here&#8217;s part 11 of the ongoing serialization of Refactoring HTML, also available from Amazon and Safari. This part&#8217;s a little funny because really it deserves an entire book on its own, and that book has yet to be written. I didn&#8217;t have space or time to write a complete second book about test driven development [...]]]></description>
				<content:encoded><![CDATA[<p><i>Here&#8217;s part 11 of the ongoing serialization of <cite>Refactoring HTML</cite>, also available from <a href="http://www.amazon.com/exec/obidos/ISBN=0321503635/ref=nosim/cafeaulaitA">Amazon</a>  and <a href="http://safari.oreilly.com/9780321552044">Safari</a>.</i></p>
<p><i>This part&#8217;s a little funny because really it deserves an entire book on its own, and that book has yet to be written. I didn&#8217;t have space or time to write a complete second book about test driven development of web sites and web applications, but perhaps this small piece will inspire someone else to do it. If not, maybe I&#8217;ll get to it one of these days. <img src='http://cafe.elharo.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </i></p>
<p>
In theory, refactoring should not break anything that isn’t already broken. In practice, it isn’t always so reliable. To some extent, the catalog later in this book shows you what changes you can safely make. However, both people and tools do make mistakes; and it’s always possible that refactoring will introduce new bugs. Thus, the refactoring process really needs a good automated test suite. After every refactoring, you’d like to be able to press a button and see at a glance whether anything broke.
</p>
<p>
Although test-driven development has been a massive success among traditional programmers, it is not yet so common among web developers, especially those working on the front end. In fact, any automated testing of web sites is probably the exception rather than the rule, especially when it comes to HTML. It is time for that to change. It is time for web developers to start to write and run test suites and to use test-driven development.
</p>
<p>
The basic test-driven development approach is as follows:
</p>
<ol>
<li>Write a test for a feature.</li>
<li>Code the simplest thing that can possibly work.</li>
<li>Run all tests.</li>
<li>If tests passed, goto 1.</li>
<li>Else, goto 2.</li>
</ol>
<p>
For refactoring purposes, it is very important that this process be as automatic as possible. In particular:
</p>
<ul>
<li>The test suite should not require any complicated setup. Ideally, you should be able to run it with the click of a button. You don’t want developers to skip running tests because they’re too hard to run.</li>
<li>The tests should be fast enough that they can be run frequently; ideally, they should take 90 seconds or less to run. You don’t want developers to skip running tests because they take too long.</li>
<li>The result must be pass or fail, and it should be blindingly obvious which it is. If the result is fail, the failed tests should generate more output explaining what failed. However, passing tests should generate no output at all, except perhaps for a message such as “All tests passed”. In particular, you want to avoid the common problem in which one or two failing tests get lost in a sea of output from passing tests.</li>
</ul>
<p>
Writing tests for web applications is harder than writing tests for classic applications. Part of this is because the tools for web application testing aren’t as mature as the tools for traditional application testing. Part of this is because any test that involves looking at something and figuring out whether it looks right is hard for a computer. (It’s easy for a person, but the goal is to remove people from the loop.) Thus, you may not achieve the perfect coverage you can in a Java or .NET application. Nonetheless, some testing is better than none, and you can in fact test quite a lot.
</p>
<p>
One thing you will discover is that refactoring your code to web standards such as XHTML is going to make testing a lot easier. Going forward, it is much easier to write tests for well-formed and valid XHTML pages than for malformed ones. This is because it is much easier to write code that consumes well-formed pages than malformed ones. It is much easier to see what the browser sees, because all browsers see the same thing in well-formed pages and different things in malformed ones. Thus, one benefit of refactoring is improving testability and making test-driven development possible in the first place. Indeed, with a lot of web sites that don’t already have tests, you may need to refactor them enough to make testing possible before moving forward.
</p>
<p>
You can use many tools to test web pages, ranging from decent to horrible and free to very expensive. Some of these are designed for programmers, some for web developers, and some for business domain experts. They include:
</p>
<ul>
<li>HtmlUnit</li>
<li>JsUnit</li>
<li>HttpUnit</li>
<li>JWebUnit</li>
<li>FitNesse</li>
<li>Selenium</li>
</ul>
<p>
In practice, the rough edges on these tools make it very helpful to have an experienced agile programmer develop the first few tests and the test framework. Once you have an automated test suite in place, it is usually easier to add more tests yourself.
</p>
<p><span id="more-276"></span></p>
<h3>JUnit</h3>
<p>
JUnit (<a href="http://www.junit.org/">http://www.junit.org/</a>) is the standard Java framework for unit testing, and the one on which a lot of the more specific frameworks such as HtmlUnit and HttpUnit are built. There’s no reason you can’t use it to test web applications, provided you can write Java code that pretends to be a browser. That’s actually not as hard as it sounds.
</p>
<p>
For example, one of the most basic tests you’ll want to run is one that tests whether each page on your site is well-formed. You can test this simply by parsing the page with an XML parser and seeing whether it throws any exceptions. Write one method to test each page on the site, and you have a very nice automated test suite for what we checked by hand in the previous section.
</p>
<p>
Listing 2.2 demonstrates a simple JUnit test that checks the well-formedness of my blog. All this code does is throw a URL at an XML parser and see whether it chokes. If it doesn’t, the test passes. This version requires Sun’s JDK 1.5 or later and JUnit 3.8 or later somewhere in the classpath. You may need to make some modifications to run this in other environments.
</p>
<p>Listing 2.2: A JUnit Test for Web Site Well-Formedness</p>
<pre>
import java.io.IOException;
import junit.framework.TestCase;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;

public class WellformednessTests extends TestCase {

    private XMLReader reader;
    
    public void setUp() throws SAXException {
      reader = XMLReaderFactory.createXMLReader(
        "com.sun.org.apache.xerces.internal.parsers.SAXParser");
    }

    public void testBlogIndex() throws SAXException, IOException {
      reader.parse("http://www.elharo.com/blog/");
    }
}
</pre>
<p>
You can run this test from inside an IDE such as Eclipse or NetBeans, or you can run it from the command line like so:
</p>
<p><samp>$ java -cp .:junit.jar junit.swingui.TestRunner WellformednessTests</samp>
</p>
<p>
If all tests pass, you’ll see a green bar as shown in Figure 2.3.
</p>
<p>
<img src='http://cafe.elharo.com/wp-content/uploads/2008/06/02junit.png' alt='Green Bar' /><br />
Figure 2.3: All tests pass.
</p>
<p>
To test additional pages for well-formedness, you simply add more methods, each of which looks exactly like <code>testBlogIndex</code>, just with a different URL. Of course, you can also write more complicated tests. You can test for validity by setting the http://xml.org/sax/features/validation feature on the parser and attaching an error handler that throws an exception if a validity error is detected.
</p>
<p>
You can use DOM, XOM, SAX, or some other API to load the page and inspect its contents. For instance, you could write a test that checks whether all links on a page are reachable. If you use TagSoup as the parser, you can even write these sorts of tests for non-well-formed HTML pages.
</p>
<p>
You can submit forms using the <code>HttpURLConnection</code> class or run JavaScript using the Rhino engine built into Java 6. This is all pretty low-level stuff, and it’s not trivial to do; but it’s absolutely possible to do it. You just have to roll up your sleeves and start coding.
</p>
<p>
If nondevelopers are making regular changes to your site, you can set up the test suite to run periodically with cron and to e-mail you if anything unexpectedly breaks. (It’s probably not reasonable to expect each author or designer to run the entire test suite before every check-in.) You can even run the suite continuously using a product such as Hudson or Cruise Control. However, that may fill your logs with a lot of uncountable test traffic, so you may wish to run this against the development server instead.
</p>
<p>
Many similar test frameworks are available for other languages and platforms: PyUnit for Python, CppUnit for C++, NUnit for .NET, and so forth. Collectively these go under the rubric xUnit. Whichever one you and your team are comfortable working with is fine for writing web test suites. The web server doesn’t care what language your tests are written in. As long as you have a one-button test harness and enough HTTP client support to write tests, you can do what needs to be done.
</p>
<h3>HtmlUnit</h3>
<p>HtmlUnit (<a href="http://htmlunit.sourceforge.net/">http://htmlunit.sourceforge.net/</a>) is an open source JUnit extension designed to test HTML pages. It will be most familiar and comfortable to Java programmers already using JUnit for test-driven development. HtmlUnit provides two main advantages over pure JUnit.
</p>
<p>
The <code>WebClient</code> class makes it much easier to pretend to be a web browser.
</p>
<p>
The <code>HTMLPage</code> class has methods for inspecting common parts of an HTML document.
</p>
<p>
For example, HtmlUnit will run JavaScript that’s specified by an <code>onLoad</code> handler before it returns the page to the client, just like a browser would. Simply loading the page with an XML parser as Listing 2.2 did would not run the JavaScript.
</p>
<p>
Listing 2.3 demonstrates the use of HtmlUnit to check that all the links on a page are not broken. I could have written this using a raw parser and DOM, but it would have been somewhat more complex. In particular, methods such as getAnchors to find all the a elements in a page are very helpful.
</p>
<p>
Listing 2.3: An HtmlUnit Test for a Page’s Links
</p>
<pre>
import java.io.IOException;
import java.net.*;
import java.util.*;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;

import junit.framework.TestCase;

public class LinkCheckTest extends TestCase {

    public void testBlogIndex() throws FailingHttpStatusCodeException, IOException {
        WebClient webClient = new WebClient();
        URL url = new URL("http://www.elharo.com/blog/");
        HtmlPage page = (HtmlPage) webClient.getPage(url);
        List links = page.getAnchors();
        Iterator iterator = links.iterator();
        while (iterator.hasNext()) {
          HtmlAnchor link = (HtmlAnchor) iterator.next();
          URL u = new URL(link.getHrefAttribute());
          // Check that we can download this page.
          // If we can't, getPage throws an exception and
          // the test fails.
          webClient.getPage(u);
      }
    }
}
</pre>
<p>
This test is more than a unit test. It checks all the links on a page, whereas a real unit test would check only one. Furthermore, it makes connections to external servers. That’s very unusual for a unit test. Still, this is a good test to have, and it will let us know that we need to fix our pages if an external site breaks links by reorganizing its pages.
</p>
<h3>HttpUnit</h3>
<p>
HttpUnit (<a href="http://httpunit.sourceforge.net/">http://httpunit.sourceforge.net/</a>) is another open source JUnit extension designed to test HTML pages. It is also best suited for Java programmers already using JUnit for test-driven development, and is in many ways quite similar to HtmlUnit. Some programmers prefer HttpUnit, and others prefer HtmlUnit. If there’s a difference between the two it’s that HttpUnit is somewhat lower-level. It tends to focus more on the raw HTTP connection whereas HtmlUnit more closely imitates a browser. HtmlUnit has somewhat better support for JavaScript, if that’s a concern. However, there’s certainly a lot of overlap between the two projects.
</p>
<p>
Listing 2.4 demonstrates an HttpUnit test that verifies that a page has exactly one H1 header, and that its text matches the web page’s title. That may not be a requirement for all pages, but it is a requirement for some. For instance, it would be a very apt requirement for a newspaper site.
</p>
<p>
Listing 2.4: An HttpUnit Test That Matches the Title to a Unique H1 Heading
</p>
<pre>import java.io.IOException;
import org.xml.sax.SAXException;
import com.meterware.httpunit.*;
import junit.framework.TestCase;

public class TitleChecker extends TestCase {

    public void testFormSubmission() throws IOException, SAXException {
        WebConversation wc = new WebConversation();
        WebResponse wr = wc.getResponse("http://www.elharo.com/blog/");
        HTMLElement[] h1 = wr.getElementsWithName("h1");
        assertEquals(1, h1.length);
        String title = wr.getTitle();
        assertEquals(title, h1[0].getText());
    }

}
</pre>
<p>
I could have written this test in HtmlUnit too, and I could have written Listing 2.3 with HttpUnit. Which one you use is mostly a matter of personal preference. Of course, these are hardly the only such frameworks. There are several more, including ones not written in Java. Use whichever one you like, but by all means use something.
</p>
<h3>JWebUnit</h3>
<p>
JWebUnit is a higher-level API that sits on top of HtmlUnit and JUnit. Generally, JWebUnit tests involve more assertions and less straight Java code. These tests are somewhat easier to write without a large amount of Java expertise, and they may be more accessible to a typical web developer. Furthermore, tests can very easily extend over multiple pages as you click links, submit forms, and in general follow an entire path through a web application.
</p>
<p>
Listing 2.5 demonstrates a JWebUnit test for the search engine on my web site. It fills in the search form on the main page and submits it. Then it checks that one of the expected results is present.
</p>
<p>
Listing 2.5: A JWebUnit Test for Submitting a Form
</p>
<pre>import junit.framework.TestCase;
import net.sourceforge.jwebunit.junit.*;

public class LinkChecker extends TestCase {
    private WebTester tester;
    
    public LinkChecker(String name) {
        super(name);
        tester = new WebTester();
        tester.getTestContext().setBaseUrl("http://www.elharo.com/");
    }

    public void testFormSubmission() {
        // start at this page
        tester.beginAt("/blog/");
        // check that the form we want is on the page
        tester.assertFormPresent("searchform");
        /// check that the input element we expect is present
        tester.assertFormElementPresent("s");
        // type something into the input element
        tester.setTextField("s", "Linux");
        // send the form
        tester.submit();
        // we're now on a different page; check that the
        // text on that page is as expected.
        tester.assertTextPresent("Windows Vista");
    }
}
</pre>
<h3>FitNesse</h3>
<p>
FitNesse (<a href="http://fitnesse.org/">http://fitnesse.org/</a>) is a Wiki designed to enable business users to write tests in table format. Business users like spreadsheets. The basic idea of FitNesse is that tests can be written as tables, much like a spreadsheet. Thus, FitNesse tests are not written in Java. Instead, they are written as a table in a Wiki.
</p>
<p>
You do need a programmer to install and configure FitNesse for your site. However, once it’s running and a few sample fixtures have been written, it is possible for savvy business users to write more tests. FitNesse works best in a pair environment, though, where one programmer and one business user can work together to define the business rules and write tests for them.
</p>
<p>
For web app acceptance testing, you install Joseph Bergin’s HtmlFixture (http://fitnesse.org/FitNesse.HtmlFixture). It too is based on HtmlUnit. It supplies instructions that are useful for testing web applications such as typing into forms, submitting forms, checking the text on a page, and so forth.
</p>
<p>
Listing 2.6 demonstrates a simple FitNesse test that checks the http-equiv meta tag in the head to make sure it’s properly specifying UTF-8. The first three lines set the classpath. Then, after a blank line, the next line identifies the type of fixture as an HtmlFixture. (There are several other kinds, but HtmlFixture is the common one for testing web applications.)
</p>
<p>
The external page at http://www.elharo.com/blog/ is then loaded. In this page, we focus on the element named meta that has an id attribute with the value charset. This will be the subject for our tests.
</p>
<p>
The test then looks at two attributes of this element. First it inspects the content attribute and asserts that its value is text/html; charset=utf-8. Next it checks the http-equiv attribute of the same element and asserts that its value is content-type.
</p>
<p>
Listing 2.6: A FitNesse Test for &lt;meta name=&#8221;charset&#8221; http-equiv=&#8221;Content-Type&#8221; content=&#8221;text/html; charset=UTF-8&#8243; />
</p>
<pre>
!path fitnesse.jar
!path htmlunit-1.5/lib/*.jar
!path htmlfixture20050422.jar

!|com.jbergin.HtmlFixture|
|http://www.elharo.com/blog/|
|Element Focus|charset |meta|
|Attribute |content |text/html; charset=utf-8|
|Attribute |http-equiv|content-type|
</pre>
<p>
This test would be embedded in a Wiki page. You can run it from a web browser just by clicking the Test button, as shown in Figure 2.4. If all of the assertions pass, and if nothing else goes wrong, the test will appear green after it is run. Otherwise, it will appear pink. You can use other Wiki markup elsewhere in the page to describe the test.
</p>
<p>
<img src='http://cafe.elharo.com/wp-content/uploads/2008/06/fitnesse.png' alt='testBlogIndex' /><br />
Figure 2.4: A FitNesse page
</p>
<h3>Selenium</h3>
<p>
Selenium is an open source browser-based test tool designed more for functional and acceptance testing than for unit testing. Unlike with HttpUnit and HtmlUnit, Selenium tests run directly inside the web browser. The page being tested is embedded in an iframe and the Selenium test code is written in JavaScript. It is mostly browser and platform independent, though the IDE for writing tests, shown in Figure 2.5, is limited to Firefox.
</p>
<p>
<img src='http://cafe.elharo.com/wp-content/uploads/2008/06/selenium.png' alt='Browser window' /><br />
Figure 2.5: The Selenium IDE
</p>
<p>
Although you can write tests manually in Selenium using remote control, it is really designed more as a traditional GUI record and playback tool. This makes it more suitable for testing an application that has already been written, and less suitable for doing test-driven development.
</p>
<p>
Selenium is likely to be more comfortable to front-end developers who are accustomed to working with JavaScript and HTML. It is also likely to be more palatable to professional testers because it’s similar to some of the client GUI testing tools they’re already familiar with.
</p>
<p>
Listing 2.7 demonstrates a Selenium test that verifies that www.elharo.com shows up in the first page of results from a Google search for “Elliotte”. This script was recorded in the Selenium IDE and then edited a little by hand. You can load it into and then run it from a web browser. Unlike the other examples given here, this is not Java code, and it does not require major programming skills to maintain. Selenium is more of a macro language than a programming language.
</p>
<p>
Listing 2.7: Test That elharo.com Is in the Top Search Results for Elliotte
</p>
<pre>&lt;html>
  &lt;head>
    &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    &lt;title>elharo.com is a top search results for Elliotte&lt;/title>
  &lt;/head>
  &lt;body>
    &lt;table cellpadding="1" cellspacing="1" border="1">
      &lt;thead>
        &lt;tr>&lt;td rowspan="1" colspan="3">New Test&lt;/td>&lt;/tr>
        &lt;/thead>&lt;tbody>
        &lt;tr>
        &lt;td>open&lt;/td>
        &lt;td>/&lt;/td>
        &lt;td>&lt;/td>
        &lt;/tr>
        &lt;tr>
        &lt;td>type&lt;/td>
        &lt;td>q&lt;/td>
        &lt;td>elliotte&lt;/td>
        &lt;/tr>
        &lt;tr>
        &lt;td>clickAndWait&lt;/td>
        &lt;td>btnG&lt;/td>
        &lt;td>&lt;/td>
        &lt;/tr>
        &lt;tr>
        &lt;td>verifyTextPresent&lt;/td>
        &lt;td>www.elharo.com/&lt;/td>
        &lt;td>&lt;/td>
        &lt;/tr>
    &lt;/tbody>&lt;/table>
  &lt;/body>
&lt;/html>
</pre>
<p>
Obviously, Listing 2.6 is a real HTML document. You can open this with the Selenium IDE in Firefox and then run the tests. Because the tests run directly inside the web browser, Selenium helps you find bugs that occur in only one browser or another. Given the wide variation in browsers that CSS, HTML, and JavaScript support this capability is very useful. HtmlUnit, HttpUnit, JWebUnit, and the like use their own JavaScript engines which do not always have the same behavior as the browsers’ engines. Selenium uses the browsers themselves, not imitations of them.
</p>
<p>
The IDE can also export the tests as C#, Java, Perl, Python, or Ruby code so that you can integrate Selenium tests into other environments. This is especially important for test automation. Listing 2.8 shows the same test as in Listing 2.7, but this time in Ruby. However, this will not necessarily catch all the cross-browser bugs you’ll find by running the tests directly in the browser.
</p>
<p>
Listing 2.8: Automated Test That elharo.com Is in the Top Search Results for Elliotte
</p>
<pre>
require "selenium"
require "test/unit"

class GoogleSearch < Test::Unit::TestCase
def setup
@verification_errors = []
if $selenium
@selenium = $selenium
else
@selenium = Selenium::SeleneseInterpreter.new("localhost",
4444, *firefox", "http://localhost:4444", 10000);
@selenium.start
end
@selenium.set_context("test_google_search", "info")
end
def teardown
@selenium.stop unless $selenium
assert_equal [], @verification_errors
end
def test_google_search
@selenium.open "/"
@selenium.type "q", "elliotte"
@selenium.click "btnG"
@selenium.wait_for_page_to_load "30000"
begin
assert @selenium.is_text_present("www.elharo.com/")
rescue Test::Unit::AssertionFailedError
@verification_errors << $!
end
end
end
</pre>
<h3>Getting Started with Tests<br />
</h3>
<p>
Because you’re refactoring, you already have a web site or application; and if it’s like most I’ve seen, it has limited, if any, front-end tests. Don’t let that discourage you. Pick the tool you like and start to write a few tests for some basic functionality. Any tests at all are better than none. At the early stages, testing is linear. Every test you write makes a noticeable improvement in your code coverage and quality. Don’t get bogged down thinking you have to test everything. That’s great if you can do it; but if you can’t, you can still do something.
</p>
<p>
Before refactoring a particular page, subdirectory, or path through a site, take an hour and write at least two or three tests for that section. If nothing else, these are smoke tests that will let you know if you totally muck up everything. You can expand on these later when you have time.
</p>
<p>
If you find a bug, by all means write a test for the bug before fixing it. That will help you know when you’ve fixed the bug, and it will prevent the bug from accidentally reoccurring in the future after other changes. Because front-end tests aren’t very unitary, it’s likely that this test will indirectly test other things besides the specific bit of buggy code.
</p>
<p>
Finally, for new features and new developments beyond refactoring, by all means write your tests first. This will guarantee that the new parts of the site are tested, and tests will often leak over into the older pages and scripts as well.
</p>
<p>
Automatic testing is critical to developing a robust, scalable application. Developing a test suite can seem daunting at first, but it’s worth doing. The first test is the hardest. Once you’ve set up your test framework and written your first test, subsequent tests will flow much more easily. Just as you can improve a site linearly through small, automatic refactorings that add up over time, so too can you improve your test suite by adding just a few tests a week. Sooner than you know, you’ll have a solid test suite that helps to ensure reliability by telling you when things are broken and showing you what to fix.</p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/testing/testing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Go Ahead. Break the Build!</title>
		<link>http://cafe.elharo.com/testing/go-ahead-break-the-build/</link>
		<comments>http://cafe.elharo.com/testing/go-ahead-break-the-build/#comments</comments>
		<pubDate>Wed, 10 Jan 2007 13:06:38 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/testing/go-ahead-break-the-build/</guid>
		<description><![CDATA[There&#8217;s a philosophy in extreme programing circles that one should never break the build. As soon as the build is broken, everything stops until it can be fixed again.1 Some teams even hand out &#8220;dunce caps&#8221; to a programmer who breaks the build. If by &#8220;build&#8221; you simply mean the compile-link-package cycle, then I tend [...]]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s a philosophy in extreme programing circles that <a href="http://jspwiki.org/wiki/DontBreakTheBuild">one should never break the build.</a> As soon as the build is broken, everything stops until it can be fixed again.<sup><a href="#f1">1</a></sup> Some teams even hand out &#8220;<a href="http://blogs.msdn.com/oldnewthing/archive/2005/12/06/500513.aspx">dunce caps</a>&#8221; to a programmer who breaks the build. </p>
<p>If by &#8220;build&#8221; you simply mean the compile-link-package cycle, then I tend to agree. Breaking the build is pretty serious. One of the advantages of extreme programming is that the increments of work are so small that you don&#8217;t get very far before discovering you&#8217;ve broken the build, so it&#8217;s relatively easy to fix. Integration is almost automatic rather than a painful, months long process. Avoiding coupling is also important to keep build times manageable. </p>
<p>However some systems define the build a little more broadly. They consider the build to include successful execution of all the unit tests. For example, <a href="http://maven.apache.org/">Maven</a> gives up if any unit test fails.<sup><a href="#footnote">*</a></sup> It will not create any subsequent targets such as a JAR file, if it can&#8217;t run unit tests. Ant doesn&#8217;t require this, but does allow this. All that&#8217;s necessary is declaring that the jar or zip target depends on the test target. </p>
<p>It&#8217;s not just open source either. Over at closed source vendor Atlassian, Charles Miller <a href="http://fishbowl.pastiche.org/2007/01/09/revenge_of_the_antitest">tells us</a>, &#8220;all our tools are predicated on tests that start green and stay green. &#8221; In fact, a failing test is so damaging to them, that he actually advocates writing tests that pass if the bug isn&#8217;t fixed and fails if it is.  That&#8217;s a recipe for disaster if I ever heard one. Five years down the line some new programmer is going to finally fix the line of code that causes the bug, and then carefully reintroduce the bug to get back to the green bar.</p>
<p>This is where I part company from the most extreme of the extremists. If building includes passing all unit tests, then it is often acceptable and even desirable to break the build.<br />
<span id="more-102"></span></p>
<p>There are several reasons you may choose to introduce a failing test, thus breaking the build; but not fix it immediately. First of all, the person who writes the failing test may not be the best qualified to fix it. For instance, the person who finds the bug and writes the test could be a tester rather than a programmer; or they could be a programmer who&#8217;s working on a different piece of the code. Sure, they can fix the bug if they happen to see how to; but if they don&#8217;t, it&#8217;s still valuable to commit the unit test that proves the bug&#8217;s existence.</p>
<p>Even if the person who finds the bug is responsible for fixing it, the fix may not be apparent. Some bugs require a lot of work. Some bugs require only a little work, but may still require a night to sleep on it before the fix becomes obvious. Sometimes it&#8217;s a 30 minute fix, but the programmer only has 15 minutes before they have to pick up their daughter from football practice. For whatever reason, not every bug can be fixed immediately. It&#8217;s still better to commit the failing unit test so it doesn&#8217;t get forgotten in the future, even if that &#8220;breaks&#8221; the build.</p>
<p>Sometimes failing tests are beyond programmer control. For instance, <a href="http://www.xom.nu/">XOM</a> has one unit test that passes on Windows and Linux, but fails on the Mac. This particular test runs across a bug in Apple&#8217;s VM involving files whose name contain Unicode characters from outside the Basic Multilingual Plane. There&#8217;s not a lot I can do to fix that; but I shouldn&#8217;t pretend it&#8217;s not a problem either. </p>
<p>All too often projects are in denial about their bugs. Rather than accept clear evidence of a bug, they do anything they can to deny it. Refusing to allow the build to break, and then defining a test failure as build breakage, is just one example of this pathology. Recognizing, identifying, and reproducing a bug with a well-defined unit test is a valuable contribution. It should be accepted gladly, not met with hostility and an insistence that the reporter immediately provide a patch.</p>
<hr />
<span class="footnote"><sup><a name="f1">1</a></sup> <a href="http://www.joelonsoftware.com/articles/fog0000000023.html">Joel Spolsky</a>: &#8220;If a daily build is broken, you run the risk of stopping the whole team. Stop everything and keep rebuilding until it&#8217;s fixed. Some days, you may have multiple daily builds.&#8221; </p>
<p><span class="footnote"><sup><a name="footnote">2</a></sup> You can tell Maven to exclude  specific failing tests from your project.xml by listing the failing tests in an <code>excludes</code> element like so:</span></p>
<pre><code>    &lt;unitTest>
      &lt;includes>
        &lt;include>**/*Test.java&lt;/include>
      &lt;/includes>
      
      &lt;excludes>
        &lt;!-- currently broken -->
        &lt;exclude>org/jaxen/test/JDOMXPathTest.java&lt;/exclude>
      &lt;/excludes>

    &lt;/unitTest></code></pre>
<p>You can also tell Maven not to run the unit tests using the command-line options <code>maven.test.skip=true</code> to skip the unit tests or <code>maven.test.failure.ignore=true</code> to run the tests but not stop if a test fails. However these are just hacks to get around what Maven really wants to do: run all the unit tests and fail the build if any fail. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/testing/go-ahead-break-the-build/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Test Your Code, Please!</title>
		<link>http://cafe.elharo.com/testing/test-your-code-please/</link>
		<comments>http://cafe.elharo.com/testing/test-your-code-please/#comments</comments>
		<pubDate>Fri, 22 Dec 2006 09:31:12 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/testing/test-your-code-please/</guid>
		<description><![CDATA[No this isn&#8217;t another rant about agile programming or test-driven development or test first programming. There&#8217;s a depressing phenomenon in some open source projects (including Jaxen and PHP) where a programmer goes off in a corner, gets a cool idea, writes it up, contributes it, has it checked in, ships it to millions of users; [...]]]></description>
				<content:encoded><![CDATA[<p>No this isn&#8217;t another rant about agile programming or test-driven development or test first programming. There&#8217;s a depressing phenomenon in some open source projects (including Jaxen and PHP) where a programmer goes off in a corner, gets a cool idea, writes it up, contributes it, has it checked in, ships it to millions of users; one of whom has the distinct pleasure of being the first to ever actually <em>use</em> this code. </p>
<p>I am getting really tired of discovering code that is broken by design; not merely buggy but partially to completely non-functional and unable to be fixed. The <a href="http://archive.jaxen.codehaus.org/dev/426E28B3.7010907%40metalab.unc.edu">worst case I ever saw</a> was in Jaxen where I once spent two days trying to write unit tests for a package that had been contributed years ago (without any tests of course) and banging my head against the wall trying to figure out how to reach that code. Only after this time, did careful analysis of code paths reveal that the code could never be reached, no matter what. It never could have been reached.<br />
<span id="more-158"></span></p>
<p>More recently I&#8217;m working with some libraries in PHP copied from libxml which itself copied from .NET. Since the developers were only copying from other APIs, I guess they didn&#8217;t think it might make sense to stop and try to write a little sample code that used their libraries and see if it worked. In any case, the libraries in both libxml and PHP, though more functional than Jaxen&#8217;s <code>org.jaxen.dom.html</code> package, are full of public but unreachable code. They contain constants for node types that will never be supplied by the parser. They are poorly documented because the designers just copied rather than creating from scratch. Half the questions I have end up with me referred back to the .NET API docs and hoping that the copy was a faithful one. Even the original programmers no longer remember exactly how it works.</p>
<p>Of course like <a href="http://memory-alpha.org/en/wiki/Mariposan">Mariposan clones</a> on Star Trek <acronym>TNG</acronym>, it gets worse the further away from the source material you get. The .NET APIs are a little broken. The libxml APIs that copied the .NET APIs are somewhat broken. The PHP APIs on top of libxml are a lot broken. They miss basic things that libxml can do like detecting the end of the document, or recognizing errors. (The specific mistake was converting a ternary int return type into a binary boolean type in the translation.) </p>
<p>However, it&#8217;s not the bad translation and adaptation that gets me. It&#8217;s that these flaws are really, really obvious. Anybody who sits down to write almost any code that uses these APIs is going to hit these problems almost immediately. Unit tests might not catch the design flaws. After all, unit tests only verify that the code is doing what the programmer says it does. They don&#8217;t verify that the programmer has chosen to make the code do the right thing. </p>
<p>We cannot  rely on unit tests alone. We also need to actually use the API before committing to it and shipping it. Try writing some non-trivial programs, and see how the API fares. Only by actually using the API in anger can you tell where it works and where it fails. You can find out what&#8217;s right, what&#8217;s wrong, and what&#8217;s missing. If you pay attention, you&#8217;ll also find out what it includes that you don&#8217;t need and that you can therefore remove. (Smaller is better.)</p>
<p>When I designed <a href="http://www.xom.nu/">XOM</a>, I took my first pass at the API, and used it to reimplement every example from <a href="http://www.cafeconleche.org/books/xmljava/">Processing XML with Java</a> in XOM. I also implemented some additional XML specifications such as Canonical XML and XInclude on top of the core libraries but in separate packages to make sure the core libraries offered enough public access to build other pieces of infrastrucutre on top of them.  </p>
<p>The results were surprising. Several methods I thought were essential didn&#8217;t actually get called anywhere. and I could take them out. I also found quite a few things I&#8217;d forgotten to do, that I obviously needed. Later I released the library to other users, who found more things I&#8217;d left out, as well as other flaws. Only after I was confident the library had been put to some real use did I declare it finished and freeze the API. </p>
<p>Of course, I knew that I would have to add more features in the future; but slow and steady wins the race. I don&#8217;t add anything to XOM unless someone actually asks for it and provides a clear use case. Even if the feature is obviously a good thing in itself, I can&#8217;t be sure it&#8217;s designed right unless I can see how the feature is used. </p>
<p>As I write this, I notice someone is gearing up to make the same damn mistake, but this time in Ruby. Laurent Sansonetti <a href="http://chopine.be/lrz/diary/2006-11-29_XML-Reader.html">writes</a>:</p>
<blockquote cite="http://chopine.be/lrz/diary/2006-11-29_XML-Reader.html"><p>
For the curious, here is the patch to bring the xmlTextReader API to the libxml-ruby project, that I used in my previous hack. The patch has been generated from CVS HEAD.</p>
<p>Everything valuable should be wrapped, but note that the test cases are not complete and that there is no documentation (RDoc comments) yet. As the libxml-ruby guys were interested in it I just sent it to them as well.</p></blockquote>
<p>Laurent, if you don&#8217;t have test cases or documentation, it isn&#8217;t done! Please don&#8217;t submit it. </p>
<p>Contributors, please don&#8217;t send in patches that add new features and new API unless you&#8217;ve actually used them first. Project maintainers: don&#8217;t accept code contributions unless there&#8217;s a clear use case and evidence of actual use. Otherwise you&#8217;re not really maintaining, just being a pack rat. When in doubt, leave it out. It is better to leave out a feature in this release than commit to supporting a broken API for the indefinite future. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/testing/test-your-code-please/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Negative Experimental Programming</title>
		<link>http://cafe.elharo.com/testing/negative-experimental-programming/</link>
		<comments>http://cafe.elharo.com/testing/negative-experimental-programming/#comments</comments>
		<pubDate>Thu, 21 Sep 2006 11:00:53 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/testing/negative-experimental-programming/</guid>
		<description><![CDATA[I&#8217;ve previously written about the benefits of experimental programming: fixing code until all tests pass without necessarily understanding at a theoretical level why they pass. This scares the bejeezus out of a lot of developers, but I&#8217;m convinced it&#8217;s going to be increasingly necessary as software grows more and more complex. The whole field of [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve previously written about the benefits of <a href="http://cafe.elharo.com/java/experimental-programming/">experimental programming</a>: fixing code until all tests pass without necessarily understanding at a theoretical level why they pass. This scares the bejeezus out of a lot of developers, but I&#8217;m convinced  it&#8217;s going to be increasingly necessary as software grows more and more complex. The whole field of <a href="http://en.wikipedia.org/wiki/Genetic_algorithms">genetic algorithms</a> is just an extreme example of this.  <a href="http://en.wikipedia.org/wiki/Simulated_annealing">Simulated annealing</a> is another. However those techniques are primarily used by scientists who are accustomed to learning by experiment before they have a full and complete understanding of the underlying principles. Computer scientists are temperamentally closer to mathematicians, who almost never do experiments; and who certainly don&#8217;t trust the results of an experiment unless they can prove it theoretically. </p>
<p>However, perhaps it&#8217;s possible to introduce experimental programming in a slightly less controversial form. While many programmers may be unwilling to accept it as positive evidence of program correctness, it can offer undeniable evidence of program failure. This was recently brought to mind by a <a href="http://jira.codehaus.org/browse/JAXEN-158">bug</a> I was trying to fix in Jaxen.<br />
<span id="more-135"></span></p>
<p>Dominic Krupp had reported the bug on the Jaxen user mailing list. I was  skeptical at first, but he had an executable test case so I couldn&#8217;t really deny it. As Joel Spolsky <a href="http://joelonsoftware.com/articles/FieldGuidetoDevelopers.html">writes</a>,</p>
<blockquote cite="http://joelonsoftware.com/articles/FieldGuidetoDevelopers.html"><div>
Programmers have very well-honed senses of justice. Code either works, or it doesn&#8217;t. There&#8217;s no sense in arguing whether a bug exists, since you can test the code and find out. The world of programming is very just and very strictly ordered and a heck of a lot of people go into programming in the first place because they prefer to spend their time in a just, orderly place, a strict meritocracy where you can win any debate simply by being <em>right</em>.
</div>
</blockquote>
<p>I rewrote Krupp&#8217;s test case as a JUnit test and added it to our test suite. Though the bug was now obvious the fix was not, so the first step was to isolate the problem. I figured the problem would either be in the Jaxen core or in the JDOM specific code. To find out, I rewrote the test using DOM rather than JDOM. That test passed, which convinced me the bug was very likely in the JDOM-part of the code, and that&#8217;s where I should begin looking. Note that I still didn&#8217;t understand why the bug existed; but experiment gave me useful information anyway.</p>
<p>I then began single stepping through the test case with the Eclipse debugger. Jaxen&#8217;s code is pretty involved, and even a simple XPath expression can involve many loops and quite deep method hierarchies. Furthermore, many methods are called multiple times from multiple places so break points aren&#8217;t quite as useful. I either missed the bug or neglected to enter the method where the bug resided. I still didn&#8217;t understand how this bug could arise, or have a good idea about where to look to fix it, so I put the problem aside for a while. </p>
<p>Next, the original reporter proposed a fix. Now I&#8217;m in a quandary. How do I judge his patch since I don&#8217;t understand the bug. Furthermore, looking at the patch, it&#8217;s not obvious to me how it would fix the problem. But this is where experimental programming comes to the rescue again. <strong>I don&#8217;t need to understand it!</strong> All I have to do is plug it in and see if the tests pass. The first results were positive. It did indeed fix the bug he reported. The next resuls were not. It broke 21 other unit tests that were passing without it. Consequently I could reject the patch, still without actually understanding it. I don&#8217;t need to explain how it&#8217;s broken. I just need to prove that it is by experiment and test.</p>
<p>You can learn something, even from an incorrect patch. I wasn&#8217;t even looking at the method Krupp patched to fix the bug. His patch may have failed, but it gives me new insight into the problem. Perhaps a slight modification of his patch might still fix the problem without breaking 21 other things. I&#8217;ll have to experiment and see. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/testing/negative-experimental-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Everything, No Matter How Simple</title>
		<link>http://cafe.elharo.com/blogroll/test-everything-no-matter-how-simple/</link>
		<comments>http://cafe.elharo.com/blogroll/test-everything-no-matter-how-simple/#comments</comments>
		<pubDate>Tue, 22 Aug 2006 11:18:44 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/java/test-everything-no-matter-how-simple/</guid>
		<description><![CDATA[There are many reasons to write your tests first. An oft unmentioned benefit is that it makes the programmer stop and think about what they&#8217;re doing. More often than you&#8217;d expect, the obvious fix is not the right answer; and writing the test first can reveal that. For example, recently Wolfgang Hoschek pointed out that [...]]]></description>
				<content:encoded><![CDATA[<p>There are many reasons to write your tests first. An oft unmentioned benefit is that it makes the programmer stop and think about what they&#8217;re doing. More often than you&#8217;d expect, the obvious fix is not the right answer; and writing the test first can reveal that.</p>
<p>For example, recently Wolfgang Hoschek pointed out that in XOM the <code>Attribute</code> class&#8217;s <code>setType()</code> method  was failing to check for null. Once he pointed it out, it was an obvious problem so I opened up Eclipse and got ready to fix it:<br />
<span id="more-129"></span></p>
<pre><code>      private void _setType(Type type) {
        this.type = type;
    }</code></pre>
<p>The fix was trivial:</p>
<pre><code>      private void _setType(Type type) {
        if (type == null) {
          throw new NullPointerException("Null attribute type");
        }
        this.type = type;
    }</code></pre>
<p>Fortunately I stopped myself. Even with a known and obvious bug, one shouldn&#8217;t fix it without first writing a test case, so I did:</p>
<pre><code>    public void testNullType() {
        try {
            a1.setType(null);
            fail("Didn't throw NullPointerException");
        }
        catch (NullPointerException success) {
            assertNotNull(success.getMessage());  
        }
    }</code></pre>
<p>And it&#8217;s a good thing I did to because it was only when writing the test case that I realized I was patching the wrong method. The check belonged in <code>setType()</code>, not <code>_setType()</code>. The former is the public method. The latter is a package-access method for internal use that saves time by doing less checking in situations where the data is already known to be good. Had I written the code without a test case, I wouldn&#8217;t have noticed that I was slowing down XOM by putting the check in the wrong place. </p>
<p>Even if I hadn&#8217;t been about to make the wrong fix, it still would have made sense to write the test. The test is not just about writing the code now. It&#8217;s about documenting the proper behavior of the code for future programmers. Once the test is in the test suite, it&#8217;s clearly documented that throwing a <code>NullPointerException</code> when the argument is null is the expected and contracted behavior. A future developer, whether me or someone else, can still change it if they want to, of course. However, they&#8217;d have to make a deliberate and carefully considered decision to do so. it won&#8217;t be changed by accident or oversight. It is unlikely to become a regression.</p>
<p>No code should be untested. Even the simplest code (like this almost trivial setter method) can have bugs, so even the simplest code needs to be tested. No exceptions! No code is too simple to fail. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/blogroll/test-everything-no-matter-how-simple/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How do you specify an exponentiation function with a test?</title>
		<link>http://cafe.elharo.com/blogroll/how-do-you-specify-an-exponentiation-function-with-a-test/</link>
		<comments>http://cafe.elharo.com/blogroll/how-do-you-specify-an-exponentiation-function-with-a-test/#comments</comments>
		<pubDate>Sat, 08 Jul 2006 11:31:27 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/java/how-do-you-specify-an-exponentiation-function-with-a-test/</guid>
		<description><![CDATA[While it may be a slightly too extreme position to say that tests are the only spec, I think it is absolutely reasonable to consider tests to be a major part of the spec. Indeed a specification without normative test cases is far less likely to be implemented correctly and interoperably than one with a [...]]]></description>
				<content:encoded><![CDATA[<p>While it may be a slightly too extreme position to say that tests are the <em>only</em> spec, I think it is absolutely reasonable to consider tests to be a major part of the spec. Indeed a specification without normative test cases is far less likely to be implemented correctly and interoperably than one with a solid normative test suite. The more exhaustive the test suite is, the easier it is to write a conforming correct implementation.</p>
<p>Cedric Beust <a href="http://beust.com/weblog/archives/000392.html">presents the question</a>, &#8220;how do you specify an exponentiation function with a test?&#8221; as a counterexample to tests as specs. Actually I don&#8217;t think it&#8217;s all that hard. Here&#8217;s one example:<br />
<span id="more-115"></span></p>
<pre><code>import junit.framework.TestCase;

public class ExponentiationTest extends TestCase {

    public void testZero() {
        double x = Exponent.calculate(10, 0);
        assertEquals(1, x, 0.0);
    }
    
    public void testOne() {
        double x = Exponent.calculate(10, 1);
        assertEquals(10.0, x, 0.0);
    }
    
    public void testNegativeBase() {
        double x = Exponent.calculate(-1, 2);
        assertEquals(1, x, 0.0);
    }
    
    public void testBigExponentWithOneBase() {
        double x = Exponent.calculate(1, 2000);
        assertEquals(1, x, 0.0);
    }
    
    public void testSquare() {
        double x = Exponent.calculate(10, 2);
        assertEquals(100, x, 0.0);
    }
    
   public void testSquareRoot() {
        double x = Exponent.calculate(100.0, 0.5);
        assertEquals(10, x, 0.0);
    }
    
   public void testFractionalBase() {
        double x = Exponent.calculate(0.5, 2);
        assertEquals(0.25, x, 0.0);
    }
    
   public void testNegativePower() {
        double x = Exponent.calculate(100.0, -1);
        assertEquals(0.01, x, 0.0);
    }
    
   public void testZeroZero() {
        double x = Exponent.calculate(0, 0);
        assertTrue(Double.isNaN(x));
    }
    
}
</code></pre>
<p>Clearly you could expand on this short example with more test cases, and if I were writing this for real code I would. In particular I&#8217;d have to think hard about what happens when the results overflow the bounds of a double. But I think this makes the point.</p>
<p>Probably if I were really writing a spec, I wouldn&#8217;t define these test cases as compilable code like this. I&#8217;d likely just list the expected input, outputs, and tolerances; and then write a tool to convert them to actual tests. However that&#8217;s an implementation detail.</p>
<p>P.S. These test cases found what is at least arguably a bug (or perhaps a design defect) in Java&#8217;s <code>Math.pow()</code> method. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/blogroll/how-do-you-specify-an-exponentiation-function-with-a-test/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Specification by Colonization</title>
		<link>http://cafe.elharo.com/blogroll/specification-by-colonization/</link>
		<comments>http://cafe.elharo.com/blogroll/specification-by-colonization/#comments</comments>
		<pubDate>Mon, 29 May 2006 12:13:41 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/java/specification-by-colonization/</guid>
		<description><![CDATA[The final chapter of the recently published Java I/O, 2nd edition focuses on the Java Bluetooth API. Like about half of what&#8217;s going on in Java today the Java Bluetooth API was defined and developed in the Java Community Process (JCP). I spend a lot of energy criticizing the W3C process, but compared to the [...]]]></description>
				<content:encoded><![CDATA[<p>The final chapter of the recently published <a href="http://www.cafeaulati.org/books/javaio2/">Java I/O, 2nd edition</a> focuses on the Java Bluetooth API. Like about half of what&#8217;s going on in Java today the Java Bluetooth API was defined and developed in the Java Community Process (<acronym title="Java Community Process">JCP</acronym>). I spend a lot of energy criticizing the W3C process, but compared to the <acronym title="Java Community Process">JCP</acronym>, it&#8217;s a model of sanity.<br />
<span id="more-105"></span></p>
<p>At first glance <acronym title="Java Community Process">JCP</acronym> specs look OK; but once you really start digging into one at the level you need to write a book about one or implement it, you rapidly discover huge areas of unspecified behavior.  Then when I write about it, I have to test the implementations to see what they actually do. I rarely test more than one or two, and then I write down its behavior as what happens. Then other people come along and read my book to figure out what they&#8217;re supposed to. The behavior that gets fixed is chosen almost by accident. </p>
<p>I blame this on the <acronym title="Java Community Process">JCP</acronym>&#8216;s culture of implementation as specification. Many specs are nothing but the JavaDoc compiled from the reference implementation and pointlessly encoded in <acronym>PDF</acronym> and/or a zip file. The specs are thus only marginally better than documentation for a typical software product (i.e. slightly better than wretched).</p>
<p>By contrast W3C specs are normally written independently of implementations. Then the working group checks to see if the specs can actually be implemented in a compatible fashion. Since they require two implementations of each feature, this tends to identify any grey areas in the spec, especially when the people doing the implementing are not the people who wrote the spec. </p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/blogroll/specification-by-colonization/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Final == Good</title>
		<link>http://cafe.elharo.com/blogroll/final-good/</link>
		<comments>http://cafe.elharo.com/blogroll/final-good/#comments</comments>
		<pubDate>Wed, 24 May 2006 12:28:53 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/</guid>
		<description><![CDATA[Here&#8217;s an interesting article that is totally, completely 180 degrees wrong. I&#8217;ve said this before, and I&#8217;ve said it again, but I&#8217;ll say it one more time: final should be the default. Java&#8217;s mistake was not that it allowed classes to be final. It was making final a keyword you had to explicitly request rather [...]]]></description>
				<content:encoded><![CDATA[<p> Here&#8217;s an <a href="http://blogs.objectmentor.com/ArticleS.MichaelFeathers.ItsTimeToDeprecateFinal">interesting article</a> that is totally, completely 180 degrees wrong. I&#8217;ve <a href="http://www.xom.nu/designprinciples.xhtml#d0e161">said this before</a>, and <a href="http://www.artima.com/intv/airbags2.html">I&#8217;ve said it again</a>, but  I&#8217;ll say it one more time: <code>final</code> should be the default. Java&#8217;s mistake was not that it allowed classes to be final. It was making <code>final</code> a keyword you had to explicitly request rather than making finality the default and adding a <code>subclassable</code> keyword to change the default for those few classes that genuinely need to be nonfinal. The lack of finality has created a huge, brittle, dangerously breakable infrastructure in the world of Java class libraries.</p>
<p><span id="more-104"></span></p>
<p> The latest shot from the <a href="http://www.cincomsmalltalk.com/blog/blogView?showComments=true&#038;entry=3325667363">final-haters</a> is a false claim that finality somehow prevents unit testing. To paraphrase Henry S. Thompson, I hate to move a direct negative, <strong>but no!</strong> There is nothing in finality that prevents unit testing, and I don&#8217;t know why people claim it does. I&#8217;ve had zero trouble testing final classes in my own work. I suppose it makes writing mock classes a little trickier, but I&#8217;m not sure that&#8217;s a bad thing. I much prefer to test the real classes and the real interactions that show what really happens rather than what the mock designer thinks will happen. Bugs aren&#8217;t always where you expect them to be. And even if finality did somehow interfere with unit testing, breaking the API to support the tests is a clear case of the tail wagging the dog. The tests exist to serve the code, not the other way around. </p>
<p> By way of contrast, although I&#8217;m careful to unit test subclassing for my nonfinal classes, I rarely encounter any other projects and libraries where that&#8217;s done. I&#8217;d venture to say that classes that allow their methods to be overridden rarely test that scenario in any way at all. Ditto for testing protected methods.</p>
<p> I will back up a little bit. It&#8217;s really only overriding methods that bothers me. I don&#8217;t have any particular objection to adding methods to a subclass. Probably the default should be to make all methods <code>final</code> unless they&#8217;re explicitly tagged as overridable. If that were done, you&#8217;d rarely need <code>final</code> on classes. However methods should be allowed to be overridden only after much careful thought, planning, and testing. </p>
<p>One final point: <code>final</code> is the safe, conservative choice. Should you mark a class or method final, and later discover a need to subclass/override it, you can remove the finality without breaking anyone&#8217;s code. You cannot go the other way. Once you&#8217;ve published a class that&#8217;s non-final you have to consider the possibility that someone, somewhere is subclassing it. Marking it final now risks breaking people&#8217;s running code and working systems. </p>
<p>One of the principles of exteme programming is to make the simplest change that could possibly work. Final is simpler than non-final. Final commits you to less. If you need a class to be non-final, fine. But please don&#8217;t make classes non-final by default.</p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/blogroll/final-good/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>The Nastiest Bug</title>
		<link>http://cafe.elharo.com/blogroll/the-nastiest-bug/</link>
		<comments>http://cafe.elharo.com/blogroll/the-nastiest-bug/#comments</comments>
		<pubDate>Thu, 02 Mar 2006 20:22:51 +0000</pubDate>
		<dc:creator>Elliotte Rusty Harold</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://minicafe.elharo.com/java/the-nastiest-bug/</guid>
		<description><![CDATA[There&#8217;s one trap I fall into repeatedly while doing software development of any kind: testing, debugging, coding, documenting, anything. And it happens in every language I&#8217;ve ever worked in: Java, C++, Perl, CSS, HTML, XML, etc. The only difference is how much time I waste tracking down the bug. I have this on my mind [...]]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s one trap I fall into repeatedly while doing software development of any kind: testing, debugging, coding, documenting, anything. And it happens in every language I&#8217;ve ever worked in: Java, C++, Perl, CSS, HTML, XML, etc. The only difference is how much time I waste tracking down the bug. </p>
<p>I have this on my mind now because I just lost at least half an hour to this while working on the CSS stylesheet for this very web site. I have had many students show up during my office hours for help with debugging this problem. I have had at least one company pay me lots of money to fix this problem for them (though they didn&#8217;t know this was their bug or they wouldn&#8217;t have needed to call me in the first place). I can virtually guarantee you&#8217;ve made this mistake too. What is the mistake? </p>
<p><em>Editing the Wrong File </em><br />
<span id="more-67"></span></p>
<p>The problem usually occurs when there are two files named Navigator.java, or wp-admin.css or prices.pl, or whatever. More often than not, they are different versions of the same file. Usually they&#8217;re in different directories. Maybe you&#8217;ve opened one from a backup directory, or you&#8217;ve accidentally saved the file onto your desktop instead of your src directory. Sometimes there are entirely separate copies of the source tree. (That&#8217;s what happened to me today. I was actually editing the CSS file for The Cafes, but loading the one from Mokka mit Schlag in my browser.)</p>
<p>This mistake is so obvious we rarely talk about it. Once you realize that&#8217;s what you&#8217;re doing, the fix is totally obvious. You feel like a bonehead, fix the problem, and move on; at least until the next time it happens. Certainly no one wants to stand up and admit they&#8217;ve done this. It is an incredibly stupid mistake, one only a bonehead could make more than once. At least it feels like that to me every time I make it, which is at least once a month. </p>
<p>Until you realize what you&#8217;re doing, this is the most frustrating bug imaginable. It usually happens to me during debugging or iterative development. I intend to make a small change and verify that the feature is added or the bug is fixed. I make the change and run the test. (Whether the test is manual or automated doesn&#8217;t matter here.) Nothing has changed.  </p>
<p>&#8220;That&#8217;s funny,&#8221; I think. I look at the code again and twiddle it a little bit. Still nothing. </p>
<p>I try something else. Nothing. </p>
<p>I back out the edit and start over. Nothing.</p>
<p>I start digging deeper, and trying to figure out how the really obvious piece of code could possibly not be doing what it is obviously doing. Maybe I set a breakpoint; then run the code in the debugger. If I&#8217;m lucky the breakpoint isn&#8217;t reached. You think that would tell me what the problem is, but it rarely does. My usual reaction is, &#8220;Hmm, I must have accidentally hit Run  instead of Debug. let&#8217;s try that again.&#8221; So I run the code in the debugger a second time. Still nothing.</p>
<p>At this point, I&#8217;m getting very frustrated. Sometimes I&#8217;ll drop out of my IDE to the command line and try it there. Sometimes that will actually work if the command line is picking up different files than the IDE. Sometimes it won&#8217;t.</p>
<p>Sooner or later (but later more than sooner) I finally realize what the problem is. I slap myself on the head and move on. The problem is fixed for the moment, but this keeps happening!</p>
<p>Is there any way to avoid this? I am convinced that the programming community is losing person-years of productivity to this mistake. Pair programming doesn&#8217;t help. I&#8217;ve absolutely been half of pairs where both pairs of eyes were totally focused on looking for bugs in the wrong file. IDEs don&#8217;t help. The fact that they often need their own copy of the source tree makes the problem worse rather than better. Ditto for source code control systems. The problem is at its worst in server side environments because the need to deploy the compiled archive introduces another step where the wrong file can replace the right one. Worse yet, the symptoms of this bug in a server side environment look very much like a failure to reload a compiled class or restart the server, even if that&#8217;s not what&#8217;s happening at all. </p>
<p>This is such an incredibly dumb bug there must be a way to prevent it, but for the life of me I can&#8217;t think of one. Ideas?</p>
]]></content:encoded>
			<wfw:commentRss>http://cafe.elharo.com/blogroll/the-nastiest-bug/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
