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```