Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(847)

Unified Diff: testing/android/docs/junit4.md

Issue 2749353002: Add doc on customizing TestRule (Closed)
Patch Set: Address comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: testing/android/docs/junit4.md
diff --git a/testing/android/docs/junit4.md b/testing/android/docs/junit4.md
index d697bcd5e7ffc0073264f9cf8b0cc5fb2436fae4..1168ff5f2e9d1f52746af2ce506630f1f97a3a65 100644
--- a/testing/android/docs/junit4.md
+++ b/testing/android/docs/junit4.md
@@ -1,4 +1,3 @@
-
# JUnit 4 Migration
As of Android 24 (N), JUnit3 style javatests have been deprecated for the new
@@ -7,6 +6,8 @@ We are in the process of changing all instrumentation tests in chromium to
JUnit4 style. This doc explains the differences between JUnit3 and JUnit4
instrumentation tests and how to write or convert them.
+[TOC]
+
## Differences between JUnit3 and JUnit4 instrumentation tests
| | JUnit3 | JUnit4 |
@@ -24,14 +25,14 @@ instrumentation tests and how to write or convert them.
> The tag for the JUnit4 runner must specify `chromium-junit4:"true"`
> ([Example][2])
-- **Other JUnit4 features**:
+- **Other JUnit4 features**:
- Tests can be annotated to expect an exception, e.g.
`@Test(expected=MyException.class)`. Tests annotated this way will
fail if they do not throw the given exception.
- **Test suite set up**: public static method annotated with `@BeforeClass`
- **Test suite tear down**: public static method annotated with
`@AfterClass`
-- **Replacement for JUnit3 test base classes**
+- **Replacement for JUnit3 test base classes**
- [`TestRule`][3]:
- TestRule is a class to **outsource your test setUp, tearDown, and
utility methods**. Since there are no more interitance and TestBase classes,
@@ -46,112 +47,194 @@ instrumentation tests and how to write or convert them.
Support Library that allows tests to launch an Activity.
([Documentation][4])
-
## Example Code of JUnit3 test and JUnit4 test
JUnit3:
```java
- public class MyTestClass extends MyActivityInstrumentationTestCase2<TestActivity> {
- @Override
- protected void setUp(){
- super.setUp();
- setActivityIntent(new Intent());
- getActivity();
- }
+public class MyTestClass extends MyActivityInstrumentationTestCase2<TestActivity> {
+ @Override
+ protected void setUp(){
+ super.setUp();
+ setActivityIntent(new Intent());
+ getActivity();
+ }
- @Override
- protected void tearDown() {
- specialActionFromSuper();
- super.tearDown();
- }
+ @Override
+ protected void tearDown() {
+ specialActionFromSuper();
+ super.tearDown();
+ }
- public void testA() {
- assertEquals(1, 1);
- }
+ public void testA() {
+ assertEquals(1, 1);
}
+}
```
JUnit4:
```java
- @RunWith(BaseJUnit4ClassRunner.class);
- public class TestClass {
- @Rule public ActivityTestRule<TestActivity> mRule = new ActivityTestRule<>(TestActivity.class);
+@RunWith(BaseJUnit4ClassRunner.class);
+public class TestClass {
+ @Rule public ActivityTestRule<TestActivity> mRule = new ActivityTestRule<>(TestActivity.class);
- @Before
- public void setUp() { //Must be public
- mRule.launchActivity(new Intent());
- }
+ @Before
+ public void setUp() { //Must be public
+ mRule.launchActivity(new Intent());
+ }
- @After
- public void tearDown() { //Must be public
- mRule.specialActionFromActivityTestRule();
- }
+ @After
+ public void tearDown() { //Must be public
+ mRule.specialActionFromActivityTestRule();
+ }
- @Test
- public void testA() {
- Assert.assertEquals(1, 1);
- }
+ @Test
+ public void testA() {
+ Assert.assertEquals(1, 1);
}
+}
```
## Migration process
-1. Add required libraries to your target dependencies in BUILD.gn
- - JUnit 4 library: `//third_party/junit`
- - Android Testing Support Rules:
- - `//third_party/android_support_test_runner:runner_java` (for `AndroidJUnitRunner`, etc)
- - `//third_party/android_support_test_runner:rules_java` (for `ActivityTestRule`, etc)
-2. Add class runner to your test apk manifest.
- ([example][2])
- - Keep in mind you can have multiple instrumentations in your manifest. Our
- test runner will run JUnit4 tests with JUnit4 runner and JUnit3 tests
- with non-JUnit4 runner.
-3. Refactor TestBase class to a TestRule class.
- ([example CL](https://codereview.chromium.org/2632043002))
- - +yolandyan will do this part, however, if you did refactoring yourself,
- please add him as a reviewer for your CL and enjoy his eternal appreciation!
-4. Use [auto migrate script][5]
- to or manually convert all JUnit3 tests to JUnit4 style in a your javatest
- directory
- - we understand it's tedious to just manually write all the annotations,
- change modifiers, etc to convert all the javatest, so we created an auto
- change script that helps you to convert all the javatests in a certain
- directory. Please check its [README page][5]
- on instructions.
+1. Add required libraries to your target dependencies in BUILD.gn
+ - JUnit 4 library: `//third_party/junit`
+ - Android Testing Support Rules:
+ - `//third_party/android_support_test_runner:runner_java`
+ (for `AndroidJUnitRunner`, etc)
+ - `//third_party/android_support_test_runner:rules_java`
+ (for `ActivityTestRule`, etc)
+2. Add class runner to your test apk manifest.
+ ([example][2])
+ - Keep in mind you can have multiple instrumentations in your manifest.
+ Our test runner will run JUnit4 tests with JUnit4 runner and JUnit3
+ tests with non-JUnit4 runner.
+3. Refactor TestBase class to a TestRule class.
+ ([example CL](https://codereview.chromium.org/2632043002))
+ - +yolandyan will do this part, however, if you did refactoring yourself,
+ please add him as a reviewer for your CL and enjoy his eternal appreciation!
+4. Use [auto migrate script][5] to or manually convert all JUnit3 tests to
+ JUnit4 style in a your javatest directory
+ - we understand it's tedious to just manually write all the annotations,
+ change modifiers, etc to convert all the javatest, so we created an auto
+ change script that helps you to convert all the javatests in a certain
+ directory. Please check its [README page][5]
+ on instructions.
+
+
+## Customized TestRule example
+
+TestRule:
+
+```java
+public class MyRule implements TestRule {
+ // 1: Add utility methods...
+
+ @Override
+ public Statement apply(final Statement base, Description desc) {
+ return new Statement() {
+ @Override
+ public void evaluate() {
+ // 2: Code here runs before @Before method
+ base.evaluate()
+ // 3: Code here runs after @After method
+ }
+ }
+ }
+}
+```
+
## Caveats
-1. Instrumentation tests that rely on test thread to have message handler
- will not work. For example error message:
-```
-java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
-```
- Please utilize `@UiThreadTest` or `ActivityTestRule.runOnUiThread(Runnable r)`
- to refactor these tests. For more, check this [github issue][6]
+1. Instrumentation tests that rely on test thread to have message handler
+ will not work. For example error message:
+
+ java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
+
+ Please utilize `@UiThreadTest` or
+ `ActivityTestRule.runOnUiThread(Runnable r)` to refactor these tests.
+ For more, check this [github issue][6]
nyquist 2017/03/23 21:28:00 Nit: GitHub
the real yoland 2017/03/24 01:35:49 Done
+
+2. Use `@UiThreadTest` with caution. Currently,
nyquist 2017/03/23 21:28:00 Nit: 1. throughout.
the real yoland 2017/03/24 01:35:49 Done
+ **@UiThreadTest is only effective when UiThreadTestRule or
+ ActivityTestRule is declared** in the test class. Please use
+ `android.support.test.annotation.UiThreadTest`, not
+ `android.test.UiThreadTest`. When using @UiThreadTest, **it would cause
+ `setUp` and `tearDown` to run in Ui Thread** as well. Avoid that by simply
+ calling [`runOnUiThread`][9] or [`runOnMainSync`][10] with a Runnable.
+
+ ```java
+ //Wrong test
nyquist 2017/03/23 21:28:00 Nit: space after // and period at the end. Same be
the real yoland 2017/03/24 01:35:49 Done
+ public class Test {
+ @Rule
+ public ActivityTestRule<MyActivity> mRule = new ActivityTestRule<>(
+ MyActivity.class>
+
+ @Before
+ public void setUp() {
+ // Cause failure because this also runs on Ui Thread, while it
+ // is intended for Instrumentation worker thread
+ mRule.launchActivity()
+ }
+
+ @UiThreadTest
+ public void test() {
+ actionThatNeedsUiThread();
+ }
+ }
+ ```
+
+ The correct thing to do is
-2. `assertEquals(float a, float b)` and `assertEquals(double a, double b)` are
+ ```java
+ //Correct test
+ public class Test {
+ @Rule
+ public ActivityTestRule<MyActivity> mRule = new ActivityTestRule<>(
+ MyActivity.class>
+
+ @Before
+ public void setUp() {
+ mRule.launchActivity()
+ }
+
+ public void test() {
+ mRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ actionThatNeedsUiThread();
+ }
+ });
+ }
+ }
+ ```
+
+
+3. `assertEquals(float a, float b)` and `assertEquals(double a, double b)` are
deprecated in JUnit4's Assert class. **Despite only generating a warning at
build time, they fail at runtime.** Please use
`Assert.assertEquals(float a, float b, float delta)`
+
## Common questions
-- Q: are `@Test` and `@LargeTest/@MediumTest/@SmallTest` annotation both
- necessary?
- - A: Yes, both are required for now. We plan to refactor this in the future.
-- Q: Isn't the inheritance of the Test classes just migrated to inheritance
- of TestRules?
- - A: Yes. During the migration, we plan to maintain a 1:1 mapping between
- the test base classes and TestRules (e.g. ContentShellTestBase to
- ContentShellTestRule in this [CL](https://codereview.chromium.org/2632043002)).
- This allows the auto convert script to replace API calls in any
- JUnit3 tests. After the migration, we plan to refactor the TestRules to
- be more modular.
-
-If you have any other questions, feel free to report in
-[this bug][7].
+- Q: are `@Test` and `@LargeTest/@MediumTest/@SmallTest` annotation both
nyquist 2017/03/23 21:28:00 Nit: "Are"
the real yoland 2017/03/24 01:35:49 Done
+ necessary?
+ - A: Yes, both are required for now. We plan to refactor this in the
+ future.
+- Q: Isn't the inheritance of the Test classes just migrated to inheritance
+ of TestRules?
+ - A: Yes. During the migration, we plan to maintain a 1:1 mapping between
+ the test base classes and TestRules (e.g. ContentShellTestBase to
+ ContentShellTestRule in this
+ [CL](https://codereview.chromium.org/2632043002)).
+ This allows the auto convert script to replace API calls in any
+ JUnit3 tests. After the migration, we plan to refactor the TestRules to
+ be more modular.
+
+If you have any other questions, feel free to report in [this bug][7].
## Links and Crbugs
@@ -167,3 +250,5 @@ If you have any other questions, feel free to report in
[6]: http://github.com/skyisle/android-test-kit/issues/121
[7]: https://bugs.chromium.org/p/chromium/issues/detail?id=640116
[8]: http://junit.org/junit4/javadoc/4.12/org/junit/rules/RuleChain.html
+[9]: https://developer.android.com/reference/android/app/Instrumentation.html#runOnMainSync(java.lang.Runnable)
+[10]: https://developer.android.com/reference/android/support/test/rule/UiThreadTestRule.html#runOnUiThread(java.lang.Runnable)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698