Testability Explorer
Testability Explorer is a Java-based library to validate how testable is your application. It analyses Java bytecode and computes how difficult it will be to write unit tests for the code. It attempts to help you quantitatively determine how hard your code is to test, and where to focus to make it more testable. Although it may not seem so useful at first, it's a handy tool for several reasons:
- Testable code is usually well designed code
- Helps to guide you when refactoring your application
- It integrates with Maven and Ant, running automatically (no need to remember to run it)
- Enforcing testable code helps your continuous integration process
Running the application
Download the zip package with the shell script in it, uncompress it an run it with:
$ testability.sh [classes_and_packages] [-cp classpath] [options]At least one of classes_and_packages or -cp is required.
An alternative is to download the jar and launch it using java -jar, as in fact the shell script just does that. Know that the application tests only jars or class files, not java files. It runs over your already compiled (bytecode) classes.
Running with Maven
The Maven plugin is not yet released to the Maven central repository. To use it, you'll need to build it from source:
$ svn checkout http://testability-explorer.googlecode.com/svn/trunk/ testability-explorer$ cd testability-explorer$ mvn install
Now you can add it to your Maven pom.xml:
group id: com.google.testability-explorer
artifact id: maven2-testability-plugin
version: 1.3.1-SNAPSHOT
and when you run mvn site, you should have a testability.html file under target/site/. See the available options by running:
mvn help:describe -Dplugin=com.google.testability-explorer:maven2-testability-plugin -Ddetail
Running with Ant
There's an explanation of the Ant task here. The most common usage is including the task into Ant and call it using: If you have doubts check the Readme file in the wiki of the project
What is it testing?
Before knowing if Testability Explorer is a good or bad idea, you must know what it test. The application mainly checks for Injectability of classes and the absence of Global State, two things that facilitate unit testing. High injectability is good because it gives the test plenty of choices where to intercept the code under tests and make the test as small as possible. Similarly low global state will aid in isolating the tests from each other. Besides that, other parameters are analysed to determine how testable a class is. One of the things the application checks is the "Law of Demeter", which says that your code should only talk to its immediate collaborators. The most common pattern that violates the Law of Demeter is this:
interface Foo { public ComplexObject getTheObject();}class MyClass { private Foo myDependency; public void method() { myDependency.getTheObject().doThingWithIt(); }}
This is a bad thing to do, because it makes testing MyClass harder. If we want to set a Mock, Stub, or Fake object into myDependency, we will be forced to implement doThingWithIt() on that object, in a way that keeps MyClass happy. That without considering how hard it may be to track a NPE in that point. As you can see, the application does an intensive check on possible pitfalls of testability. You can find more detail in these links: