aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java11
-rw-r--r--ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java68
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java83
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java34
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitPropertyTester.java130
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java103
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java24
10 files changed, 404 insertions, 80 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
index 9995426..9dd1d16 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
@@ -49,6 +49,7 @@ public class RemoteAndroidTestRunner {
private static final String LOG_ARG_NAME = "log";
private static final String DEBUG_ARG_NAME = "debug";
private static final String COVERAGE_ARG_NAME = "coverage";
+ private static final String PACKAGE_ARG_NAME = "package";
/**
* Creates a remote Android test runner.
@@ -146,6 +147,16 @@ public class RemoteAndroidTestRunner {
}
/**
+ * Sets to run all tests in specified package
+ * Must be called before 'run'.
+ *
+ * @param packageName fully qualified package name (eg x.y.z)
+ */
+ public void setTestPackageName(String packageName) {
+ addInstrumentationArg(PACKAGE_ARG_NAME, packageName);
+ }
+
+ /**
* Adds a argument to include in instrumentation command.
* <p/>
* Must be called before 'run'. If an argument with given name has already been provided, it's
diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
index 6a653ad..864e219 100644
--- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
+++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
@@ -17,16 +17,17 @@
package com.android.ddmlib.testrunner;
import com.android.ddmlib.Client;
-import com.android.ddmlib.Device.DeviceState;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.log.LogReceiver;
import com.android.ddmlib.RawImage;
import com.android.ddmlib.SyncService;
+import com.android.ddmlib.Device.DeviceState;
+import com.android.ddmlib.log.LogReceiver;
import java.io.IOException;
import java.util.Map;
+
import junit.framework.TestCase;
/**
@@ -81,6 +82,17 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
}
/**
+ * Test the building of the instrumentation runner command with test package set.
+ */
+ public void testRunWithPackage() {
+ final String packageName = "foo.test";
+ mRunner.setTestPackageName(packageName);
+ mRunner.run(new EmptyListener());
+ assertStringsEquals(String.format("am instrument -w -r -e package %s %s/%s", packageName,
+ TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
+ }
+
+ /**
* Test the building of the instrumentation runner command with extra argument added.
*/
public void testRunWithAddInstrumentationArg() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
index 4b9d3a0..8092f3a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
@@ -43,7 +43,8 @@ Require-Bundle: com.android.ide.eclipse.ddms,
org.eclipse.jdt.junit,
org.eclipse.jdt.junit.runtime,
org.eclipse.ltk.core.refactoring,
- org.eclipse.ltk.ui.refactoring
+ org.eclipse.ltk.ui.refactoring,
+ org.eclipse.core.expressions
Eclipse-LazyStart: true
Export-Package: com.android.ide.eclipse.adt;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.build;x-friends:="com.android.ide.eclipse.tests",
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
index a75b8b9..35ceba7 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -563,7 +563,7 @@
<adapt type="org.eclipse.jdt.core.IJavaElement">
<test property="org.eclipse.jdt.core.isInJavaProjectWithNature" value="com.android.ide.eclipse.adt.AndroidNature"/>
<test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="junit.framework.Test"/>
- <test property="org.eclipse.jdt.junit.canLaunchAsJUnit" forcePluginActivation="true"/>
+ <test property="com.android.ide.eclipse.adt.canLaunchAsJUnit"/>
</adapt>
</iterate>
</with>
@@ -595,4 +595,14 @@
id="com.android.ide.eclipse.adt.refactoring.extract.string">
</contribution>
</extension>
+ <extension
+ point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ properties="isTest,canLaunchAsJUnit"
+ namespace="com.android.ide.eclipse.adt"
+ type="org.eclipse.core.runtime.IAdaptable"
+ class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitPropertyTester"
+ id="com.android.ide.eclipse.adt.AndroidJUnitPropertyTester">
+ </propertyTester>
+ </extension>
</plugin>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java
index 747fcfe..9bcc63d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java
@@ -24,7 +24,6 @@ import com.android.ide.eclipse.adt.launch.junit.runtime.RemoteAdtTestRunner;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
@@ -39,18 +38,15 @@ import org.eclipse.jdt.launching.VMRunnerConfiguration;
*/
class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
- private String mTestPackage;
- private String mRunner;
+ private final AndroidJUnitLaunchInfo mLaunchInfo;
/**
* Creates a AndroidJUnitLaunchAction.
*
- * @param testPackage the Android application package that contains the tests to run
- * @param runner the InstrumentationTestRunner that will execute the tests
+ * @param launchInfo the {@link AndroidJUnitLaunchInfo} for the JUnit run
*/
- public AndroidJUnitLaunchAction(String testPackage, String runner) {
- mTestPackage = testPackage;
- mRunner = runner;
+ public AndroidJUnitLaunchAction(AndroidJUnitLaunchInfo launchInfo) {
+ mLaunchInfo = launchInfo;
}
/**
@@ -60,17 +56,21 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
* @see IAndroidLaunchAction#doLaunchAction(DelayedLaunchInfo, IDevice)
*/
public boolean doLaunchAction(DelayedLaunchInfo info, IDevice device) {
- String msg = String.format("Launching instrumentation %s on device %s", mRunner,
- device.getSerialNumber());
+ String msg = String.format("Launching instrumentation %s on device %s",
+ mLaunchInfo.getRunner(), device.getSerialNumber());
AdtPlugin.printToConsole(info.getProject(), msg);
try {
- JUnitLaunchDelegate junitDelegate = new JUnitLaunchDelegate(info, device);
+ mLaunchInfo.setDebugMode(info.isDebugMode());
+ mLaunchInfo.setDevice(info.getDevice());
+ mLaunchInfo.setLaunch(info.getLaunch());
+ JUnitLaunchDelegate junitDelegate = new JUnitLaunchDelegate(mLaunchInfo);
final String mode = info.isDebugMode() ? ILaunchManager.DEBUG_MODE :
ILaunchManager.RUN_MODE;
+
junitDelegate.launch(info.getLaunch().getLaunchConfiguration(), mode, info.getLaunch(),
info.getMonitor());
-
+
// TODO: need to add AMReceiver-type functionality somewhere
} catch (CoreException e) {
AdtPlugin.printErrorToConsole(info.getProject(), "Failed to launch test");
@@ -82,20 +82,18 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
* {@inheritDoc}
*/
public String getLaunchDescription() {
- return String.format("%s JUnit launch", mRunner);
+ return String.format("%s JUnit launch", mLaunchInfo.getRunner());
}
/**
* Extends the JDT JUnit launch delegate to allow for JUnit UI reuse.
*/
- private class JUnitLaunchDelegate extends JUnitLaunchConfigurationDelegate {
+ private static class JUnitLaunchDelegate extends JUnitLaunchConfigurationDelegate {
- private IDevice mDevice;
- private DelayedLaunchInfo mLaunchInfo;
+ private AndroidJUnitLaunchInfo mLaunchInfo;
- public JUnitLaunchDelegate(DelayedLaunchInfo info, IDevice device) {
- mLaunchInfo = info;
- mDevice = device;
+ public JUnitLaunchDelegate(AndroidJUnitLaunchInfo launchInfo) {
+ mLaunchInfo = launchInfo;
}
/* (non-Javadoc)
@@ -110,34 +108,28 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
/**
* {@inheritDoc}
- * @throws CoreException
* @see org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate#verifyMainTypeName(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
- public String verifyMainTypeName(ILaunchConfiguration configuration) throws CoreException {
+ public String verifyMainTypeName(ILaunchConfiguration configuration) {
return "com.android.ide.eclipse.adt.junit.internal.runner.RemoteAndroidTestRunner"; //$NON-NLS-1$
}
/**
* Overrides parent to return a VM Runner implementation which launches a thread, rather
* than a separate VM process
- * @throws CoreException
*/
@Override
- public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)
- throws CoreException {
- return new VMTestRunner(new AndroidJUnitLaunchInfo(mLaunchInfo.getProject(),
- mTestPackage, mRunner, mLaunchInfo.isDebugMode(), mDevice));
+ public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) {
+ return new VMTestRunner(mLaunchInfo);
}
/**
* {@inheritDoc}
- * @throws CoreException
* @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
*/
@Override
- public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
- throws CoreException {
+ public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
return mLaunchInfo.getLaunch();
}
}
@@ -161,7 +153,7 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
IProgressMonitor monitor) throws CoreException {
TestRunnerProcess runnerProcess =
- new TestRunnerProcess(config, launch, mJUnitInfo);
+ new TestRunnerProcess(config, mJUnitInfo);
runnerProcess.start();
launch.addProcess(runnerProcess);
}
@@ -173,15 +165,12 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
private static class TestRunnerProcess extends Thread implements IProcess {
private final VMRunnerConfiguration mRunConfig;
- private final ILaunch mLaunch;
private final AndroidJUnitLaunchInfo mJUnitInfo;
private RemoteAdtTestRunner mTestRunner = null;
private boolean mIsTerminated = false;
- TestRunnerProcess(VMRunnerConfiguration runConfig, ILaunch launch,
- AndroidJUnitLaunchInfo info) {
+ TestRunnerProcess(VMRunnerConfiguration runConfig, AndroidJUnitLaunchInfo info) {
mRunConfig = runConfig;
- mLaunch = launch;
mJUnitInfo = info;
}
@@ -194,10 +183,9 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
/**
* {@inheritDoc}
- * @throws DebugException
* @see org.eclipse.debug.core.model.IProcess#getExitValue()
*/
- public int getExitValue() throws DebugException {
+ public int getExitValue() {
return 0;
}
@@ -205,14 +193,14 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
* @see org.eclipse.debug.core.model.IProcess#getLabel()
*/
public String getLabel() {
- return mLaunch.getLaunchMode();
+ return mJUnitInfo.getLaunch().getLaunchMode();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IProcess#getLaunch()
*/
public ILaunch getLaunch() {
- return mLaunch;
+ return mJUnitInfo.getLaunch();
}
/* (non-Javadoc)
@@ -254,10 +242,9 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
/**
* {@inheritDoc}
- * @throws DebugException
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
- public void terminate() throws DebugException {
+ public void terminate() {
if (mTestRunner != null) {
mTestRunner.terminate();
}
@@ -274,3 +261,4 @@ class AndroidJUnitLaunchAction implements IAndroidLaunchAction {
}
}
}
+
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java
index fa8e4b0..543daf0 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java
@@ -22,6 +22,7 @@ import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration;
import com.android.ide.eclipse.adt.launch.AndroidLaunchController;
import com.android.ide.eclipse.adt.launch.IAndroidLaunchAction;
import com.android.ide.eclipse.adt.launch.LaunchConfigDelegate;
+import com.android.ide.eclipse.adt.launch.junit.runtime.AndroidJUnitLaunchInfo;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
@@ -32,8 +33,11 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
/**
* Run configuration that can execute JUnit tests on an Android platform.
@@ -47,6 +51,7 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
/** Launch config attribute that stores instrumentation runner. */
static final String ATTR_INSTR_NAME = AdtPlugin.PLUGIN_ID + ".instrumentation"; //$NON-NLS-1$
+
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
@Override
@@ -55,7 +60,7 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
AndroidLaunchConfiguration config, AndroidLaunchController controller,
IFile applicationPackage, AndroidManifestParser manifestParser) {
- String testPackage = manifestParser.getPackage();
+ String appPackage = manifestParser.getPackage();
String runner = getRunner(project, configuration, manifestParser);
if (runner == null) {
AdtPlugin.displayError("Android Launch",
@@ -63,8 +68,13 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
androidLaunch.stopLaunch();
return;
}
+ AndroidJUnitLaunchInfo junitLaunchInfo = new AndroidJUnitLaunchInfo(project, appPackage,
+ runner);
+ junitLaunchInfo.setTestClass(getTestClass(configuration));
+ junitLaunchInfo.setTestPackage(getTestPackage(configuration));
+ junitLaunchInfo.setTestMethod(getTestMethod(configuration));
- IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(testPackage, runner);
+ IAndroidLaunchAction junitLaunch = new AndroidJUnitLaunchAction(junitLaunchInfo);
controller.launch(project, mode, applicationPackage, manifestParser.getPackage(),
manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
@@ -72,6 +82,49 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
}
/**
+ * Returns the test package stored in the launch configuration, or <code>null</code> if not
+ * specified.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test package info from
+ * @return the test package or <code>null</code>.
+ */
+ private String getTestPackage(ILaunchConfiguration configuration) {
+ // try to retrieve a package name from the JUnit container attribute
+ String containerHandle = getStringLaunchAttribute(
+ JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, configuration);
+ if (containerHandle != null && containerHandle.length() > 0) {
+ IJavaElement element = JavaCore.create(containerHandle);
+ // containerHandle could be a IProject, check if its a java package
+ if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+ return element.getElementName();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the test class stored in the launch configuration.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test class info from
+ * @return the test class. <code>null</code> if not specified.
+ */
+ private String getTestClass(ILaunchConfiguration configuration) {
+ return getStringLaunchAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
+ configuration);
+ }
+
+ /**
+ * Returns the test method stored in the launch configuration.
+ *
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the test method info from
+ * @return the test method. <code>null</code> if not specified.
+ */
+ private String getTestMethod(ILaunchConfiguration configuration) {
+ return getStringLaunchAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
+ configuration);
+ }
+
+ /**
* Gets a instrumentation runner for the launch.
* <p/>
* If a runner is stored in the given <code>configuration</code>, will return that.
@@ -114,11 +167,29 @@ public class AndroidJUnitLaunchConfigDelegate extends LaunchConfigDelegate {
}
private String getRunnerFromConfig(ILaunchConfiguration configuration) throws CoreException {
- String runner = configuration.getAttribute(ATTR_INSTR_NAME, EMPTY_STRING);
- if (runner.length() < 1) {
- return null;
+ return getStringLaunchAttribute(ATTR_INSTR_NAME, configuration);
+ }
+
+ /**
+ * Helper method to retrieve a string attribute from the launch configuration
+ *
+ * @param attributeName name of the launch attribute
+ * @param configuration the {@link ILaunchConfiguration} to retrieve the attribute from
+ * @return the attribute's value. <code>null</code> if not found.
+ */
+ private String getStringLaunchAttribute(String attributeName,
+ ILaunchConfiguration configuration) {
+ try {
+ String attrValue = configuration.getAttribute(attributeName, EMPTY_STRING);
+ if (attrValue.length() < 1) {
+ return null;
+ }
+ return attrValue;
+ } catch (CoreException e) {
+ AdtPlugin.log(e, String.format("Error when retrieving launch info %1$s", //$NON-NLS-1$
+ attributeName));
}
- return runner;
+ return null;
}
/**
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java
index eb57482..584d45e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java
@@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.launch.junit;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.launch.MainLaunchConfigTab;
import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.ProjectChooserHelper;
import org.eclipse.core.resources.IProject;
@@ -241,7 +242,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
private void createTestContainerSelectionGroup(Composite comp) {
mTestContainerRadioButton = new Button(comp, SWT.RADIO);
mTestContainerRadioButton.setText(
- JUnitMessages.JUnitLaunchConfigurationTab_label_containerTest);
+ "Run all tests in the selected project, or package");
GridData gd = new GridData();
gd.horizontalSpan = 3;
mTestContainerRadioButton.setLayoutData(gd);
@@ -249,12 +250,12 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
public void widgetSelected(SelectionEvent e) {
if (mTestContainerRadioButton.getSelection()) {
testModeChanged();
- }
+ }
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
-
+
mContainerText = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalIndent = 25;
@@ -265,7 +266,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
updateLaunchConfigurationDialog();
}
});
-
+
mContainerSearchButton = new Button(comp, SWT.PUSH);
mContainerSearchButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_search);
mContainerSearchButton.addSelectionListener(new SelectionAdapter() {
@@ -821,7 +822,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
@SuppressWarnings("unchecked")
private IJavaElement chooseContainer(IJavaElement initElement) {
- Class[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IJavaProject.class,
+ Class[] acceptedClasses = new Class[] { IJavaProject.class,
IPackageFragment.class };
TypedElementSelectionValidator validator = new TypedElementSelectionValidator(
acceptedClasses, false) {
@@ -839,7 +840,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
if (element instanceof IPackageFragmentRoot &&
((IPackageFragmentRoot) element).isArchive()) {
return false;
- }
+ }
try {
if (element instanceof IPackageFragment &&
!((IPackageFragment) element).hasChildren()) {
@@ -852,7 +853,7 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
}
};
- StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider();
+ AndroidJavaElementContentProvider provider = new AndroidJavaElementContentProvider();
ILabelProvider labelProvider = new JavaElementLabelProvider(
JavaElementLabelProvider.SHOW_DEFAULT);
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(),
@@ -974,4 +975,23 @@ public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurat
mInstrumentations = null;
mInstrumentationCombo.removeAll();
}
+
+ /**
+ * Overrides the {@link StandardJavaElementContentProvider} to only display Android projects
+ */
+ private static class AndroidJavaElementContentProvider
+ extends StandardJavaElementContentProvider {
+
+ /**
+ * Override parent to return only Android projects if at the root. Otherwise, use parent
+ * functionality.
+ */
+ @Override
+ public Object[] getChildren(Object element) {
+ if (element instanceof IJavaModel) {
+ return BaseProjectHelper.getAndroidProjects((IJavaModel) element);
+ }
+ return super.getChildren(element);
+ }
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitPropertyTester.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitPropertyTester.java
new file mode 100644
index 0000000..eadafee
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitPropertyTester.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.adt.launch.junit;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
+
+/**
+ * A {@link PropertyTester} that checks if selected elements can be run as Android
+ * JUnit tests.
+ * <p/>
+ * Based on org.eclipse.jdt.internal.junit.JUnitPropertyTester. The only substantial difference in
+ * this implementation is source folders cannot be run as Android JUnit.
+ */
+@SuppressWarnings("restriction")
+public class AndroidJUnitPropertyTester extends PropertyTester {
+ private static final String PROPERTY_IS_TEST = "isTest"; //$NON-NLS-1$
+
+ private static final String PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST = "canLaunchAsJUnit"; //$NON-NLS-1$
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.corext.refactoring.participants.properties.IPropertyEvaluator#test(java.lang.Object, java.lang.String, java.lang.String)
+ */
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (!(receiver instanceof IAdaptable)) {
+ final String elementName = (receiver == null ? "null" : //$NON-NLS-1$
+ receiver.getClass().getName());
+ throw new IllegalArgumentException(
+ String.format("Element must be of type IAdaptable, is %s", //$NON-NLS-1$
+ elementName));
+ }
+
+ IJavaElement element;
+ if (receiver instanceof IJavaElement) {
+ element = (IJavaElement) receiver;
+ } else if (receiver instanceof IResource) {
+ element = JavaCore.create((IResource) receiver);
+ if (element == null) {
+ return false;
+ }
+ } else { // is IAdaptable
+ element= (IJavaElement) ((IAdaptable) receiver).getAdapter(IJavaElement.class);
+ if (element == null) {
+ IResource resource = (IResource) ((IAdaptable) receiver).getAdapter(
+ IResource.class);
+ element = JavaCore.create(resource);
+ if (element == null) {
+ return false;
+ }
+ }
+ }
+ if (PROPERTY_IS_TEST.equals(property)) {
+ return isJUnitTest(element);
+ } else if (PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST.equals(property)) {
+ return canLaunchAsJUnitTest(element);
+ }
+ throw new IllegalArgumentException(
+ String.format("Unknown test property '%s'", property)); //$NON-NLS-1$
+ }
+
+ private boolean canLaunchAsJUnitTest(IJavaElement element) {
+ try {
+ switch (element.getElementType()) {
+ case IJavaElement.JAVA_PROJECT:
+ return true; // can run, let JDT detect if there are tests
+ case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+ return false; // not supported by Android test runner
+ case IJavaElement.PACKAGE_FRAGMENT:
+ return ((IPackageFragment) element).hasChildren();
+ case IJavaElement.COMPILATION_UNIT:
+ case IJavaElement.CLASS_FILE:
+ case IJavaElement.TYPE:
+ case IJavaElement.METHOD:
+ return isJUnitTest(element);
+ default:
+ return false;
+ }
+ } catch (JavaModelException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Return whether the target resource is a JUnit test.
+ */
+ private boolean isJUnitTest(IJavaElement element) {
+ try {
+ IType testType = null;
+ if (element instanceof ICompilationUnit) {
+ testType = (((ICompilationUnit) element)).findPrimaryType();
+ } else if (element instanceof IClassFile) {
+ testType = (((IClassFile) element)).getType();
+ } else if (element instanceof IType) {
+ testType = (IType) element;
+ } else if (element instanceof IMember) {
+ testType = ((IMember) element).getDeclaringType();
+ }
+ if (testType != null && testType.exists()) {
+ return TestSearchEngine.isTestOrTestSuite(testType);
+ }
+ } catch (CoreException e) {
+ // ignore, return false
+ }
+ return false;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java
index 89cad97..8ac80ca 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java
@@ -15,35 +15,38 @@
*/
package com.android.ide.eclipse.adt.launch.junit.runtime;
-import org.eclipse.core.resources.IProject;
-
import com.android.ddmlib.IDevice;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.debug.core.ILaunch;
+
/**
* Contains info about Android JUnit launch
*/
public class AndroidJUnitLaunchInfo {
private final IProject mProject;
- private final String mTestPackage;
+ private final String mAppPackage;
private final String mRunner;
- private final boolean mDebugMode;
- private final IDevice mDevice;
-
- public AndroidJUnitLaunchInfo(IProject project, String testPackage, String runner,
- boolean debugMode, IDevice device) {
+
+ private boolean mDebugMode = false;
+ private IDevice mDevice = null;
+ private String mTestPackage = null;
+ private String mTestClass = null;
+ private String mTestMethod = null;
+ private ILaunch mLaunch = null;
+
+ public AndroidJUnitLaunchInfo(IProject project, String appPackage, String runner) {
mProject = project;
- mTestPackage = testPackage;
+ mAppPackage = appPackage;
mRunner = runner;
- mDebugMode = debugMode;
- mDevice = device;
}
-
+
public IProject getProject() {
return mProject;
}
- public String getTestPackage() {
- return mTestPackage;
+ public String getAppPackage() {
+ return mAppPackage;
}
public String getRunner() {
@@ -53,8 +56,80 @@ public class AndroidJUnitLaunchInfo {
public boolean isDebugMode() {
return mDebugMode;
}
+
+ public void setDebugMode(boolean debugMode) {
+ mDebugMode = debugMode;
+ }
public IDevice getDevice() {
return mDevice;
}
+
+ public void setDevice(IDevice device) {
+ mDevice = device;
+ }
+
+ /**
+ * Specify to run all tests within given package.
+ *
+ * @param testPackage fully qualified java package
+ */
+ public void setTestPackage(String testPackage) {
+ mTestPackage = testPackage;
+ }
+
+ /**
+ * Return the package of tests to run.
+ *
+ * @return fully qualified java package. <code>null</code> if not specified.
+ */
+ public String getTestPackage() {
+ return mTestPackage;
+ }
+
+ /**
+ * Sets the test class to run.
+ *
+ * @param testClass fully qualfied test class to run
+ * Expected format: x.y.x.testclass
+ */
+ public void setTestClass(String testClass) {
+ mTestClass = testClass;
+ }
+
+ /**
+ * Returns the test class to run.
+ *
+ * @return fully qualfied test class to run.
+ * <code>null</code> if not specified.
+ */
+ public String getTestClass() {
+ return mTestClass;
+ }
+
+ /**
+ * Sets the test method to run. testClass must also be set.
+ *
+ * @param testMethod test method to run
+ */
+ public void setTestMethod(String testMethod) {
+ mTestMethod = testMethod;
+ }
+
+ /**
+ * Returns the test method to run.
+ *
+ * @return test method to run. <code>null</code> if not specified.
+ */
+ public String getTestMethod() {
+ return mTestMethod;
+ }
+
+ public ILaunch getLaunch() {
+ return mLaunch;
+ }
+
+ public void setLaunch(ILaunch launch) {
+ mLaunch = launch;
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java
index 0a6a3da..962d761 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java
@@ -69,8 +69,9 @@ public class RemoteAdtTestRunner extends RemoteTestRunner {
* executing the tests, and send it back to JDT JUnit. The second is the actual test execution,
* whose results will be communicated back in real-time to JDT JUnit.
*
- * @param testClassNames array of fully qualified test class names to execute. Cannot be empty.
- * @param testName test to execute. If null, will be ignored.
+ * @param testClassNames ignored - the AndroidJUnitLaunchInfo will be used to determine which
+ * tests to run.
+ * @param testName ignored
* @param execution used to report test progress
*/
@Override
@@ -78,16 +79,21 @@ public class RemoteAdtTestRunner extends RemoteTestRunner {
// hold onto this execution reference so it can be used to report test progress
mExecution = execution;
- RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mLaunchInfo.getTestPackage(),
+ RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mLaunchInfo.getAppPackage(),
mLaunchInfo.getRunner(), mLaunchInfo.getDevice());
- if (testClassNames != null && testClassNames.length > 0) {
- if (testName != null) {
- runner.setMethodName(testClassNames[0], testName);
- } else {
- runner.setClassNames(testClassNames);
- }
+ if (mLaunchInfo.getTestClass() != null) {
+ if (mLaunchInfo.getTestMethod() != null) {
+ runner.setMethodName(mLaunchInfo.getTestClass(), mLaunchInfo.getTestMethod());
+ } else {
+ runner.setClassName(mLaunchInfo.getTestClass());
+ }
}
+
+ if (mLaunchInfo.getTestPackage() != null) {
+ runner.setTestPackageName(mLaunchInfo.getTestPackage());
+ }
+
// set log only to first collect test case info, so Eclipse has correct test case count/
// tree info
runner.setLogOnly(true);