ulrail.gif

Omondo Lab

  ur-2c.gif urrail.gif
blrail-nonavbar.gif

Home | Resources | Homeworks
 Exams | Slides | Contacts | Submit

br-2a.gif   br-2c.gif brrail.gif
spacer.gif spacer.gif spacer.gif

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'...

  1. Download the jar file containing the source for JUnit from here.
  2. 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'
  3. 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.
    1. Choose Archive File as the source (this includes jar files)
    2. Hit Next and in the next screen use Browse to find your jar file
    3. You might play with expanding the directory tree view you see here. You check boxes to indicated which folders/files you want to import.
    4. For this lab, un-check the top-level folder, but then check the junit sub-folder. And then...
    5. 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.
    6. Click Finish, and watch the progress, including down in the bottom-right.
    7. Back in the Package perspective, expand the src directory to see your project files.
  4. 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.

 

spacer.gif
spacer.gif footer-middle.gif spacer.gif