Goals
- to practice using the Eclipse integrated development environment
- to use a debugger
- to write specific repeatable black-box tests with JUnit
- to develop white-box tests that cover the code
Parts of the Assignment
40% - building a substantial test set in JUnit for Puzzle class
30% - using the debugger to find the bugs in Puzzle class and fix them
30% - building test sets that cover the conditions
in some methods of the WordSearch class
Overview
We've discussed white-box and black-box testing.
We've considered the benefits of using an integrated development
environment (IDE).
Using a debugger is something you should know how to do.
In this assignment, 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.
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.
You will submit a zip file containing a directory of your modified code and test cases to my katz330 account (yes, katz330). I've enabled web submissions, so you can turn it in by connecting to http://cs.millersville.edu/submit/ and using your cs (Linux) account name.
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. I will freely help you if you ask. I'm giving you until the last day of classes to finish this, but it's better if you complete it earlier.
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 WordSearch.zip available from the course web page. It contains a directory named WordSearch420 that contains six files: Puzzle.java, PuzzleTest.java, WordSearch.java, data.txt, coverage.txt, and test.html (this file).
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 Eclispe
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 WordSearch420.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 WordSearch420 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 WS420. 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 WordSearch420 and default package.
Double-click PuzzleTest.java to open it.
Add your name after mine in the comments.
Note that there are comments here.
I expect them to be updated on what you turn in.
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. You don't see the red/green bar unless you are showing the JUnit tab at left. 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 Bugs 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 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. When j gets to the value 5, control will 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. Read the next section to understand how far you have to go with this.
Completing Tasks One and Two
I've introduced several bugs into this program.
Some are more subtle than others.
You may find them by reading the code. Maybe not.
None of them are specific to Java.
Your C++ background is sufficient to find them.
Use JUnit and the debugger to find as many as you can.
I expect you to continue adding test cases to
reasonably cover the specifications of the problem.
I expect you to find and correct the bugs I introduced.
Reasonably covering the specifications will be difficult with this one puzzle. I suggest creating another puzzle in another test case class. You can duplicate PuzzleTest.java, give the class a new name, and edit it appropriately. Change the Run configuration so that it runs all tests in the selected project.
What you turn in should have a green bar when I run JUnit. All of the bugs I introduced should be fixed. The program should meet the specifications in terms of finding words in the puzzle. The tests should be such that they reveal all the bugs. Searching in all directions, at the borders, in extra puzzles, and for words that occur multiple times should be sufficient for this assignment. Try to break the program. I should be able to run all your tests by running JUnit. Each test should be commented. Copy and paste are your friends.
I know that Puzzle doesn't check that all the rows have the same number of columns. That isn't a bug you need to detect or fix. You shouldn't need to be making long changes, adding methods to Puzzle, or dealing with exceptions. The bugs are such that they could occur in C++ or Java and are small fixes.
The Third Task - Testing WordSearch class
considering coverage
The above tasks used JUnit and tests that could be checked automatically.
The testing was based on the specifications.
For this task, look at the code in the WordSearch class.
You may want to print it.
As far as I know, there are no bugs here.
Develop test sets (input and expected output) that cover the conditions of the findWords and readPuzzleFromStream methods. You don't have to worry about the other methods. Have each part of a condition evaluate to true and false - not merely the entire condition. Rather than have several different input files with different row and column sizes, you can create a data file or two and modify them as you run them. Leave those files in the directory when you turn it in.
Document what tests you used to cover the conditions in a file named coverage.txt that will be in this directory so that you turn it in with everything else. A beginning version of this file is included.
Turning in In
When you are ready to turn this in, do a Project / Clean
to remove the extra .class files.
If you forget, it isn't a problem because they don't take up much space.
Then create a zip file.
In our Windows lab, use WinZip.
If you don't know how to use it, learn.
On the Mac, use File / Create archive.
Those should create a file ending in .zip that contains all of
the parts for this assignment.
Submit that zip file to my katz330 account
using web submissions
as described at the beginning of this handout.
Another look at Debugger
Another way to use the debugger (but not in this assignment) is to
select a class with a main function (WordSearch, for example)
and choose Run / Debug As... / Java Application.
When the program would crash, the debugger opens and you can look around.
You can see the call chain, examine variables, and so forth.
Collaboration
This assignment is to be completed on your own.
It is NOT a group assignment.
I've tried to make it focussed enough to make it straightforward.
Check it out early so that if you get stuck, you can ask me questions.
I've tried to proofread it and walk through it, but there are bound
to be mistakes in this description. Ask me about them.