|
|
|
Objective
In this 'lab', you will gain a bit of experience using the free
UML CASE tool Omondo, which is integrated into Eclipse.
Setup As it turns out, Omondo is not installed in the
lab. So we have to install Eclipse with Omonodo, and use that
version. What a pain....
First download the installation file from here (you have to right-click and select 'save as') -- it's 120 Mb or so in
size (if you are not in Olsson 001, the link is here).
Load up a command prompt, cd into the directory that you saved that
file to (probably c:/localdata), and execute java -cp
eclipseUML_E312_freeEditionIncludingEclipseForWindows_2.1.0.20060315.jar
com.izforge.izpack.installer.Installer . This will start
the installation process. The directory we are installing to is
c:/localdata/eclipse. Then, go to that directory and run
eclipse.exe.
Right. Now onto the 'lab'...
- Download the jar file containing the source for JUnit from
here.
- Start Eclipse, and create a new 'Java Project' called junit. We'll
use Java 5.0 (aka 1.5) for this project. Also select 'create
separate source and output folders'
- Right-click on the src folder in the package perspective, and choose
Import. Here are the steps to import files from the jar file for this
project.
- Choose Archive File as the source (this includes jar files)
- Hit Next and in the next screen use Browse to find your jar file
- You might play with expanding the directory tree view you see
here. You check boxes to indicated which folders/files you want to
import.
- For this lab, un-check the top-level folder, but then check the
junit sub-folder. And then...
- Click FilterTypes and see what that does. If you just want Java
files, you should click that option. If you want all files except
class files, click SelectAll and then de-select the class extension.
For this lab, we can take everything. Or just the java files. Either
way.
- Click Finish, and watch the progress, including down in the
bottom-right.
- Back in the Package perspective, expand the src directory to see
your project files.
- 4. Open the framework package and answer the following questions.
1. Package Relationships
Create a package dependency diagram for JUnit:
- Right-click on src, then choose Open UML, and then "Package ..." (if a
dialog box pops up, click 'yes')
- When you see the Java Model Reverse Engineering dialog, put a check next to your project name. FYI, by doing
this you're allowing the tool to put comments into your files.
- Click OK
- This creates a diagram called default diagram.ucd. Of course you can click the maximize icon in the
top right of this window to get a full-screen view of this. Or, you can use the Outline view to the right to pan
around to see regions of the complete window.
- Consider: What is the relationship between the extensions package and the rest of JUnit?
What if we want to know the relationship between the extensions package and the rest of JUnit? There are several
ways to explore this using the tools we have. Try each of the methods below to see which helps you answer these
two questions (which are very practical things to ask about a large system).
(1) What if you wanted to find out what other classes might import classes from the extensions diagrams?
(2) Can you tell what classes are used by classes in the extensions package?
- Can the UML package diagram you created above help you understand this?
- Use JDepend (if installed in the 001 lab) by right-clicking on the src folder, and choosing JDepend from the menu
and then Show JDepend view. Is this a good way about answering the questions above? (Note: when you're done,
switch back to the Java view by clicking at the top-right of the workspace.)
- Try Eclipse's Search menu. First, make sure you've clicked on the current project's src icon. Next, choose
Search and then Java Search. Next, type junit.extensions* in the search-string field, choose Package for "search
for", choose References or All Occurrences for "limit too", and finally make the scope "enclosing
projects" so that it only looks in the current project. (The Java Search feature is powerful and perhaps
a bit tricky. Worth figuring out!)
2. Class Diagrams
Create class diagram for the framework package:
- Right-click on junit.framework, then choose Open UML, and then Class Diagram Editor.
- For wire automation, select two of the choices: association, inheritance, but not dependency
- Then click OK on Package Content Selection.
Explore how you can use the results class diagram.
- Try using the Outline on the right to move around the diagram, and then also use the maximize icon on the diagram's
window to make it larger.
- Try double-clicking on a class or on a method or field.
- What's the type of relationship between TestCase and Assert?
- What's the type of relationship between TestCase and TestSuite? Can you see why? To do so, you'll have to
look at the code of TestSuite (double-click in the class diagram), and hit CTRL-f and look for TestSuite.
Layout of the class diagram with a lot of classes is clearly not ideal, but for smaller sets of packages (e.g.
java.awtui) it is useful "as is" and probably can be made more useful if one took the time to clean
up the diagrams it generated.
3. Sequence Diagrams
Let's see if sequence diagrams can help us explore how the Observer design pattern is used in JUnit. Keep
in mind that:
The class TestResult has the role of subject (or observable). A TestResult object changes when
someone (itself, perhaps) calls either addFailure() or addError() on that object. (JUnit has two types of failed
results.)
- Question: Can you see from the TestResult class what "type" can be an observer of TestResult objects?
What method in TestResult allows an observer to register to watch a given subject object?
- Look at the code for TestResult.addError() to see what it does when a subject object changes.
- But what can actually make the subject change? How would you find out who calls TestResult.addError()? Think
about this for a second....
Now, try this way: drag the addError() icon from the Outline view on the right into the Call Hierarchy view
(this is NOT the Hierarchy view). If you don't see the Call Hierarchy view, use the Window -> ShowView
-> Other -> Java menu at the top of the workspace. Play
with the icons at the top of this view and see how you can answer this question. Try clicking on a item in this
view to jump to a call of addError().
Let's create a sequence diagram for this call. Click on the method TestResult.addError() in any view, and then
right-click. Under Open UML, choose the sequence diagram operation. Note that
this won't work in the free version of Omondo. Again, you have the Outline view to the right,
you can maximize the diagram window, and you can also change the scale of the diagram from 100% to some other scale
value in a toolbar at the top.
We'd expect TestResult.addError() to call an "update" operation on each observer object in its collection
of observers. In this diagram, can you see the object (and its type) of the observer and what the name of that
"update" operation is? Why don't we see the "real" type in this diagram? Discuss with your
partner or the TA.
4. Execution of a Test-Class
The observer design pattern you just explored plays a role in the overall execution structure of JUnit. Let's
explore how this works by starting with one of the three versions of a test "runner" class.
In the package textui there's a TestRunner that provides a command-line based tool to run tests. When it runs,
it's given the name of one test-class to be run. (By the way, there are runners for each of the three UI packages.
This one is the simplest to look at, but feel free to explore the swing version.)
Choose the TestRunner.doRun(Test,boolean) method, and create a sequence diagram. From this, can you see what
the four major steps are that take place in this method?
Do you think that a TestRunner object might be acting as an observer of a TestResult? If so, what do you see
in this diagram that tells you this?
Explain precisely what it is about how TestRunner is defined as a class that makes it an observer type. You
might not see it right away in the code. You may find the Type Hierarchy view useful. (Remember, click on a type
anywhere and hit F4.)
List all the concrete classes in junit that can be an observer of a TestResult.
5. Wrap Up
Consider what's good and bad, what you like and don't like, about using Omondo's UML product for reverse engineering
to learn about the design of a system like JUnit.
|
|