Andrej Koelewijn

3/14/2005

Testing swing/jclient applications with Marathon

Filed under: — site admin @ 10:03 am

Marathon is a very nice tool to test swing applications. You can write test scripts using python, or you can have Marathon record your actions. The result of this is a python script which looks like this:

useFixture(default)
def test():

window('My Application') click('JTree', '/Someone/Contact Data') select('sexComboBox', 'F') select('weightFormattedTextField', '90') assertText('statusLabel','') select('dateOfBirthFormattedTextField', '01.01.1900') close()

You specify which components you’re using by refering to the component name, which you can set using setName() on every component. In jdeveloper you’d expect that if you specify name in the property sheet of a component that jdeveloper would generate a setName call in your code. This is not the case however. Instead it changes the instance name of the component, which isn’t bad either, but not very helpfull if you’re creating marathon scripts. You’re test scripts will be a lot less readable. In the example above, i didn’t manually call setName for the JTree component. If i’d had 3 JTree components they would have referred to as JTree, JTree1, JTree2.

I’ve created a small utility which will set the name of a component and it’s child components by taking the instance name and calling setName on the component. Might be usefull if you’re using Marathon.

package nl.iteye.swingtest;

	

import java.awt.Component;
import java.awt.Container;
import java.lang.reflect.Field;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**

* @author Andrej Koelewijn */
public class TestHelper { public TestHelper() { } public static void setComponentNames(Component parent) { if (parent instanceof Container) { Component[] childs = ((Container) parent).getComponents(); Field[] fields = parent.getClass().getDeclaredFields(); for (int i = 0, n = fields.length; i < n; i++) { if (Component.class.isAssignableFrom(fields[i].getType())) { try { fields[i].setAccessible(true); Object o = fields[i].get(parent); if (o != null) { ((Component) o).setName(fields[i].getName()); } } catch (IllegalAccessException e) { } } } for (int i = 0, n = childs.length; i < n; i++) { if (childs[i] instanceof Container) { TestHelper.setComponentNames(childs[i]); } } } }
}

3 Responses to “Testing swing/jclient applications with Marathon”

  1. Raghu Says:

    Hi,

    Will you silve my problem…

    I am using Fedora Core 4 in my system.
    Yesterday I downloaded Marathon-0.9a.
    When i tried to run according the given instructions, it showing the following error…

    Exception in thread “main” java.lang.NoClassDefFoundError: while resolving class: com.jgoodies.plaf.plastic.PlasticBorders

    at java.lang.VMClassLoader.transformException(java.lang.Class, java.lang.Throwable) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.VMClassLoader.resolveClass(java.lang.Class) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.Class.initializeClass() (/usr/lib/libgcj.so.6.0.0)
    at com.jgoodies.plaf.plastic.PlasticLookAndFeel.initComponentDefaults(javax.swing.UIDefaults) (Unknown Source)
    at com.jgoodies.plaf.plastic.Plastic3DLookAndFeel.initComponentDefaults(javax.swing.UIDefaults) (Unknown Source)
    at javax.swing.plaf.basic.BasicLookAndFeel.getDefaults() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.plaf.metal.MetalLookAndFeel.getDefaults() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.UIManager.getDefaults() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.UIManager.getUI(javax.swing.JComponent) (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JPanel.updateUI() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JPanel.JPanel(java.awt.LayoutManager, boolean) (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JPanel.JPanel() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JRootPane.createGlassPane() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JRootPane.getGlassPane() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JRootPane.JRootPane() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JWindow.createRootPane() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JWindow.getRootPane() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JWindow.windowInit() (/usr/lib/libgcj.so.6.0.0)
    at javax.swing.JWindow.JWindow() (/usr/lib/libgcj.so.6.0.0)
    at net.sourceforge.marathon.display.SplashScreen.SplashScreen() (Unknown Source)
    at net.sourceforge.marathon.Main.showSplash() (Unknown Source)
    at net.sourceforge.marathon.Main.runGUIMode() (Unknown Source)
    at net.sourceforge.marathon.Main.main(java.lang.String[]) (Unknown Source)
    at gnu.java.lang.MainThread.call_main() (/usr/lib/libgcj.so.6.0.0)
    at gnu.java.lang.MainThread.run() (/usr/lib/libgcj.so.6.0.0)
    Caused by: java.lang.ClassNotFoundException: javax.swing.plaf.metal.MetalBorders$ScrollPaneBorder not found in gnu.gcj.runtime.SystemClassLoader{urls=[file:/Disk2/Marathon/marathon-0.90a/,file:./,file:./,file:/Disk2/Marathon/marathon-0.90a/marathon.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/,file:/Disk2/Marathon/marathon-0.90a/Support/commons-logging1.0.1.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/jaccess-1.3.jar,file:/Disk2/Marathon/marathon-0.90a/Support/junit3.8.1.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/jython-2.1.jar,file:/Disk2/Marathon/marathon-0.90a/Support/looks-1.2.2.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/forms-1.0.4.jar,file:/Disk2/Marathon/marathon-0.90a/Support/rmi-lite.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/scope-1.0.1.jar,file:/Disk2/Marathon/marathon-0.90a/Support/selfesteem-applet.jar,file:./,file:/Disk2/Marathon/marathon-0.90a/Support/selfesteem.jar], parent=gnu.gcj.runtime.ExtensionClassLoader{urls=[], parent=null}}
    at java.net.URLClassLoader.findClass(java.lang.String) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.ClassLoader.loadClass(java.lang.String, boolean) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.ClassLoader.loadClass(java.lang.String) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.VMClassLoader.defineClass(java.lang.ClassLoader, java.lang.String, byte[], int, int, java.security.ProtectionDomain) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.ClassLoader.defineClass(java.lang.String, byte[], int, int, java.security.ProtectionDomain) (/usr/lib/libgcj.so.6.0.0)
    at java.security.SecureClassLoader.defineClass(java.lang.String, byte[], int, int, java.security.CodeSource) (/usr/lib/libgcj.so.6.0.0)
    at java.net.URLClassLoader.findClass(java.lang.String) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.ClassLoader.loadClass(java.lang.String, boolean) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.ClassLoader.loadClass(java.lang.String) (/usr/lib/libgcj.so.6.0.0)
    at java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader) (/usr/lib/libgcj.so.6.0.0)
    ...24 more

    Marathon is running on windows system,but its not running on my Linux system.

    Please solve my problem

    Regards
    Raghu

  2. andrejk Says:

    Looks like you’re using gcj on linux, which uses gnu classpath. I think gnu classpath isn’t complete regarding swing classes. Try using a different jdk, for example sun’s jdk, which contains a complete swing implementation.

  3. Dakshinamurthy Karra Says:

    Hi,

    I released a new version of Marathon recently and looking for feedback. Can you take few minutes and have a look at it?

    Thanks in advance.

Leave a Reply

Powered by WordPress