aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Jin <kjin@google.com>2015-02-17 12:01:06 -0800
committerKevin Jin <kjin@google.com>2015-02-17 13:07:45 -0800
commit0af99cf1b946ba40e19356a9dcf12cbf5a9a33c6 (patch)
tree15a37990ebbce13d48c69a19a4c5e10659ef9a9c
parent514b47e26150180248b22b1173b4d2cbccd086f7 (diff)
downloaddroiddriver-0af99cf1b946ba40e19356a9dcf12cbf5a9a33c6.tar.gz
Add SingleRun, a safer mechanism than classSetUp
Change-Id: If7c8f42d9fbbfb012783d12587fbbfc8d0b01729
-rw-r--r--manualtest/src/com/google/android/droiddriver/manualtest/ManualTest.java5
-rw-r--r--src/com/google/android/droiddriver/helpers/BaseDroidDriverTest.java40
-rw-r--r--src/com/google/android/droiddriver/helpers/SingleRun.java46
3 files changed, 81 insertions, 10 deletions
diff --git a/manualtest/src/com/google/android/droiddriver/manualtest/ManualTest.java b/manualtest/src/com/google/android/droiddriver/manualtest/ManualTest.java
index 238db2e..c1f3946 100644
--- a/manualtest/src/com/google/android/droiddriver/manualtest/ManualTest.java
+++ b/manualtest/src/com/google/android/droiddriver/manualtest/ManualTest.java
@@ -37,9 +37,4 @@ public class ManualTest extends BaseDroidDriverTest<Activity> {
// assertEquals(password, driver.on(password_edit).getText());
assertEquals(null, driver.on(password_edit).getText());
}
-
- @Override
- protected final void classSetUp() {
- DroidDrivers.init(DroidDrivers.newDriver(getInstrumentation()));
- }
}
diff --git a/src/com/google/android/droiddriver/helpers/BaseDroidDriverTest.java b/src/com/google/android/droiddriver/helpers/BaseDroidDriverTest.java
index 9905cf4..48113fd 100644
--- a/src/com/google/android/droiddriver/helpers/BaseDroidDriverTest.java
+++ b/src/com/google/android/droiddriver/helpers/BaseDroidDriverTest.java
@@ -17,6 +17,7 @@
package com.google.android.droiddriver.helpers;
import android.app.Activity;
+import android.app.Instrumentation;
import android.content.Context;
import android.os.Debug;
import android.test.FlakyTest;
@@ -40,6 +41,30 @@ import java.lang.reflect.Modifier;
*/
public abstract class BaseDroidDriverTest<T extends Activity> extends
D2ActivityInstrumentationTestCase2<T> {
+ /**
+ * Calls {@link DroidDrivers#init} once and only once.
+ */
+ public static class DroidDriversInitializer extends SingleRun {
+ private static DroidDriversInitializer instance;
+ protected final Instrumentation instrumentation;
+
+ protected DroidDriversInitializer(Instrumentation instrumentation) {
+ this.instrumentation = instrumentation;
+ }
+
+ @Override
+ protected void run() {
+ DroidDrivers.init(DroidDrivers.newDriver(instrumentation));
+ }
+
+ public static synchronized DroidDriversInitializer get(Instrumentation instrumentation) {
+ if (instance == null) {
+ instance = new DroidDriversInitializer(instrumentation);
+ }
+ return instance;
+ }
+ }
+
private static boolean classSetUpDone = false;
// In case of device-wide fatal errors, e.g. OOME, the remaining tests will
// fail and the messages will not help, so skip them.
@@ -86,12 +111,17 @@ public abstract class BaseDroidDriverTest<T extends Activity> extends
}
/**
- * Initializes test fixture once for all tests extending this class. Typically
- * you call {@link DroidDrivers#init} with an appropriate instance. If an
- * InstrumentationDriver is used, this is a good place to call
- * {@link com.google.android.droiddriver.instrumentation.ViewElement#overrideClassName}
+ * Initializes test fixture once for all tests extending this class. This may have unexpected
+ * behavior - if multiple subclasses override this method, only the override is executed. The
+ * other overrides are silently ignored. You can either use {@link SingleRun} in {@link #setUp},
+ * or override this method, which is a simpler alternative with the aforementioned catch.
+ * <p/>
+ * If an InstrumentationDriver is used, this is a good place to call {@link
+ * com.google.android.droiddriver.instrumentation.ViewElement#overrideClassName}
*/
- protected abstract void classSetUp();
+ protected void classSetUp() {
+ DroidDriversInitializer.get(getInstrumentation()).singleRun();
+ }
protected boolean reportSkippedAsFailed() {
return false;
diff --git a/src/com/google/android/droiddriver/helpers/SingleRun.java b/src/com/google/android/droiddriver/helpers/SingleRun.java
new file mode 100644
index 0000000..d11e1b0
--- /dev/null
+++ b/src/com/google/android/droiddriver/helpers/SingleRun.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 DroidDriver committers
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.google.android.droiddriver.helpers;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Base class for an action that should run only once no matter how many times the method {@link
+ * #singleRun()} is called upon an instance. Typically it is used on a singleton to achieve once for
+ * a class effect.
+ */
+public abstract class SingleRun {
+ private AtomicBoolean hasRun = new AtomicBoolean();
+
+ /**
+ * Calls {@link #run()} if it is the first time this method is called upon this instance.
+ *
+ * @return true if this is the first time it is called, otherwise false
+ */
+ public boolean singleRun() {
+ if (hasRun.compareAndSet(false, true)) {
+ run();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Takes the action that should run only once.
+ */
+ protected abstract void run();
+}