[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[swtbot-dev] SWTbot tests in dynamic languages (Jython)
|
Hi all,
After suggestions from Ketan I've created my own Eclipse application
that I believe should be able to run SWTBot tests in any dynamic
language just by pointing out a source file. I have only tested it on
a minimal example using Jython but in principle it ought to work. I
attach the source code for this.
I can then basically write a Python test for the rcpmail example:
first I run this under Jython:
allArgs = [ "-application", "org.eclipse.swtbot.testscript.application",
"-testApplication", "org.rcpmail", "-product",
"org.rcpmail.product",
"-testScript", "/users/geoff/tmp/rcptest.py" ]
import org.eclipse.equinox.launcher as launcher
launcher.Main.main(allArgs)
and then write this in rcptest.py : "bot" is a global variable set up
by the attached Java code:
bot.menu("File").menu("Open Another Message View").click()
bot.viewByTitle("Message")
then I can achieve the same things as in the inital example using Python.
The surprise here was that it did not work to create the
SWTWorkbenchBot in Python. If I tried it just threw
IllegalStateException the whole time (and this wasn't a timing issue,
I could wait forever and still got this). It is iterating through all
existing threads and I suspect there is some clash between Java and
Jython threads. I worked around this by creating it in Java and adding
it to the global namespace of the script.
Regards,
Geoff Bache
package org.eclipse.swtbot.testscript;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.testing.ITestHarness;
import org.eclipse.ui.testing.TestableObject;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* Copied from the headless test runner: the point here is to support running dynamic language scripts
* in e.g. Python, Groovy or Ruby, primarily for testing
*/
public class Application implements IApplication, ITestHarness {
private static final String DEFAULT_APP_3_0 = "org.eclipse.ui.ide.workbench"; //$NON-NLS-1$
private TestableObject fTestableObject;
private IApplication fApplication;
/*
* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
public Object start(IApplicationContext context) throws Exception {
String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
Object app = getApplication(args);
Assert.isNotNull(app);
fTestableObject = PlatformUI.getTestableObject();
fTestableObject.setTestHarness(this);
if (app instanceof IApplication) {
fApplication = (IApplication) app;
return fApplication.start(context);
}
throw new IllegalArgumentException("Could not execute application " + getApplicationToRun(args));
}
/*
* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#stop()
*/
public void stop() {
if (fApplication != null)
fApplication.stop();
}
/*
* return the application to run, or null if not even the default application is found.
*/
private Object getApplication(String[] args) throws CoreException {
// Find the name of the application as specified by the PDE JUnit launcher.
// If no application is specified, the 3.0 default workbench application
// is returned.
IExtension extension = Platform.getExtensionRegistry().getExtension(Platform.PI_RUNTIME, Platform.PT_APPLICATIONS,
getApplicationToRun(args));
Assert.isNotNull(extension);
// If the extension does not have the correct grammar, return null.
// Otherwise, return the application object.
IConfigurationElement[] elements = extension.getConfigurationElements();
if (elements.length > 0) {
IConfigurationElement[] runs = elements[0].getChildren("run"); //$NON-NLS-1$
if (runs.length > 0) {
Object runnable = runs[0].createExecutableExtension("class"); //$NON-NLS-1$
if (runnable instanceof IApplication)
return runnable;
}
}
return null;
}
/*
* The -testApplication argument specifies the application to be run. If the PDE JUnit launcher did not set this
* argument, then return the name of the default application. In 3.0, the default is the
* "org.eclipse.ui.ide.worbench" application.
*/
private String getApplicationToRun(String[] args) {
IProduct product = Platform.getProduct();
if (product != null)
return product.getApplication();
return getArgument(args, "-testApplication", DEFAULT_APP_3_0);
}
private String getArgument(String[] args, String argName, String defaultValue) {
for (int i = 0; i < args.length; i++)
if (args[i].equals(argName) && (i < args.length - 1)) //$NON-NLS-1$
return args[i + 1];
return defaultValue;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.testing.ITestHarness#runTests()
*/
public void runTests() {
fTestableObject.testingStarting();
try {
String testScript = getArgument(Platform.getCommandLineArgs(), "-testScript", null);
if (testScript == null)
throw new IllegalArgumentException("Test script file not specified"); //$NON-NLS-1$
runScript(testScript);
} catch (Exception e) {
e.printStackTrace();
}
fTestableObject.testingFinished();
}
private void runScript(String testScript) throws ScriptException, IOException {
String extension = getExtension(testScript);
SWTWorkbenchBot bot = new SWTWorkbenchBot();
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(extension);
engine.put("bot", bot);
BufferedReader reader = new BufferedReader(new FileReader(testScript));
engine.eval(reader);
}
private String getExtension(String testScript) {
String[] parts = testScript.split("\\.");
return parts[parts.length - 1];
}
}