Calculator example.

A calculator application was developed and the result is bundled in a jar file (tutorial/lib/calculator.jar). Launch it just by double-clicking1 the jar file. Play with the calculator, next figure shows the application:

alef'1

Graphic3

Step 1: Write some acceptance tests

We want to write tests for the calculator. We expect the calculator to be able to:
    1. add two values

    2. subtract two values

    3. clear the current value

Let's write a test script to test addition.
    1. create a new Marathon project

    2. create a new empty test (a test is a Python script file)

      • double click the root node in the left-side navigator panel

      • right click on the "TestCases" folder and select the "New" menu item:

    save it as a file named testAdd.py, you should see somthing like:

write the test

  • click on the record button in the toolbar (the red circle)

  • enter "12 + 4 =", the result is displayed (16), if you look at the Marathon IDE you can now see:

 
if window('Calculator Example'):
            click('1')
            click('2')
            click('+')
            click('4')
            click('=')
        close(

    press control right-click in the the text area, to open the contextual menu,

  • select Assert Text

  • stop recording (the button with a red square), the script now looks like:

 
if window('Calculator Example'):
            click('1')
            click('2')
            click('+')
            click('4')
            click('=')
			assert_p('TextField', 'Text', '16')
        close(
    • save the script2


  • run the the test. Select the "JUnit" tab, in the left-side panel. Click the test view, you should see your new created test. Click on the "Run all tests" button, in the JUnit's control bar, and get the green bar:

  • Change the asserted value to some bad value and see the error report (bottom panel):

  • can create two more tests: testSubtract and testClear3

 
if window('Calculator Example'):
            click('1')
            click('2')
            click('-')
            click('4')
            click('=')
			assert_p('TextField', 'Text', '8')
        close(

and

 
if window('Calculator Example'):
            click('1')
            click('2')
            click('-')
            click('4')
            click('=')
            click('C')
			assert_p('TextField', 'Text', '0')
        close(

Step 2: Refactor the Tests

As the Marathon acceptance tests are written in Python scripting language it helps managing the tests as you would do in any programming development: make maintenance easier and reuse of code.
Can we refactor anything in the three test scripts? Let's try. What can we refactor? What don't we like right now?
    1. Writing one more test, without using the recording feature of Marathon, is hard.

    2. Reading the tests to undrestand what is going on is not easy.

    3. Currently the tests is saying: click on the component named '1' (for instance), if we later want to change the name of our component we will have to modify all our scripts

    4. All the scripts start and end with the same sequence...

Wouldn't be easier (or nicer) to write:
 
enter('12')
add('4') 
assertResult('16')
close()
instead of
 
window('Calculator Example')
click('1')
click('2')
click('+') 
click('4')
 click('=')
assertText('JTextField', '16')
close()
We need to create some helper methods: enter, add, subtract, clear, assertResult and assertCleared. As we want them to be used by all the scripts, we're going to create a new Python module:

tutorial/step2/Module/util.py
 
from marathon.playback import *

def enter(value):
    window('Calculator Example')
    enterValue(value)

def add(value):
    click('+')
    enterValue(value)

def subtract(value):
    click('-')
    enterValue(value)

def clear():
    click('C')

def assertResult(expected):
    click('=')
    assertText('JTextField', expected)

def assertCleared():
    assertText('JTextField', '0')

def enterValue(value):
    for char in value:
            click(char)
Here is some explanation about this script:
    • The import statements say we are using code from the named modules (marathon.playback and defaultFixture).

    • The enter method first waits for the calculator main window to be displayed, next calls the enters the value.

    • The add method first simulates a click on the plus button and the enters the value.

    • The subtract method first simulates a click on the minus button and the enters the value.

    • The clear method simulates a click on the clear button.

    • The assertResult method sumulates a click on the equal button and checks if the current result is equal to the expected value.

    • The assertCleared method checks if the current result is equal to the current value is zero (meaning cleared)

    • The enterValue method simulates clicks for all the caracters of the value

Now, we can rewrite the three test scripts as:
testAdd.py
 
from Modules.util import *

    
useFixture(default)

    
def test():
    enter('12')
    add('4')
    assertResult('16')
    close()
testSubstract.py
 
from Modules.util import *

    
useFixture(default)

    
def test():
    enter('12')
    subtract('4')
    assertResult('8')
    close()
testClear.py
 
from Modules.util import *

    
useFixture(default)

    
def test():
    enter('12')
    subtract('4')
    assertResult('8')
    clear()
    assertCleared()
    close()

Step 3: More Tests...

Now we can write more tests, without even recording user actions.
testAddAndAdd.py
 
from step3.util import *

    
def test():
    enter('12')
    add('4')
    assertResult('16')
    add('30')
    assertResult('46')
    close()
testAddAndSubtract.py
 
from step3.util import *

    
def test():
    enter('12')
    add('4')
    assertResult('16')
    subtract('5')
    assertResult('11')
    close()
Now, you can launch the Marathon IDE again and run them.

Step 4: Automate tests with JUnit

At this stage if we want to run the tests we must start the Marathon IDE and manually run the tests or use the batch mode.
To run all the tests, from step 3, in batch mode execute next command line: marathon -b <some-dir>\tutorial\step3.
But, what if we write some Java unit tests and run them with JUnit? And if we are using automated builds, with tests run, How can we also run the Marathon tests?
Let's write a test suite that uses the scripts written so far. We assume here that the working directory is set to the right Marathon project on startup (see the line with System.getProperty("user.dir")).
TutorialTestSuite.java
 
import net.sourceforge.marathon.Constants;
import net.sourceforge.marathon.junit.TestCreator;
import net.sourceforge.marathon.component.MarathonNamingStrategy;
br>

    
import junit.framework.Test;

    
public class TutorialTestSuite {

    
    public static Test suite() throws Exception {
	
        String marathonProject = System.getProperty("user.dir");

    
        System.setProperty(Constants.PROP_RECORDER_NAMINGSTRATEGY, MarathonNamingStrategy.class.getName());
        System.setProperty(Constants.PROP_APPLICATION_PYTHONPATH, marathonProject);
        System.setProperty(Constants.PROP_TEST_DIR, marathonProject);
		
        TestCreator creator = new TestCreator();
        
        return creator.getTest("AllTests");
		
    }

    
}
After compiling this file, we can run the tests using JUnit.
To run the tests, add next elements to your classpath:
  • <marathon-dir>/marathon.jar
  • <marathon-dir>/Support/jaccess-1.3/jaccess.jar
  • <marathon-dir>/Support/junit3.8.2/junit.jar
  • <marathon-dir>/Support/jython-2.1/jython.jar
  • <marathon-dir>/Support/rmi-lite.jar
Also, add next JVM options:
    -Dmarathon.home=<marathon-dir> -Dpython.home=<marathon-dir>

Download

You can download the tutorial here.

writeContactMe()

Contact

Drop me a mail, start the mail subject with [jlaz].


1This should work on Windows with a JRE / JDK 1.2 or later; alternatively use the command line: java -jar calculator.jar or java -cp calculator.jar calculator.CalculatorDialog

2A cachedir directory was created by Marathon while you ran the recorder in the marathon installation directory.

3You can either record them or write the scripts by hand

Annex

Create a new Marathon project

Start the Marathon IDE (using the <marathon-dir>\marathon.bat file):
ide-create
Click the "New" button to create a new project.
Select a directory where you want to create the project and name it "Step 1".
In the "Main" tab type the main class name: calculator.CalculatorDialog.
In the "Class path" tab click the "Add Archives" button and point to the calculator jar file.
Click the "Save" button, you're back to the previous window.
Now, click "OK". Next window should open:
ide-first
Check you can run the application, click on the "Open Application" button in the toolbar (the black running man icon). You should see the calculator image. Next to the "Open Application" is the "Close Application" button to stop it.