/******************************************************************************* * Copyright (c) 2012 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.runtime.common; import junit.framework.TestCase; import com.windowtester.internal.runtime.junit.core.ExecutionMonitor; import com.windowtester.internal.runtime.junit.core.IExecutionContext; import com.windowtester.internal.runtime.junit.core.IExecutionMonitor; import com.windowtester.internal.runtime.junit.core.SequenceRunner; import com.windowtester.internal.runtime.junit.core.ISequenceRunner.IRunnable; import com.windowtester.internal.runtime.junit.core.launcher.IApplicationLauncher; import com.windowtester.internal.runtime.junit.core.launcher.LauncherFactory; import com.windowtester.runtime.IUIContext; import com.windowtester.runtime.internal.TestClassManager; import com.windowtester.runtime.util.TestMonitor; /** * A common UI TestCase base class for SWT, RCP and Swing UI tests. */ public abstract class UITestCaseCommon extends TestCase { /** * Cached UIContext instance. */ private IUIContext ui; /** * Used manage execution state. */ private IExecutionContext executionContext; /** * Used to launch the application under test. */ private IApplicationLauncher applicationLauncher; /** * Manages onetime setup and teardown. */ private final static TestClassManager testClassWatcher = new TestClassManager() { public void firstRun(TestCase t) throws Exception { ((UITestCaseCommon)t).oneTimeSetup(); } public void lastRun(TestCase t) throws Exception { ((UITestCaseCommon)t).oneTimeTearDown(); } }; ///////////////////////////////////////////////////////////////////////////////// // // Instance Creation // ///////////////////////////////////////////////////////////////////////////////// /** * Create an instance. */ public UITestCaseCommon() { this((String)null); } /** * Create an instance with the given name. */ public UITestCaseCommon(String testName) { this(testName, (Class<?>)null); } public UITestCaseCommon(String testName, Class<?> launchClass) { this(testName, launchClass, null); } /** * Create an instance that will launch and test the specified application class. * * @param launchClass - The application class to be launched by calling the static * main method with the specified arguments (see ) in a separate thread, or * <code>null</code> if no application is to be launched. */ public UITestCaseCommon(Class<?> launchClass) { this(launchClass, null); } /** * Create an instance that will launch and test the specified application class. * * @param launchClass - The application class to be launched by calling the static * main method with the specified arguments (see ) in a separate thread, or * <code>null</code> if no application is to be launched. * @param launchArgs - The arguments to be passed to the static main method of the * application class to be launched, or <code>null</code> if no * application is to be launched. */ public UITestCaseCommon(Class<?> launchClass, String[] launchArgs) { this(null, launchClass, launchArgs); } public UITestCaseCommon(String testName, Class<?> launchClass, String[] launchArgs) { super(testName); //create a launcher for the given class and args (note: NoOP launcher class created //in case class is null applicationLauncher = LauncherFactory.create(launchClass, launchArgs); testClassWatcher.toRun(this); } ///////////////////////////////////////////////////////////////////////////////// // // Test Lifecycle // ///////////////////////////////////////////////////////////////////////////////// /* (non-Javadoc) * @see junit.framework.TestCase#runBare() */ public void runBare() throws Throwable { //decrement tests to run counter -- TODO: should this be moved? // --_testsToRun; //exec launch (NOTE: should this be in runner?) launchApp(); //run test runUITest(new UITestRunnable() { public void run() throws Throwable { UITestCaseCommon.super.runBare(); } }); } public void runUITest(final UITestRunnable runnable) throws Throwable { //start test monitor ---> TODO: this should be in the exec monitor/runner TestMonitor.getInstance().beginTestCase(this); //get an execution monitor appropriate for this test type IExecutionMonitor execMonitor = getExecutionMonitor(); //publish execution context ExecutionMonitor.setContext(getExecutionContext()); //run the test in a separate monitored thread new SequenceRunner(execMonitor).exec(new IRunnable(){ public void run() throws Throwable { runStarted(); try { runnable.run(); } finally { runFinished(); } } }); //stop test monitor ---> TODO: this should be in the exec monitor/runner TestMonitor.getInstance().endTestCase(); } private void launchApp() { IApplicationLauncher launcher = getApplicationLauncher(); launch(launcher); launcher.launch(); } /** * Perform application launching, called before launching. * Note: subclasses can participate in launching by attaching listeners * here. For example: * <pre> * la * </pre> * @param launcher */ protected void launch(IApplicationLauncher launcher) { //deafult is to do nothing } /** * Get an execution monitor for the current test. */ protected IExecutionMonitor getExecutionMonitor() { return getExecutionContext().getExecutionMonitor(); } private IApplicationLauncher getApplicationLauncher() { return applicationLauncher; } protected IExecutionContext getExecutionContext() { if (executionContext == null) executionContext = createExecutionContext(); return executionContext; } /** * Create an execution context instance for the current test. * It is the subclass responsibility to create the appropriate execution context for its test type. */ protected abstract IExecutionContext createExecutionContext(); private void runStarted() throws Exception { testClassWatcher.runStarted(this); } private void runFinished() throws Exception { testClassWatcher.runFinished(this); } /** * Performs one time setup of the test fixture. Called once per test class, before * setup. */ protected void oneTimeSetup() throws Exception { //default: no-op } /** * Performs one time teardown of the test fixture. Called once per test class, after * teardown. */ protected void oneTimeTearDown() throws Exception { //default: no-op } ///////////////////////////////////////////////////////////////////////////////// // // UI Access // ///////////////////////////////////////////////////////////////////////////////// /** * Get the backing UI instance appropriate for this test execution. */ public IUIContext getUI() { if (ui == null) ui = getExecutionContext().getUI(); return ui; } }