Transcript Debugging

Testing and debugging
A short interlude
26-Jul-16
Print statements

An old-fashioned, but still very useful, debugging
technique is putting in print statements


However, it’s a nuisance to remove them again (then add them
again, then remove them again...)
Here’s a helpful technique:



boolean debugging = true;
debug("Some debugging message...");
private void debug(Object obj) {
if (debugging) System.out.println(obj);
}
Debugging output methods, I

JUnit testing should not produce any output that you
have to look at--it should be fully automatic

First, consider whether you can separate the output
method into one method that computes the output, and
another method that actually prints it



Then you can test the former method
Since a String can contain newlines, you are not restricted to
single-line output
Separation of concerns is good practice in any case
Debugging output methods, II

You can also change (maybe temporarily) where the output goes





PrintStream usualSystemOut = System.out; // save old stream
System.setOut(someOtherPrintStream); // use new stream
System.setOut(usualPrintStream); // change it back
You can write to a file, then test whether the file has the right
contents
Here's a more sophisticated approach:



Use a ByteArrayOutputStream to capture the output in a byte array
Use the ByteArray's toString() method to examine the output
Complete sample code is on the next slide
Program to capture output
public static void main(String[] args) {
PrintStream originalOut = System.out;
OutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
System.setOut(ps);
System.out.print("Hello, output!");
System.setOut(originalOut);
System.out.println("I got: [" + os.toString() + "]");
}
I got: [Hello, output!]
toString()


In general, you want to avoid unnecessary methods in your
classes, but...
...It’s usually a good idea to override toString()



Having a toString() method often simplifies debugging, because you can
see what your objects really are
Don’t use your toString() methods to compare objects in your
JUnit tests, unless you are very sure you will never change the
string representation of your objects
For JUnit testing (especially with assertEquals), you should
have a good version of
public boolean equals(Object o)

The default equals method tests identity, not equality, and this is probably
not what you want
Review: Overriding methods

To override a method is to write a method that has the exact same
signature as an inherited method





The names of parameters are not part of the signature, so they can be
different if you really want
You cannot override a method with a less public method (but it can be more
public if you want)
You cannot throw any checked exceptions that the inherited method doesn’t
throw
In Java 5, you should precede your method with @Override
Examples:


public String toString() { ... }
public boolean equals(Object o) { ... } // Notice type of parameter!
The End
Eclipse Hints
● You can put a “task” in any comment:
● TODO -- code to be written
● FIXME -- error to be fixed
● XXX -- need to think more about this
● To show tasks, choose Window 
Show view  Other...  Tasks