HTML and CSS Reference
fixture) that itself loads the libraries to test, along with the unit tests and the testing
framework. Other types of test runners can run in other environments, e.g., using
Mozilla's Rhino implementation to run tests on the command line. What kind of
test runner is suitable to test a specific application depends on whether it is a client-
side application, server-side, or maybe even a browser plugin (an example of which
would be FireUnit, a unit testing framework that uses Firebug and is suitable for
developing Firefox plugins).
A related concern is the test report. Clear fail/success status is vital to the
test-driven development process, and clear feedback with details when tests fail or
have errors is needed to easily handle them as they occur. Ideally, the test runner
should produce test results that are easily integrated with continuous integration
Additionally, some sort of plugin architecture for the test runner can enable us
to gather metrics from testing, or otherwise allow us to extend the runner to improve
the workflow. An example of such a plugin is the test coverage report. A coverage
report shows how well the test suite covers the system by measuring how many lines
in production code are executed by tests. Note that 100% coverage does not imply
that every thinkable test is written, but rather that the test suite executes each and
every line of production code. Even with 100% coverage, certain sets of input can
still break the code—it cannot guarantee the absence of, e.g., missing error handling.
Coverage reports are useful to find code that is not being exercised by tests.
A rich set of assertions can really boost the expressiveness of tests. Given that a good
unit test clearly states its intent, this is a massive boon. It's a lot easier to spot what
a test is targeting if it compares two values with assertEqual(expected,
actual) rather than with assert(expected == actual) . Although
assert is all we really need to get the job done, more specific assertions make
test code easier to read, easier to maintain, and easier to debug.
Assertions is one aspect where an exact port of the xUnit framework design
from, e.g., Java leaves a little to be desired. To achieve good expressiveness in tests,
it's helpful to have assertions tailored to specific language features, for instance,
and infinity . Many other assertions can be provided to better support testing
tions like those mentioned are easy to write piggybacking a general purpose assert
(or, as is common, a fail method that can be called when the assertion does not