Skip to content

Commit 2ea701d

Browse files
committed
Rename utility classes and refactor test runner
1 parent bcec158 commit 2ea701d

File tree

7 files changed

+97
-181
lines changed

7 files changed

+97
-181
lines changed

smoke-tests/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ dependencies {
6060

6161
implementation "com.google.firebase:firebase-common:16.0.7"
6262

63-
androidTestImplementation "androidx.test.espresso:espresso-core:3.1.0"
64-
androidTestImplementation "androidx.test.espresso:espresso-idling-resource:3.1.0"
6563
androidTestImplementation "androidx.test:runner:1.1.0"
6664

6765
// Firestore

smoke-tests/src/androidTest/java/com/google/firebase/testing/common/SmokeTestBase.java

Lines changed: 0 additions & 78 deletions
This file was deleted.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.testing.common;
16+
17+
import android.app.Activity;
18+
import android.util.Log;
19+
import java.lang.reflect.InvocationTargetException;
20+
import java.lang.reflect.Method;
21+
22+
/**
23+
* A runner for smoke tests.
24+
*
25+
* <p>This class will eventually become a JUnit runner, but it is simply a utility class for now.
26+
*
27+
* <p>All smoke tests should manually use this class until JUnit integration is complete. Test
28+
* methods must be annotated with {@link SmokeTest} and must be in the test's primary activity.
29+
*
30+
* <p>This design enables test code to be built, obfuscated, and run like any other application's
31+
* code. Test methods may be fully defined in one source tree, instead of splitting them across the
32+
* two APKs used during testing.
33+
*/
34+
public class SmokeTestRunner {
35+
36+
private static final String TAG = "SmokeTestRunner";
37+
38+
/**
39+
* Runs all smoke tests in the provided activity.
40+
*
41+
* <p>This method reflectively obtains all methods defined in the activity with the {@link
42+
* SmokeTest} annotation. These are executed sequentially. Any exception thrown by the test
43+
* methods is rethrown here without wrapping.
44+
*/
45+
public static void runSmokeTests(Activity instance) throws Exception {
46+
Method[] methods = instance.getClass().getMethods();
47+
Log.d(TAG, "Searching for SmokeTest methods.");
48+
for (Method method : methods) {
49+
if (method.getAnnotation(SmokeTest.class) == null) {
50+
continue;
51+
}
52+
53+
Log.d(TAG, "Preparing to run method, " + method.getName() + ".");
54+
try {
55+
method.invoke(instance);
56+
Log.d(TAG, "Test method complete.");
57+
} catch (IllegalAccessException ex) {
58+
throw new IllegalStateException("Test method is not public", ex);
59+
} catch (InvocationTargetException ex) {
60+
Throwable t = ex.getCause();
61+
if (t instanceof Exception) {
62+
throw (Exception) t;
63+
} else if (t instanceof Error) {
64+
throw (Error) t;
65+
}
66+
67+
throw new IllegalStateException("Test threw unexpected Throwable", t);
68+
}
69+
}
70+
71+
Log.d(TAG, "Finished test runs.");
72+
}
73+
}

smoke-tests/src/androidTest/java/com/google/firebase/testing/common/TestApkUtil.java

Lines changed: 0 additions & 73 deletions
This file was deleted.

smoke-tests/src/androidTestFirestore/java/com/google/firebase/testing/firestore/FirestoreTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
import android.util.Log;
1818
import androidx.test.rule.ActivityTestRule;
1919
import androidx.test.runner.AndroidJUnit4;
20-
import com.google.firebase.testing.common.SmokeTestBase;
20+
import com.google.firebase.testing.common.SmokeTestRunner;
2121
import org.junit.Rule;
2222
import org.junit.Test;
2323
import org.junit.runner.RunWith;
2424

2525
@RunWith(AndroidJUnit4.class)
26-
public final class FirestoreTest extends SmokeTestBase {
26+
public final class FirestoreTest {
2727

2828
private static final String TAG = "FirestoreTest";
2929

@@ -36,7 +36,7 @@ public void runSmokeTests() throws Exception {
3636
Log.d(TAG, "Initializing activity.");
3737
FirestoreActivity instance = atr.getActivity();
3838

39-
// Delegate to base class.
40-
runSmokeTests(instance);
39+
// Delegate to test runner class.
40+
SmokeTestRunner.runSmokeTests(instance);
4141
}
4242
}

smoke-tests/src/firestore/java/com/google/firebase/testing/firestore/FirestoreActivity.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import com.google.firebase.firestore.FirebaseFirestoreException;
2828
import com.google.firebase.firestore.ListenerRegistration;
2929
import com.google.firebase.testing.common.SmokeTest;
30-
import com.google.firebase.testing.common.TestUtil;
30+
import com.google.firebase.testing.common.Tasks2;
3131
import java.util.HashMap;
3232

3333
/** An empty activity with Firestore smoke tests. */
@@ -40,7 +40,7 @@ public void listenForUpdate() throws Exception {
4040

4141
auth.signOut();
4242
Task<?> signInTask = auth.signInWithEmailAndPassword("[email protected]", "password");
43-
TestUtil.waitForSuccess(signInTask);
43+
Tasks2.waitForSuccess(signInTask);
4444

4545
DocumentReference doc = firestore.collection("restaurants").document("Baadal");
4646
SnapshotListener listener = new SnapshotListener();
@@ -52,8 +52,8 @@ public void listenForUpdate() throws Exception {
5252

5353
Task<?> setTask = doc.set(new HashMap<>(data));
5454
Task<DocumentSnapshot> snapshotTask = listener.toTask();
55-
TestUtil.waitForSuccess(setTask);
56-
TestUtil.waitForSuccess(snapshotTask);
55+
Tasks2.waitForSuccess(setTask);
56+
Tasks2.waitForSuccess(snapshotTask);
5757

5858
DocumentSnapshot result = snapshotTask.getResult();
5959
assertThat(result.getData()).isEqualTo(data);

smoke-tests/src/main/java/com/google/firebase/testing/common/TestUtil.java renamed to smoke-tests/src/main/java/com/google/firebase/testing/common/Tasks2.java

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,28 @@
1515
package com.google.firebase.testing.common;
1616

1717
import com.google.android.gms.tasks.Task;
18-
import java.lang.reflect.InvocationTargetException;
19-
import java.lang.reflect.Method;
18+
import com.google.android.gms.tasks.Tasks;
19+
import java.util.concurrent.ExecutionException;
20+
import java.util.concurrent.TimeUnit;
2021

21-
/** Test utilities invoked from the application APK. */
22-
public final class TestUtil {
22+
/** Test utilities for asynchronous tasks. */
23+
public final class Tasks2 {
2324

24-
private static Method waitForSuccessImpl;
25+
private static final long WAIT_DURATION = 30;
26+
private static final TimeUnit WAIT_UNIT = TimeUnit.SECONDS;
2527

26-
private TestUtil() {}
28+
private Tasks2() {}
2729

28-
@SuppressWarnings("unchecked")
30+
/**
31+
* Waits for the task to complete successfully.
32+
*
33+
* <p>This method will block the current thread and return the result of the task. It will rethrow
34+
* any expection thrown by the task without wrapping.
35+
*/
2936
public static <T> T waitForSuccess(Task<T> task) throws Exception {
30-
if (waitForSuccessImpl == null) {
31-
try {
32-
Class<?> impl = Class.forName("com.google.firebase.testing.common.TestApkUtil");
33-
waitForSuccessImpl = impl.getMethod("waitForSuccess", Task.class);
34-
} catch (Exception ex) {
35-
throw new IllegalStateException("Error initializing test framework", ex);
36-
}
37-
}
38-
3937
try {
40-
return (T) waitForSuccessImpl.invoke(null, task);
41-
} catch (InvocationTargetException ex) {
38+
return Tasks.await(task, WAIT_DURATION, WAIT_UNIT);
39+
} catch (ExecutionException ex) {
4240
Throwable t = ex.getCause();
4341
if (t instanceof Exception) {
4442
throw (Exception) t;
@@ -47,8 +45,6 @@ public static <T> T waitForSuccess(Task<T> task) throws Exception {
4745
}
4846

4947
throw new IllegalStateException("Task threw unexpected Throwable", t);
50-
} catch (Exception ex) {
51-
throw new IllegalStateException("Error invoking test APK", ex);
5248
}
5349
}
5450
}

0 commit comments

Comments
 (0)