1# JUnit Tests
2
3JUnit tests are Java unit tests. These tests run locally on your workstation.
4
5[TOC]
6
7## Writing a JUnit test
8
9When writing JUnit tests, you must decide whether you need to use Android code.
10If you want to use Android code you must write a [Robolectric](http://robolectric.org/) test.
11
12### JUnit tests (without Android)
13
14Build these types of test using the `junit_binary` GN template.
15
16If you don't need to use any Android code in your tests, you can write plain,
17old JUnit tests. Some more documentation about writing JUnit tests can be
18found [here](https://github.com/junit-team/junit4/wiki/Getting-started).
19
20#### Example Code
21
22```java
23package org.chromium.sample.test;
24
25import static org.junit.Assert.assertTrue;
26
27import org.junit.Test;
28import org.junit.runner.RunWith;
29import org.junit.runners.BlockJUnit4ClassRunner;
30
31@RunWith(BlockJUnit4ClassRunner.class)
32public class MyJUnitTest {
33
34    @Test
35    public void exampleTest() {
36        boolean shouldWriteMoreJUnitTests = true;
37        assertTrue(shouldWriteMoreJUnitTests);
38    }
39}
40```
41
42#### Example within Chromium
43
44See the [junit_unit_tests](https://cs.chromium.org/chromium/src/testing/android/junit/BUILD.gn) test suite.
45
46### JUnit tests with Robolectric
47
48Build these types of test using the `junit_binary` GN template.
49
50Robolectric is a unit testing framework that lets you run tests with Android
51code on your workstation. It does this by providing a special version of the
52Android SDK jar that can run in your host JVM. Some more information about
53Robolectric can be found [here](http://robolectric.org/).
54
55One on the main benefits of using Robolectric framework are [shadow classes](http://robolectric.org/extending/).
56Robolectric comes with many prebuilt shadow classes and also lets you define
57your own. Whenever an object is instantiated within a Robolectric test,
58Robolectric looks for a corresponding shadow class (marked by
59`@Implements(ClassBeingShadowed.class)`). If found, any time a method is invoked
60on the object, the shadow class's implementation of the method is invoked first.
61This works even for static and final methods.
62
63#### Useful Tips
64
65* Use `@RunWith(LocalRobolectricTestRunner.class)` for all Chromium Robolectric tests.
66* You can specify the Android SDK to run your test with with `@Config(sdk = ??)`.
67
68> Currently, only SDK levels 18, 21, and 25 are supported in Chromium
69> but more can be added on request.
70
71#### Example Code
72
73```java
74package org.chromium.sample.test;
75
76import static org.junit.Assert.assertTrue;
77
78import android.text.TextUtils;
79
80import org.junit.Test;
81import org.junit.runner.RunWith;
82import org.robolectric.annotation.Config;
83
84import org.chromium.testing.local.LocalRobolectricTestRunner;
85
86// Be sure to specify to run tests with the LocalRobolectricTestRunner. The
87// default JUnit test runner won't load the Robolectric Android code properly.
88@RunWith(LocalRobolectricTestRunner.class)
89// Can specify some Robolectric related configs here.
90// More about configuring Robolectric at http://robolectric.org/configuring/.
91// SDK will default to the latest we support in Chromium.
92@Config(manifest = Config.NONE, sdk = 21)
93public class MyRobolectricJUnitTest {
94
95    @Test
96    public void exampleTest() {
97        String testString = "test";
98
99        // Even though these tests runs on the host, Android classes are
100        // available to use thanks to Robolectric.
101        assertTrue(TextUtils.equals(testString, "test"));
102    }
103}
104```
105
106#### Example junit_binary build template.
107
108```python
109junit_binary("my_robolectric_tests") {
110
111    sources = [
112        "java/src/foo/bar/MyJUnitTest.java"
113    ]
114
115    deps = [
116        "//my/test:dependency",
117    ]
118
119    # Sets app's package name in Robolectric tests. You need to specify
120    # this variable in order for Robolectric to be able to find your app's
121    # resources.
122    package_name = manifest_package
123}
124```
125
126#### Example within Chromium
127
128See the [content_junit_tests](https://cs.chromium.org/chromium/src/content/public/android/BUILD.gn) test suite.
129
130## Running JUnit tests
131
132After writing a test, you can run it by:
133
1341. Adding the test file to a `junit_binary` GN target.
1352. Rebuild.
1363. GN will generate binary `<out_dir>/bin/run_<suite name>` which
137   can be used to run your test.
138
139For example, the following can be used to run chrome_junit_tests.
140
141```bash
142# Build the test suite after adding our new test.
143ninja -C out/Debug chrome_junit_tests
144
145# Run the test!
146out/Debug/bin/run_chrome_junit_tests
147```