From 4bc762a919ead1ad02d4ee065a95e4ecf8a4e657 Mon Sep 17 00:00:00 2001
From: Quddus Chong Unit tests are the fundamental tests in your app testing strategy. By creating and running unit
+tests against your code, you can easily verify that the logic of individual units is correct.
+Running unit tests after every build helps you to
+quickly catch and fix software regressions introduced by code changes to your app.
+ A unit test generally exercises the functionality of the smallest possible unit of code (which
+could be a method, class, or component) in a repeatable way. You should build unit tests when you
+need to verify the logic of specific code in your app. For example, if you are unit testing a
+class, your test might check that the class is in the right state. Typically, the unit of code
+is tested in isolation; your test affects and monitors changes to that unit only. A
+mocking framework
+can be used to isolate your unit from its dependencies. Note: Unit tests are not suitable for testing
+complex UI interaction events. Instead, you should use the UI testing frameworks, as described in
+Automating UI Tests. For testing Android apps, you typically create these types of automated unit tests: The lessons in this class teach you how to build these types of automated unit tests.
+Instrumented unit tests are unit tests that run on physical devices and emulators, instead of
+the Java Virtual Machine (JVM) on your local machine. You should create instrumented unit tests
+if your tests need access to instrumentation information (such as the target app's
+{@link android.content.Context}) or if they require the real implementation of an Android framework
+component (such as a {@link android.os.Parcelable} or {@link android.content.SharedPreferences}
+object). Using instrumented unit tests also helps to reduce the effort required to write and
+maintain mock code. You are still free to use a mocking framework, if you choose, to simulate any
+dependency relationships. Instrumented unit tests can take advantage of the Android framework APIs
+and supporting APIs, such as the Android Testing Support Library.
+ Before building instrumented unit tests, you must:
+Your instrumented unit test class should be written as a JUnit 4 test class. To learn more about
+creating JUnit 4 test classes and using JUnit 4 assertions and annotations, see
+Create a Local Unit Test Class.
+ To create an instrumented JUnit 4 test class, add the {@code @RunWith(AndroidJUnit4.class)}
+annotation at the beginning of your test class definition. You also need to specify the
+
+{@code AndroidJUnitRunner} class
+provided in the Android Testing Support Library as your default test runner. This step is described
+in more detail in Run Instrumented Unit Tests.
+ The following example shows how you might write an instrumented unit test to test that
+the {@link android.os.Parcelable} interface is implemented correctly for the
+{@code LogHistory} class:
+To organize the execution of your instrumented unit tests, you can group a collection of test
+classes in a test suite class and run these tests together. Test suites can be nested;
+your test suite can group other test suites and run all their component test classes together.
+
+A test suite is contained in a test package, similar to the main application package. By
+convention, the test suite package name usually ends with the {@code .suite} suffix (for example,
+{@code com.example.android.testing.mysample.suite}).
+
+To create a test suite for your unit tests, import the JUnit
+{@code RunWith} and
+{@code Suite} classes. In your test suite, add the
+{@code @RunWith(Suite.class)} and the {@code @Suite.SuitClasses()} annotations. In
+the {@code @Suite.SuiteClasses()} annotation, list the individual test classes or test
+suites as arguments.
+
+The following example shows how you might implement a test suite called {@code UnitTestSuite}
+that groups and runs the {@code CalculatorInstrumentationTest} and
+{@code CalculatorAddParameterizedTest} test classes together.
+
+The
+
+ Android Plug-in for Gradle
+provides a default directory ({@code src/androidTest/java}) for you to store the instrumented unit
+and integration test classes and test suites that you want to run on a device. The plug-in compiles
+the test code in that directory and then executes the test app using a test runner class. You must
+set the
+
+{@code AndroidJUnitRunner} class provided in the
+Android Testing Support Library
+as your default test runner.
+ You should also read
+
+
+
+
+
+
+Lessons
+
+
\ No newline at end of file
diff --git a/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd
new file mode 100644
index 0000000..07f0f73
--- /dev/null
+++ b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd
@@ -0,0 +1,250 @@
+page.title=Building Instrumented Unit Tests
+page.tags=testing,androidjunitrunner,junit,unit test,mock,instrumentation
+trainingnavtop=true
+
+@jd:body
+
+
+Dependencies and Prerequisites
+
+
+
+
+ This lesson teaches you to
+
+
+
+
+ Try it out
+
+
+Set Up Your Testing Environment
+
+
+
+app/src/androidTest/java
folder.
+ To learn more about setting up your project directory, see
+ Managing Projects.
+
+dependencies {
+ androidTestCompile 'com.android.support.test:runner:0.2'
+ androidTestCompile 'com.android.support.test:rules:0.2'
+ // Set this dependency if you want to use Hamcrest matching
+ androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
+}
+
+ Create an Instrumented Unit Test Class
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import java.util.List;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+@RunWith(AndroidJUnit4.class)
+public class LogHistoryAndroidUnitTest {
+
+ public static final String TEST_STRING = "This is a string";
+ public static final long TEST_LONG = 12345678L;
+ private LogHistory mLogHistory;
+
+ @Before
+ public void createLogHistory() {
+ mLogHistory = new LogHistory();
+ }
+
+ @Test
+ public void logHistory_ParcelableWriteRead() {
+ // Set up the Parcelable object to send and receive.
+ mLogHistory.addEntry(TEST_STRING, TEST_LONG);
+
+ // Write the data.
+ Parcel parcel = Parcel.obtain();
+ mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());
+
+ // After you're done with writing, you need to reset the parcel for reading.
+ parcel.setDataPosition(0);
+
+ // Read the data.
+ LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
+ List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData();
+
+ // Verify that the received data is correct.
+ assertThat(createdFromParcelData.size(), is(1));
+ assertThat(createdFromParcelData.get(0).first, is(TEST_STRING));
+ assertThat(createdFromParcelData.get(0).second, is(TEST_LONG));
+ }
+}
+
+
+Creating a test suite
+
+import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
+import com.example.android.testing.mysample.CalculatorInstrumentationTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+// Runs all unit tests.
+@RunWith(Suite.class)
+@Suite.SuiteClasses({CalculatorInstrumentationTest.class,
+ CalculatorAddParameterizedTest.class})
+public class UnitTestSuite {}
+
+
+Run Instrumented Unit Tests
+
To specify + +{@code AndroidJUnitRunner} as the default test instrumentation runner, add the following +setting in your {@code build.gradle} file:
++android { + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } +} ++ +
+To run instrumented unit tests in your Gradle project from Android Studio: +
+Android Studio displays the results of the unit test execution in the Run +window.
+ +To run instrumented unit tests in your Gradle project from the command-line, call the + {@code connectedCheck} (or {@code cC}) task:
+ ++./gradlew cC ++ +
You can find the generated HTML test result reports in the +{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory, +and the corresponding XML files in the +{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.
\ No newline at end of file diff --git a/docs/html/training/testing/unit-testing/local-unit-tests.jd b/docs/html/training/testing/unit-testing/local-unit-tests.jd new file mode 100644 index 0000000..421709b --- /dev/null +++ b/docs/html/training/testing/unit-testing/local-unit-tests.jd @@ -0,0 +1,302 @@ +page.title=Building Local Unit Tests +page.tags=testing,androidjunitrunner,junit,unit test,mock +trainingnavtop=true + +@jd:body + + +If your unit test has no dependencies or only has simple dependencies on Android, you should run +your test on a local development machine. This testing approach is efficient because it helps +you avoid the overhead of loading the target app and unit test code onto a physical device or +emulator every time your test is run. Consequently, the execution time for running your unit +test is greatly reduced. With this approach, you normally use a mocking framework, like +Mockito, to fulfill any +dependency relationships.
+ +Android Plug-in for Gradle +version 1.1.0 and higher allows you to create a source directory ({@code src/test/java}) in your +project to store JUnit tests that you want to run on a local machine. This feature improves your +project organization by letting you group your unit tests together into a single source set. You +can run the tests from Android Studio or the command-line, and the plugin executes them on the +local Java Virtual Machine (JVM) on your development machine.
+ +Before building local unit tests, you must:
+ +app/src/test/java
folder.
+ To learn more about setting up your project directory, see
+ Run Local Unit Tests and
+ Managing Projects.
+ +dependencies { + // Unit testing dependencies + testCompile 'junit:junit:4.12' + // Set this dependency if you want to use Mockito + testCompile 'org.mockito:mockito-core:1.10.19' + // Set this dependency if you want to use Hamcrest matching + androidTestCompile 'org.hamcrest:hamcrest-library:1.1' +} ++
Your local unit test class should be written as a JUnit 4 test class. +JUnit is the most popular +and widely-used unit testing framework for Java. The latest version of this framework, JUnit 4, +allows you to write tests in a cleaner and more flexible way than its predecessor versions. Unlike +the previous approach to Android unit testing based on JUnit 3, with JUnit 4, you do not need to +extend the {@code junit.framework.TestCase} class. You also do not need to prefix your test method +name with the {@code ‘test’} keyword, or use any classes in the {@code junit.framework} or +{@code junit.extensions} package.
+ +To create a basic JUnit 4 test class, create a Java class that contains one or more test methods. +A test method begins with the {@code @Test} annotation and contains the code to exercise +and verify a single functionality in the component that you want to test.
+ +The following example shows how you might implement a local unit test class. The test method +{@code emailValidator_CorrectEmailSimple_ReturnsTrue} verifies that the {@code isValidEmail()} +method in the app under test returns the correct result.
+ ++import org.junit.Test; +import java.util.regex.Pattern; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class EmailValidatorTest { + + @Test + public void emailValidator_CorrectEmailSimple_ReturnsTrue() { + assertThat(EmailValidator.isValidEmail("name@email.com"), is(true)); + } + ... +} ++ +
To test that components in your app return the expected results, use the + +junit.Assert methods to perform validation checks (or assertions) to compare the state +of the component under test against some expected value. To make tests more readable, you +can use +Hamcrest matchers (such as the {@code is()} and {@code equalTo()} methods) to match the +returned result against the expected result.
+ +In your JUnit 4 test class, you can use annotations to call out sections in your test code for +special processing, such as:
+ ++By default, the +Android Plug-in for Gradle executes your local unit tests against a modified +version of the {@code android.jar} library, which does not contain any actual code. Instead, method +calls to Android classes from your unit test throw an exception. +
++You can use a mocking framework to stub out external dependencies in your code, to easily test that +your component interacts with a dependency in an expected way. By substituting Android dependencies +with mock objects, you can isolate your unit test from the rest of the Android system while +verifying that the correct methods in those dependencies are called. The +Mockito mocking framework +for Java (version 1.9.5 and higher) offers compatibility with Android unit testing. +With Mockito, you can configure mock objects to return some specific value when invoked.
+ +To add a mock object to your local unit test using this framework, follow this programming model: +
+ ++The following example shows how you might create a unit test that uses a mock +{@link android.content.Context} object. +
+ ++import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.CoreMatchers.*; +import static org.mockito.Mockito.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import android.content.SharedPreferences; + +@RunWith(MockitoJUnitRunner.class) +public class UnitTestSample { + + private static final String FAKE_STRING = "HELLO WORLD"; + + @Mock + Context mMockContext; + + @Test + public void readStringFromContext_LocalizedString() { + // Given a mocked Context injected into the object under test... + when(mMockContext.getString(R.string.hello_word)) + .thenReturn(FAKE_STRING); + ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext); + + // ...when the string is returned from the object under test... + String result = myObjectUnderTest.getHelloWorldString(); + + // ...then the result should be the expected one. + assertThat(result, is(FAKE_STRING)); + } +} ++ +
+To learn more about using the Mockito framework, see the +Mockito API reference and the +{@code SharedPreferencesHelperTest} class in the +sample code. +
+ ++The Android Plug-in for Gradle provides a default directory ({@code src/test/java}) for you to +store unit test classes that you want to run on a local JVM. The plug-in compiles the test code in +that directory and then executes the test app locally using the default test runner class. +
++As with production code, you can create unit tests for a +specific flavor or build type. You should keep unit tests in a test +source tree location that corresponds to your production source tree, such as: + +
Path to Production Class | +Path to Local Unit Test Class | +
---|---|
{@code src/main/java/Foo.java} | +{@code src/test/java/FooTest.java} | +
{@code src/debug/java/Foo.java} | +{@code src/testDebug/java/FooTest.java} | +
{@code src/myFlavor/java/Foo.java} | +{@code src/testMyFlavor/java/FooTest.java} | +
+To run local unit tests in your Gradle project from Android Studio: +
+Android Studio displays the results of the unit test execution in the Run +window.
+ +To run local unit tests in your Gradle project from the command-line, call the {@code test} task +command with the {@code --continue} option.
+ ++./gradlew test --continue ++ +
If there are failing tests, the command will display links to HTML reports (one per build +variant). You can find the generated HTML test result reports in the +{@code <path_to_your_project>/app/build/reports/tests/} directory, and the corresponding XML +files in the {@code <path_to_your_project>/app/build/test-results/} directory.
\ No newline at end of file diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 3ee7ab7..0a13672 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1858,6 +1858,24 @@ results." +