Using Eclipse and JUnit
CS 420 - Spring 2006 - Ms. Katz

Goals
- to practice using the Eclipse integrated development environment
- to use a debugger
- to write specific repeatable black-box tests with JUnit

Overview
This semester, you are using an integrated development environment (IDE) named Eclipse to build your project. Using a debugger is something you should know how to do. In this exercise, you'll do a little of each of those as you explore a word search program that I've written in Java and then broken just a little. This is not an assignment for a grade.

You're going to use Eclipse and JUnit in the PC lab. You may do this at home as long as you use Eclipse and JUnit. They work on Windows, Mac, or Linux. However, do not try to do it in our Linux lab because there are problems with how it interacts with our network.

These directions are not as detailed as those I write for lower-level courses. They are more detailed than I wanted to write, but I want you to focus on seeing how you can use the debugger and on building test cases. You should be able to figure things out for yourselves based on what's here.

The Problem
Consider the word search problem distributed and discussed in class. It's modified somewhat from the CS 162 project. This version is in Java and does not read the filename for the puzzle from the command line. Also, the current version of Eclipse does not handle standard input end-of-file well. So there is a sentinel of an exclamation mark (!) to terminate the word list when running the app. The row and column sizes must be the only two inputs on the first line of the puzzle file.

The Program
I've written a Java program to solve this problem. It has two classes. WordSearch handles the files and input. Puzzle provides a puzzle that is initialized with a matrix of characters. Calling its locationInPuzzle method with a word will return a String description of the location of that word in the puzzle.

There is a zip file named WordSearch06.zip available from the course web page. It contains a directory named WordSearch06 that contains four files: Puzzle.java, PuzzleTest.java, WordSearch.java, and data.txt.

You could compile the program on cs from the command line with
   javac Puzzle.java WordSearch.java
Then execute it (entering data.txt when prompted and then words as you wish) with
   java WordSearch
Use exclamation mark on a line by itself to stop.

Getting Started with Eclipse
Instead of translating and running from the command line (or even using cs at all), I'd like you to have the experience of using Eclipse (a free, multi-platform, multi-language integrated development environment). If you want to download it to home, look at http://www.eclipse.org/

Create a directory called MyWorkspace (or whatever else, but I'll use MyWorkspace for my examples). In our Windows lab, I created that under My Documents. Copy the WordSearch06.zip file to there and unzip it.

Launch Eclipse. You'll need to choose a workspace, so find MyWorkspace. Create a new project (File / New) and choose Java project. Click next. The next page should have your workspace as the directory location. Give WordSearch06 as the Project Name. You should get a long note at the bottom saying the location exists. Click Finish to create the project from those files.

On the left side in the Package Explorer, the package may have an X on it because it needs to know where the JUnit files are. It may not. If it does have an X, right-click the package and choose Properties from the bottom of the contextual menu. Click on Java Build Path and the Libraries tab. Choose Add External JARs and browse to wherever Eclipse is stored, plugins, org.junit.version, junit.jar. Add that.

Eclipse keeps track of various configurations for running. You'll use one configuration to run the WordSearch class with file input and another configuration to run JUnit tests on the Puzzle class. To set up the first, choose Run / Run... The left side shows various configuration types. Choose Java Application and click new at the bottom of the column. Give it a name like WS06. Also enter (or search for) WordSearch as the main class. Now the Run button should be enabled. Click it.

The Console interaction is at the bottom of the Eclipse window. There's not much space there. At the upper right of that pane are minimize and maximize buttons (little window shape, big window shape). Maximize so you can see what you're doing. There's a data file in the files I gave you. End the input with an exclamation mark on a line by itself. The green arrow button icon repeats running with the most recent run configuration.

If you look at the data file and the output or try to find some words, you should notice that something isn't right. I've broken the program. The problems you are seeing are in the Puzzle class. Let's test in a more controlled way and find the bugs.

The First Task - Testing Puzzle class with JUnit
In the Package Explorer, open WordSearch06 and default package. Double-click PuzzleTest.java to open it. Add your name after mine in the comments. Note that there are comments here. You should adjust them as you add tests. Document your changes.

This is the PuzzleTest class. It has two instance variables. Matrix m contains the puzzle data. The setup method constructs a Puzzle p from m by calling the Puzzle class constructor. Below the setup method are various test methods. Each method is a test that will be run and reported on by the JUnit framework. For now there are two tests: testPuzzleNE and testPuzzleNotFound.

Run those tests by building a new run configuration using JUnit as the configuration type. When you actually run a JUnit test and show the JUnit tab, you'll see a red/green bar. The two tests should have run cleanly giving a green bar.

JUnit is checking the output with the assertTrue method. That kind of assertion is good enough for our purposes here. We're also printing some things to the console for our benefit. Each test displays the value of theAnswer obtained in the search. If the word isn't in the puzzle, the string is empty. That's why there appears to be no line of output for 'rain' in the console window.

Let's build a test that will not pass. Try to find the word 'swoop' that should be going west starting at 1,5. It looks to be printed backwards on the top line. Copy the code for the testPuzzleNE method and edit it into an appropriate test. There's no need to print the puzzle again.

Run. You see a red bar because a test failed. Maybe the string for comparing isn't well-formed, but theAnswer isn't showing up in the console. Look in the left bottom pane to see the Failure Trace. (You can drag the bar between panes to resize them.) There was an AssertionFailed error. Let's use the debugger to locate the problem.

The Second Task - Using the Debugger to find the bug in Puzzle class
Double-click the failed test and method in the JUnit view to open the corresponding file in the editor and scroll to the failing method. Set a breakpoint at the beginning of the test method (Run / Toggle Line Breakpoint and a blue dot appears on that line). Select the test case (function in the PuzzleTest.java file) and execute with Run / Debug As...  JUnit Test. You'll be asked if you want to switch to the Debug Perspective. You do.

You are now in the debugger. You can switch perspectives easily by clicking the Java and Debug icons at far upper right. The program is stopped at the breakpoint you set. If you click the Console tab near bottom left, you'll see the printed puzzle and the result of searching for the first word.

At upper right, there is a Variables pane displaying the PuzzleTest object. If you click the down arrow in front of the green dot, you'll be able to browse through the objects contained in this object. Look at the Puzzle p and theBoard and especially row 1 of the board because that's where you expect to find the word.

Let's step into the call to the locationInPuzzle method. Step Into is F5 (function key 5) while Step Over is F6. There are also little arrow icons for this and menu choices under Run. When you press F5, the file displayed changes to Puzzle.java. That's because Step Into goes into the function that is called. The variables displayed now include the word 'swoop'. Use Step Over if you want the next statement to execute as a whole.

Look around here. Step Over as needed to see what is happening. Notice that you can watch the loop variables i and j update. Use Run / Debug Last Launched (F11) if you need to start over. You may have to Terminate and then do F11. When j gets to the value 5, control should move to the statement inside the if. Hmmmm.

Use your understanding of loops to fix the problem. You can save it and start again. At some point, you may get a panel that says you need to terminate to apply changes.

Another look at Debugger
Another way to use the debugger is to select a class with a main function (WordSearch, for example) and choose Run / Debug As... / Java Application. When the program crashes, the debugger opens and you can look around. You can see the call chain, examine variables, and so forth.