Showing preview only (1,092K chars total). Download the full file or copy to clipboard to get everything.
Repository: android/testing-samples
Branch: main
Commit: 8c9df3a534ef
Files: 577
Total size: 923.0 KB
Directory structure:
gitextract_2qqpyglt/
├── .bazelrc
├── .github/
│ ├── ci-gradle.properties
│ └── workflows/
│ ├── composescreenshot.yml
│ ├── copy-branch.yml
│ ├── gradle-wrapper-validation.yml
│ └── test-all.yml
├── .gitignore
├── BUILD.bazel
├── CODEOWNERS
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── WORKSPACE
├── bazelci/
│ └── buildkite-pipeline.yml
├── common_defs.bzl
├── integration/
│ └── ServiceTestRuleSample/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── ServiceTestRuleSample/
│ │ │ └── LocalServiceTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── ServiceTestRuleSample/
│ │ │ └── LocalService.java
│ │ └── res/
│ │ ├── values/
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v13/
│ │ │ └── styles.xml
│ │ └── values-v21/
│ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── projects.conf
├── renovate.json
├── runner/
│ ├── AndroidJunitRunnerSample/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── androidjunitrunnersample/
│ │ │ │ ├── CalculatorAddParameterizedTest.java
│ │ │ │ ├── CalculatorInstrumentationTest.java
│ │ │ │ ├── CalculatorTest.java
│ │ │ │ ├── HintMatcher.java
│ │ │ │ ├── OperationHintInstrumentationTest.java
│ │ │ │ ├── OperationHintLegacyInstrumentationTest.java
│ │ │ │ └── suite/
│ │ │ │ ├── AndroidTestSuite.java
│ │ │ │ ├── InstrumentationTestSuite.java
│ │ │ │ └── UnitTestSuite.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── androidjunitrunnersample/
│ │ │ │ ├── Calculator.java
│ │ │ │ └── CalculatorActivity.java
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_calculator.xml
│ │ │ ├── values/
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-v14/
│ │ │ │ └── styles.xml
│ │ │ ├── values-v21/
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ ├── AndroidTestOrchestratorSample/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── androidtestorchestratorsample/
│ │ │ │ ├── CalculatorAddParameterizedTest.java
│ │ │ │ └── CalculatorInstrumentationTest.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── androidtestorchestratorsample/
│ │ │ │ ├── Calculator.java
│ │ │ │ └── CalculatorActivity.java
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_calculator.xml
│ │ │ ├── values/
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-v14/
│ │ │ │ └── styles.xml
│ │ │ ├── values-v21/
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ └── AndroidTestOrchestratorWithTestCoverageSample/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── androidtestorchestratorsample/
│ │ │ ├── CalculatorAddParameterizedTest.java
│ │ │ └── CalculatorInstrumentationTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── androidtestorchestratorsample/
│ │ │ ├── Calculator.java
│ │ │ └── CalculatorActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_calculator.xml
│ │ ├── values/
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v14/
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── test_all.sh
├── ui/
│ ├── PreviewScreenshot/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── .gitignore
│ │ │ ├── build.gradle.kts
│ │ │ ├── proguard-rules.pro
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── compose/
│ │ │ │ │ └── previewscreenshot/
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ └── ui/
│ │ │ │ │ └── theme/
│ │ │ │ │ ├── Color.kt
│ │ │ │ │ ├── Theme.kt
│ │ │ │ │ └── Type.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── themes.xml
│ │ │ │ ├── values-es/
│ │ │ │ │ └── strings.xml
│ │ │ │ └── xml/
│ │ │ │ ├── backup_rules.xml
│ │ │ │ └── data_extraction_rules.xml
│ │ │ └── screenshotTest/
│ │ │ └── kotlin/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── compose/
│ │ │ └── previewscreenshot/
│ │ │ └── MainScreen.kt
│ │ ├── build.gradle.kts
│ │ ├── gradle/
│ │ │ ├── libs.versions.toml
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle.kts
│ ├── espresso/
│ │ ├── AccessibilitySample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── AccessibilitySample/
│ │ │ │ │ └── AccessibilityChecksTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── AccessibilitySample/
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v13/
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── BasicSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── BasicSample/
│ │ │ │ │ ├── ChangeTextBehaviorKtTest.kt
│ │ │ │ │ └── ChangeTextBehaviorTest.java
│ │ │ │ ├── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── AppManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── android/
│ │ │ │ │ │ └── testing/
│ │ │ │ │ │ └── espresso/
│ │ │ │ │ │ └── BasicSample/
│ │ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ │ └── ShowTextActivity.java
│ │ │ │ │ └── res/
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ ├── activity_main.xml
│ │ │ │ │ │ └── activity_show_text.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── dimens.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v13/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v21/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-w820dp/
│ │ │ │ │ └── dimens.xml
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── BasicSample/
│ │ │ │ └── ChangeTextBehaviorLocalTest.java
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── CustomMatcherSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── AppManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── android/
│ │ │ │ │ │ └── testing/
│ │ │ │ │ │ └── espresso/
│ │ │ │ │ │ └── CustomMatcherSample/
│ │ │ │ │ │ └── MainActivity.java
│ │ │ │ │ └── res/
│ │ │ │ │ ├── drawable/
│ │ │ │ │ │ ├── correct.xml
│ │ │ │ │ │ └── incorrect.xml
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ └── activity_main.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── dimens.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v13/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v21/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-w820dp/
│ │ │ │ │ └── dimens.xml
│ │ │ │ └── sharedTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── CustomMatcherSample/
│ │ │ │ ├── HintMatcher.java
│ │ │ │ └── HintMatchersTest.java
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── DataAdapterSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── AppManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── android/
│ │ │ │ │ │ └── testing/
│ │ │ │ │ │ └── espresso/
│ │ │ │ │ │ └── DataAdapterSample/
│ │ │ │ │ │ └── LongListActivity.java
│ │ │ │ │ └── res/
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ ├── list_activity.xml
│ │ │ │ │ │ └── list_item.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── dimens.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v21/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-w820dp/
│ │ │ │ │ └── dimens.xml
│ │ │ │ └── sharedTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── DataAdapterSample/
│ │ │ │ └── LongListActivityTest.java
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── EspressoDeviceSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── EspressoDeviceSample/
│ │ │ │ │ ├── RequiresDisplayTest.kt
│ │ │ │ │ └── ResizeDisplayTest.kt
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── EspressoDeviceSample/
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v13/
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── FragmentScenarioSample/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── build.gradle
│ │ │ │ ├── proguard-rules.pro
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── android/
│ │ │ │ │ │ └── testing/
│ │ │ │ │ │ └── espresso/
│ │ │ │ │ │ └── fragmentscenario/
│ │ │ │ │ │ ├── SampleDialogFragment.kt
│ │ │ │ │ │ └── SampleFragment.kt
│ │ │ │ │ └── res/
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ └── fragment_sample.xml
│ │ │ │ │ └── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── sharedTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── fragmentscenario/
│ │ │ │ ├── SampleDialogFragmentTest.kt
│ │ │ │ └── SampleFragmentTest.kt
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── IdlingResourceSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── IdlingResourceSample/
│ │ │ │ │ └── ChangeTextBehaviorTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── IdlingResourceSample/
│ │ │ │ │ ├── IdlingResource/
│ │ │ │ │ │ └── SimpleIdlingResource.java
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ └── MessageDelayer.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v13/
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── IntentsAdvancedSample/
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── intents/
│ │ │ │ │ └── AdvancedSample/
│ │ │ │ │ ├── ImageViewHasDrawableMatcher.java
│ │ │ │ │ └── ImageViewerActivityTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── intents/
│ │ │ │ │ └── AdvancedSample/
│ │ │ │ │ └── ImageViewerActivity.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_image_viewer.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v13/
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── IntentsBasicSample/
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── AppManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── android/
│ │ │ │ │ │ └── testing/
│ │ │ │ │ │ └── espresso/
│ │ │ │ │ │ └── IntentsBasicSample/
│ │ │ │ │ │ ├── ContactsActivity.java
│ │ │ │ │ │ └── DialerActivity.java
│ │ │ │ │ └── res/
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ ├── activity_contacts.xml
│ │ │ │ │ │ └── activity_dialer.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── dimens.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v13/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── values-v21/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-w820dp/
│ │ │ │ │ └── dimens.xml
│ │ │ │ └── sharedTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── IntentsBasicSample/
│ │ │ │ └── DialerActivityTest.java
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── MultiProcessSample/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── multiprocesssample/
│ │ │ │ │ └── ExampleInstrumentedTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── multiprocesssample/
│ │ │ │ │ ├── DefaultProcessActivity.java
│ │ │ │ │ ├── PrivateProcessActivity.java
│ │ │ │ │ └── Util.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ ├── activity_default_process.xml
│ │ │ │ │ └── activity_private_process.xml
│ │ │ │ └── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── MultiWindowSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── MultiWindowSample/
│ │ │ │ │ └── MultiWindowTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── MultiWindowSample/
│ │ │ │ │ └── SuggestActivity.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── suggest_activity.xml
│ │ │ │ └── values/
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── RecyclerViewSample/
│ │ │ ├── .gitignore
│ │ │ ├── BUILD.bazel
│ │ │ ├── README.md
│ │ │ ├── app/
│ │ │ │ ├── build.gradle
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── RecyclerViewSample/
│ │ │ │ │ └── RecyclerViewSampleTest.java
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── AppManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── RecyclerViewSample/
│ │ │ │ │ ├── CustomAdapter.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ ├── activity_main.xml
│ │ │ │ │ └── text_row_item.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v13/
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ ├── ScreenshotSample/
│ │ │ ├── .gitignore
│ │ │ ├── app/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── build.gradle
│ │ │ │ ├── proguard-rules.pro
│ │ │ │ └── src/
│ │ │ │ ├── androidTest/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── screenshotsample/
│ │ │ │ │ ├── ScreenshotJavaTest.java
│ │ │ │ │ └── ScreenshotTest.kt
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── espresso/
│ │ │ │ │ └── screenshotsample/
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ ├── drawable-v24/
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── themes.xml
│ │ │ │ └── values-night/
│ │ │ │ └── themes.xml
│ │ │ ├── build.gradle
│ │ │ ├── gradle/
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ └── settings.gradle
│ │ └── WebBasicSample/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── web/
│ │ │ │ └── BasicSample/
│ │ │ │ └── WebViewActivityTest.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── assets/
│ │ │ │ ├── web_form.html
│ │ │ │ └── web_form_response.html
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── espresso/
│ │ │ │ └── web/
│ │ │ │ └── BasicSample/
│ │ │ │ └── WebViewActivity.java
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_web_view.xml
│ │ │ ├── values/
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-v13/
│ │ │ │ └── styles.xml
│ │ │ ├── values-v21/
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ └── uiautomator/
│ └── BasicSample/
│ ├── .gitignore
│ ├── BUILD.bazel
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── androidTest/
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── uiautomator/
│ │ │ └── BasicSample/
│ │ │ └── ChangeTextBehaviorTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── AppManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── uiautomator/
│ │ │ └── BasicSample/
│ │ │ ├── MainActivity.java
│ │ │ └── ShowTextActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── activity_show_text.xml
│ │ ├── values/
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v13/
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── unit/
│ ├── BasicNativeAndroidTest/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── .gitignore
│ │ │ ├── build.gradle
│ │ │ ├── proguard-rules.pro
│ │ │ └── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── android/
│ │ │ │ └── testing/
│ │ │ │ └── nativesample/
│ │ │ │ └── AdderTest.kt
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ └── cpp/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── include/
│ │ │ │ └── adder
│ │ │ ├── src/
│ │ │ │ └── adder.cpp
│ │ │ └── test/
│ │ │ └── adder_test.cpp
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ ├── BasicSample/
│ │ ├── .google/
│ │ │ └── packaging.yaml
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── unittesting/
│ │ │ │ │ └── BasicSample/
│ │ │ │ │ ├── EmailValidator.java
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ ├── SharedPreferenceEntry.java
│ │ │ │ │ └── SharedPreferencesHelper.java
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── unittesting/
│ │ │ └── BasicSample/
│ │ │ ├── EmailValidatorTest.java
│ │ │ └── SharedPreferencesHelperTest.java
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ ├── BasicSample-kotlinApp/
│ │ ├── .google/
│ │ │ └── packaging.yaml
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── example/
│ │ │ │ │ └── android/
│ │ │ │ │ └── testing/
│ │ │ │ │ └── unittesting/
│ │ │ │ │ └── BasicSample/
│ │ │ │ │ ├── EmailValidator.kt
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ ├── SharedPreferenceEntry.kt
│ │ │ │ │ └── SharedPreferencesHelper.kt
│ │ │ │ └── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── values-v21/
│ │ │ │ │ ├── dimens.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── unittesting/
│ │ │ └── BasicSample/
│ │ │ ├── EmailValidatorTest.kt
│ │ │ └── SharedPreferencesHelperTest.kt
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ └── BasicUnitAndroidTest/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── unittesting/
│ │ │ └── basicunitandroidtest/
│ │ │ └── LogHistoryAndroidUnitTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── android/
│ │ │ └── testing/
│ │ │ └── unittesting/
│ │ │ └── basicunitandroidtest/
│ │ │ ├── LogHistory.java
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
└── update_versions.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .bazelrc
================================================
# Configurations for testing with Bazel
# Select a configuration by running `bazel test //my:target --config={headless, gui, local_device}`
# Headless instrumentation tests
test:headless --test_arg=--enable_display=false
# Graphical instrumentation tests. Ensure that $DISPLAY is set.
test:gui --test_env=DISPLAY
test:gui --test_arg=--enable_display=true
# Testing with a local emulator or device. Ensure that `adb devices` lists the device.
# Run tests serially.
test:local_device --test_strategy=exclusive
# Use the local device broker type, as opposed to WRAPPED_EMULATOR.
test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER
# Uncomment and set $device_id if there is more than one connected device.
# test:local_device --test_arg=--device_serial_number=$device_id
test --flaky_test_attempts=3
# The unified launcher runs in Python 2 host configuration
# https://github.com/bazelbuild/bazel/issues/7899
build --host_force_python=PY2
# ------------------------
# General RBE configuration
# ------------------------
build:remote --jobs=100
# Java toolchain setup
build:remote --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build:remote --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build:remote --host_javabase=@rbe_default//java:jdk
build:remote --javabase=@rbe_default//java:jdk
# C++ toolchain setup
build:remote --extra_toolchains=@rbe_default//config:cc-toolchain
build:remote --crosstool_top=@rbe_default//cc:toolchain
# Remote instance setup
build:remote --remote_instance_name=projects/bazel-untrusted/instances/default_instance
build:remote --project_id=bazel-untrusted
# Set various strategies so that all actions execute remotely. Mixing remote
# and local execution will lead to errors unless the toolchain and remote
# machine exactly match the host machine.
build:remote --spawn_strategy=remote
build:remote --define=EXECUTOR=remote
# Enable the remote cache so action results can be shared across machines,
# developers, and workspaces.
build:remote --remote_cache=remotebuildexecution.googleapis.com
# Enable remote execution so actions are performed on the remote systems.
build:remote --remote_executor=remotebuildexecution.googleapis.com
# Enable authentication. This will pick up application default credentials by
# default.
build:remote --google_default_credentials
# -------------------------------------------
# Custom RBE configuration for Android builds
# -------------------------------------------
build:remote_android --config=remote # Reuse general configuration
# Platform configuration
build:remote_android --extra_execution_platforms=:android_platform
build:remote_android --host_platform=:android_platform
build:remote_android --platforms=:android_platform
build:remote_android --strategy=DexBuilder=remote
build:remote_android --noexperimental_check_desugar_deps # Workaround for singlejar incompatibility with RBE
build:remote_android --incompatible_strict_action_env
================================================
FILE: .github/ci-gradle.properties
================================================
================================================
FILE: .github/workflows/composescreenshot.yml
================================================
# Workflow name
name: Compose Preview Screenshot
on:
workflow_dispatch:
push:
branches: [ main ]
# When it will be triggered
# And in which branch
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set Up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'
cache: 'gradle'
- name: Build project and run screenshot tests
working-directory: ./ui/PreviewScreenshot
run: ./gradlew validateDebugScreenshotTest
================================================
FILE: .github/workflows/copy-branch.yml
================================================
# Duplicates default main branch to the old master branch
name: Duplicates main to old master branch
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
workflow_dispatch:
push:
branches: [ main ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "copy-branch"
copy-branch:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it,
# but specifies master branch (old default).
- uses: actions/checkout@v2
with:
fetch-depth: 0
ref: master
- run: |
git config user.name github-actions
git config user.email github-actions@github.com
git merge origin/main
git push
================================================
FILE: .github/workflows/gradle-wrapper-validation.yml
================================================
name: Validate Gradle Wrapper
on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
validation:
name: Validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
================================================
FILE: .github/workflows/test-all.yml
================================================
# Workflow name
name: Build + Test all
on:
workflow_dispatch:
push:
branches: [ main ]
# When it will be triggered
# And in which branch
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
ls /dev/kvm
- name: Set Up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '17'
cache: 'gradle'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Build project and run local and device tests
run: ./test_all.sh
- name: Upload test reports
if: always()
uses: actions/upload-artifact@v4
with:
name: test-reports
path: '**/app/build/reports/androidTests'
================================================
FILE: .gitignore
================================================
.idea
*.iml
local.properties
build
.gradle
# Eclipse project files
.project
.settings/
.classpath
bazel-*
.DS_Store
================================================
FILE: BUILD.bazel
================================================
load("@rules_jvm_external//:defs.bzl", "artifact")
load("//:common_defs.bzl", "androidxLibVersion", "coreVersion", "espressoVersion", "extJUnitVersion", "extTruthVersion", "rulesVersion", "runnerVersion")
licenses(["notice"]) # Apache 2.0
android_library(
name = "test_deps",
visibility = ["//visibility:public"],
exports = [
artifact("androidx.annotation:annotation"),
artifact("androidx.test.espresso:espresso-core"),
artifact("androidx.test:rules"),
artifact("androidx.test:runner"),
artifact("androidx.test:monitor"),
artifact("androidx.test.ext:junit"),
artifact("androidx.test:core"),
artifact("com.google.guava:guava"),
artifact("com.google.inject:guice"),
artifact("javax.inject:javax.inject"),
artifact("junit:junit"),
artifact("org.hamcrest:java-hamcrest"),
],
)
# Platform configuration for emulators on RBE for Bazel CI
platform(
name = "android_platform",
constraint_values = [
"@bazel_tools//platforms:x86_64",
"@bazel_tools//platforms:linux",
"@bazel_toolchains//constraints:xenial",
"@bazel_tools//tools/cpp:clang",
],
# TODO(@jin): s/di-cloud-exp/rbe-containers/ when the official android-test container with libxcursor1 and libxcomposite1 is ready.
# URI for official container: docker://gcr.io/rbe-containers/ubuntu16_04-android_test@sha256:<sha256>
remote_execution_properties = """
properties: {
name: "container-image"
value: "docker://gcr.io/di-cloud-exp/rbe-ubuntu16-04-android@sha256:eb3828f71faf595f44b20b97d205e73e8a21982f1d7a170c3ec8f9d33ce3179a"
}
properties: {
name: "dockerNetwork"
value: "standard"
}
properties: {
name: "dockerPrivileged"
value: "true"
}
properties: {
name: "gceMachineType"
value: "n1-standard-2"
}
""",
)
================================================
FILE: CODEOWNERS
================================================
* @josealcerreca
================================================
FILE: CONTRIBUTING.md
================================================
# How to become a contributor and submit your own code
To contribute with a small fix, simply create a pull request. If you want to add a new sample or plan to request a big change, [contact us](https://groups.google.com/forum/#!forum/android-testing-support-library) first.
## Contributing new samples
If you want to contribute full samples, we'd love to review and accept them. In case you need ideas, these are some samples on the roadmap:
* Advanced Idling Resource
* RecyclerView actions
* Sharding
* RunListener
* Rules
You can also contribute to this list if you have a sample request.
## Code style and structure
Please check out the [Code Style for Contributors](https://source.android.com/source/code-style.html) section in AOSP. Also, check out the rest of the samples and maintain as much consistency with them as possible.
## Contributor License Agreements
We'd love to accept your sample apps and patches! Before we can take them, we
have to jump a couple of legal hurdles.
Please fill out either the individual or corporate Contributor License Agreement (CLA).
* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an [individual CLA]
(https://cla.developers.google.com).
* If you work for a company that wants to allow you to contribute your work,
then you'll need to sign a [corporate CLA]
(https://cla.developers.google.com).
* Please make sure you sign both, Android and Google CLA
Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.
## Contributing A Patch
1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a
Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which
you are contributing. Refer to the
[Android Code Style Guide]
(https://source.android.com/source/code-style.html) for the
recommended coding standards for this organization.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
Android testing samples
===================================
A collection of samples demonstrating different frameworks and techniques for automated testing.
### Espresso Samples
**[BasicSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/BasicSample)** - Basic Espresso sample
**[CustomMatcherSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/CustomMatcherSample)** - Shows how to extend Espresso to match the *hint* property of an EditText
**[DataAdapterSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/DataAdapterSample)** - Showcases the `onData()` entry point for Espresso, for lists and AdapterViews
**[FragmentScenarioSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/FragmentScenarioSample)** - Basic usage of `FragmentScenario` with Espresso.
**[IdlingResourceSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/IdlingResourceSample)** - Synchronization with background jobs
**[IntentsBasicSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/IntentsBasicSample)** - Basic usage of `intended()` and `intending()`
**[IntentsAdvancedSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/IntentsAdvancedSample)** - Simulates a user fetching a bitmap using the camera
**[MultiWindowSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/MultiWindowSample)** - Shows how to point Espresso to different windows
**[RecyclerViewSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/RecyclerViewSample)** - RecyclerView actions for Espresso
**[ScreenshotSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/ScreenshotSample)** - Screenshot capturing and saving using Espresso and androidx.test.core APIs
**[WebBasicSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/WebBasicSample)** - Use Espresso-web to interact with WebViews
**[BasicSampleBundled](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/BasicSampleBundled)** - Basic sample for Eclipse and other IDEs
**[MultiProcessSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/MultiProcessSample)** - Showcases how to use multiprocess Espresso.
### UiAutomator Sample
**[BasicSample](https://github.com/googlesamples/android-testing/tree/main/ui/uiautomator/BasicSample)** - Basic UI Automator sample
### AndroidJUnitRunner Sample
**[AndroidJunitRunnerSample](https://github.com/googlesamples/android-testing/tree/main/runner/AndroidJunitRunnerSample)** - Showcases test annotations, parameterized tests and testsuite creation
### JUnit4 Rules Sample
**All previous samples use ActivityTestRule or IntentsTestRule but there's one specific to ServiceTestRule:
**[BasicSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/BasicSample)** - Simple usage of `ActivityTestRule`
**[IntentsBasicSample](https://github.com/googlesamples/android-testing/blob/main/ui/espresso/IntentsBasicSample)** - Simple usage of `IntentsTestRule`
**[ServiceTestRuleSample](https://github.com/googlesamples/android-testing/tree/main/integration/ServiceTestRuleSample)** - Simple usage of `ServiceTestRule`
Prerequisites
--------------
- Android SDK v28
- Android Build Tools v28.03
Getting Started
---------------
These samples use the Gradle build system. To build a project, enter the project directory and use the `./gradlew assemble` command or use "Import Project" in Android Studio.
- Use `./gradlew connectedAndroidTest` to run the tests on a connected emulator or device.
- Use `./gradlew test` to run the unit test on your local host.
There is a top-level `build.gradle` file if you want to build and test all samples from the root directory. This is mostly helpful to build on a CI (Continuous Integration) server.
AndroidX Test Library
---------------
Many of these samples use the AndroidX Test Library. Visit the [Testing site on developer.android.com](https://developer.android.com/training/testing) for more information.
Experimental Bazel Support
--------------------------
[](https://buildkite.com/bazel/android-testing)
Some of these samples can be tested with [Bazel](https://bazel.build) on Linux. These samples contain a `BUILD.bazel` file, which is similar to a `build.gradle` file. The external dependencies are defined in the top level `WORKSPACE` file.
This is __experimental__ feature. To run the tests, please install the latest version of Bazel (0.12.0 or later) by following the [instructions on the Bazel website](https://docs.bazel.build/versions/master/install-ubuntu.html).
### Bazel commands
```
# Clone the repository if you haven't.
$ git clone https://github.com/google/android-testing
$ cd android-testing
# Edit the path to your local SDK at the top of the WORKSPACE file
$ $EDITOR WORKSPACE
# Test everything in a headless mode (no graphical display)
$ bazel test //... --config=headless
# Test a single test, e.g. ui/espresso/BasicSample/BUILD.bazel
$ bazel test //ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_21_x86 --config=headless
# Query for all android_instrumentation_test targets
$ bazel query 'kind(android_instrumentation_test, //...)'
//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_23_x86
//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_22_x86
//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_21_x86
//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_19_x86
//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_23_x86
//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_22_x86
//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_21_x86
//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_19_x86
//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_23_x86
//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_22_x86
...
# Test everything with GUI enabled
$ bazel test //... --config=gui
# Test with a local device or emulator. Ensure that `adb devices` lists the device.
$ bazel test //... --config=local_device
# If multiple devices are connected, add --device_serial_number=$identifier where $identifier is the name of the device in `adb devices`
$ bazel test //... --config=local_device --test_arg=--device_serial_number=$identifier
```
For more information, check out the documentation for [Android Instrumentation Tests in Bazel](https://docs.bazel.build/versions/master/android-instrumentation-test.html). You may also want to check out [Building an Android App with Bazel](https://docs.bazel.build/versions/master/tutorial/android-app.html), and the list of [Android Rules](https://docs.bazel.build/versions/master/be/android.html) in the Bazel Build Encyclopedia.
Known issues:
* Building of APKs is supported on Linux, Mac and Windows, but testing is only supported on Linux.
* `android_instrumentation_test.target_device` attribute still needs to be specified even if `--config=local_device` is used.
* If using a local device or emulator, the APKs are not uninstalled automatically after the test. Use this command to
remove the packages:
* `adb shell pm list packages com.example.android.testing | cut -d ':' -f 2 | tr -d '\r' | xargs -L1 -t adb uninstall`
Please file Bazel related issues against the [Bazel](https://github.com/bazelbuild/bazel) repository instead of this repository.
Support
-------
- Google+ Community: https://plus.google.com/communities/105153134372062985968
- Stack Overflow: http://stackoverflow.com/questions/tagged/android-testing
If you've found an error in this sample, please file an issue:
https://github.com/googlesamples/android-testing
Patches are encouraged, and may be submitted by forking this project and
submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
License
-------
Copyright 2015 The Android Open Source Project, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
================================================
FILE: WORKSPACE
================================================
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_maven_import_external")
# Set the path to your local SDK installation, or use the ANDROID_HOME environment variable.
android_sdk_repository(name = "androidsdk")
# Required for running emulator tests on RBE on Bazel CI
android_ndk_repository(name = "androidndk")
# Android Test Support
#
# This repository contains the supporting tools to run Android instrumentation tests,
# like the emulator definitions (android_device) and the device broker/test runner.
ATS_TAG = "1edfdab3134a7f01b37afabd3eebfd2c5bb05151"
ATS_SHA256 = "dcd1ff76aef1a26329d77863972780c8fe1fc8ff625747342239f0489c2837ec"
http_archive(
name = "android_test_support",
sha256 = ATS_SHA256,
strip_prefix = "android-test-%s" % ATS_TAG,
urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_TAG],
)
load("@android_test_support//:repo.bzl", "android_test_repositories")
android_test_repositories()
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "3.1"
RULES_JVM_EXTERNAL_SHA = "e246373de2353f3d34d35814947aa8b7d0dd1a58c2f7a6c41cfeaff3007c2d14"
http_archive(
name = "rules_jvm_external",
sha256 = RULES_JVM_EXTERNAL_SHA,
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
load("@rules_jvm_external//:specs.bzl", "maven")
load(
"//:common_defs.bzl",
"androidxLibVersion",
"coreVersion",
"espressoVersion",
"extJUnitVersion",
"extTruthVersion",
"rulesVersion",
"runnerVersion",
"uiAutomatorVersion",
)
maven_install(
name = "maven",
artifacts = [
"androidx.annotation:annotation:" + androidxLibVersion,
"androidx.core:core:" + androidxLibVersion,
"androidx.recyclerview:recyclerview:" + androidxLibVersion,
"androidx.test:core:" + coreVersion,
"androidx.test.espresso:espresso-accessibility:" + espressoVersion,
"androidx.test.espresso:espresso-contrib:" + espressoVersion,
"androidx.test.espresso:espresso-core:" + espressoVersion,
"androidx.test.espresso:espresso-idling-resource:" + espressoVersion,
"androidx.test.espresso:espresso-intents:" + espressoVersion,
"androidx.test.ext:junit:" + extJUnitVersion,
"androidx.test.ext:truth:" + extTruthVersion,
"androidx.test:monitor:" + runnerVersion,
"androidx.test:rules:" + rulesVersion,
"androidx.test:runner:" + runnerVersion,
"androidx.test.uiautomator:uiautomator:" + uiAutomatorVersion,
"androidx.viewpager:viewpager:1.0.0",
maven.artifact(
"com.google.inject",
"guice",
"4.0",
neverlink = True,
),
"junit:junit:4.12",
"javax.inject:javax.inject:1",
"org.hamcrest:java-hamcrest:2.0.0.0",
maven.artifact(
"org.robolectric",
"robolectric",
"4.3-beta-1",
neverlink = True,
exclusions = ["com.google.guava:guava"],
),
"com.google.guava:guava:26.0-android",
"com.google.truth:truth:0.42",
"com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0",
],
jetify = True,
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
],
version_conflict_policy = "pinned",
)
http_archive(
name = "bazel_toolchains",
sha256 = "4d348abfaddbcee0c077fc51bb1177065c3663191588ab3d958f027cbfe1818b",
strip_prefix = "bazel-toolchains-2.1.0",
urls = [
"https://github.com/bazelbuild/bazel-toolchains/releases/download/2.1.0/bazel-toolchains-2.1.0.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/2.1.0.tar.gz",
],
)
load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig")
rbe_autoconfig(name = "rbe_default")
================================================
FILE: bazelci/buildkite-pipeline.yml
================================================
# https://github.com/googlesamples/android-testing#experimental-bazel-support
---
platforms:
ubuntu1804:
build_targets:
- "//..."
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_23_x86" # BazelCI does not have Android Emulator
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_23_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_22_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_21_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_19_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_23_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_22_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_21_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_19_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_23_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_22_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_21_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_19_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_23_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_22_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_21_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_19_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_19_x86"
test_flags:
- "--config=remote_android"
- "--flaky_test_attempts=3"
test_targets:
- "//..."
- "-//ui/espresso/AccessibilitySample/..."
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_23_x86" # BazelCI does not have Android Emulator
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/uiautomator/BasicSample:BasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_23_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_22_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_21_x86"
- "-//ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest_19_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_23_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_22_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_21_x86"
- "-//ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest_19_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_23_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_22_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_21_x86"
- "-//ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest_19_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_23_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_22_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_21_x86"
- "-//ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest_19_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_23_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_22_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_21_x86"
- "-//ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest_19_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/BasicSample:BasicSampleInstrumentationTest_19_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_23_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_22_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_21_x86"
- "-//ui/espresso/AccessibilitySample:BasicSampleInstrumentationTest_19_x86"
macos:
# Testing does not work for macos and windows yet
build_targets: # Results of `bazel query 'kind(android_binary, //...)'
- "//ui/uiautomator/BasicSample:BasicSampleTest"
- "//ui/uiautomator/BasicSample:BasicSample"
- "//ui/espresso/RecyclerViewSample:RecyclerViewSampleTest"
- "//ui/espresso/RecyclerViewSample:RecyclerViewSample"
- "//ui/espresso/MultiWindowSample:MultiWindowSampleTest"
- "//ui/espresso/MultiWindowSample:MultiWindowSample"
- "//ui/espresso/IntentsBasicSample:IntentsBasicSampleTest"
- "//ui/espresso/IntentsBasicSample:IntentsBasicSample"
- "//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleTest"
- "//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSample"
- "//ui/espresso/IdlingResourceSample:IdlingResourceSampleTest"
- "//ui/espresso/IdlingResourceSample:IdlingResourceSample"
- "//ui/espresso/DataAdapterSample:DataAdapterSampleTest"
- "//ui/espresso/DataAdapterSample:DataAdapterSample"
- "//ui/espresso/CustomMatcherSample:CustomMatcherSampleTest"
- "//ui/espresso/CustomMatcherSample:CustomMatcherSample"
- "//ui/espresso/BasicSample:BasicSampleTest"
- "//ui/espresso/BasicSample:BasicSample"
- "//ui/espresso/AccessibilitySample:BasicSampleTest"
- "//ui/espresso/AccessibilitySample:BasicSample"
windows:
build_targets: # Results of `bazel query 'kind(android_binary, //...)'
- "//ui/uiautomator/BasicSample:BasicSampleTest"
- "//ui/uiautomator/BasicSample:BasicSample"
- "//ui/espresso/RecyclerViewSample:RecyclerViewSampleTest"
- "//ui/espresso/RecyclerViewSample:RecyclerViewSample"
- "//ui/espresso/MultiWindowSample:MultiWindowSampleTest"
- "//ui/espresso/MultiWindowSample:MultiWindowSample"
- "//ui/espresso/IntentsBasicSample:IntentsBasicSampleTest"
- "//ui/espresso/IntentsBasicSample:IntentsBasicSample"
- "//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleTest"
- "//ui/espresso/IntentsAdvancedSample:IntentsAdvancedSample"
- "//ui/espresso/IdlingResourceSample:IdlingResourceSampleTest"
- "//ui/espresso/IdlingResourceSample:IdlingResourceSample"
- "//ui/espresso/DataAdapterSample:DataAdapterSampleTest"
- "//ui/espresso/DataAdapterSample:DataAdapterSample"
- "//ui/espresso/CustomMatcherSample:CustomMatcherSampleTest"
- "//ui/espresso/CustomMatcherSample:CustomMatcherSample"
- "//ui/espresso/BasicSample:BasicSampleTest"
- "//ui/espresso/BasicSample:BasicSample"
- "//ui/espresso/AccessibilitySample:BasicSampleTest"
- "//ui/espresso/AccessibilitySample:BasicSample"
================================================
FILE: common_defs.bzl
================================================
# Common constants for bazel builds
# keep naming convention consistent with gradle variables, so version numbers can be auto-incremented
# via a script
androidxLibVersion = "1.0.0"
coreVersion = "1.2.0-beta01"
extJUnitVersion = "1.1.1-beta01"
extTruthVersion = "1.2.0-beta01"
runnerVersion = "1.2.0-beta01"
rulesVersion = "1.2.0-beta01"
espressoVersion = "3.2.0-beta01"
uiAutomatorVersion = "2.2.0"
minSdkVersion = "14"
targetSdkVersion = "28"
================================================
FILE: integration/ServiceTestRuleSample/.gitignore
================================================
.gradle
local.properties
.idea
.DS_Store
build
*.iml
================================================
FILE: integration/ServiceTestRuleSample/README.md
================================================
# Basic sample for ServiceTestRule
This rule provides a simplified mechanism to start and shutdown your service before and after
the duration of your test. It also guarantees that the service is successfully connected when starting
(or binding to) a service. The service can be started (or bound) using one of the helper methods.
It will automatically be stopped (or unbound) after the test completes and any methods annotated with @After are finished.
Note: This rule doesn't support `IntentService` because it's automatically destroyed when
`IntentService#onHandleIntent(android.content.Intent)`
finishes all outstanding commands. So there is no guarantee to establish a successful connection in a timely manner.
This project uses the Gradle build system. You don't need an IDE to build and execute it but Android Studio is recommended.
1. Download the project code, preferably using `git clone`.
1. Open the Android SDK Manager (*Tools* Menu | *Android*) and make sure you have installed the *Support Repository* under *Extras*.
1. In Android Studio, select *File* | *Open...* and point to the `./build.gradle` file.
1. Check out the relevant code:
* The application under test is located in `src/main/java`
* Tests are in `src/androidTest/java`
1. Connect a device or start an emulator
1. Run the newly created configuration
The application will be started on the device/emulator and a series of actions will be performed automatically.
If you are using Android Studio, the *Run* window will show the test results.
================================================
FILE: integration/ServiceTestRuleSample/app/build.gradle
================================================
apply plugin: "com.android.application"
android {
compileSdk 34
defaultConfig {
applicationId "com.example.android.testing.integrationtesting.ServiceTestRuleSample"
minSdkVersion 21
targetSdkVersion 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
productFlavors {
}
testOptions {
managedDevices {
devices {
// run with ../gradlew nexusOneApi30DebugAndroidTest
nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
// A lower resolution device is used here for better emulator performance
device = "Nexus One"
apiLevel = 30
// Also use the AOSP ATD image for better emulator performance
systemImageSource = "aosp-atd"
}
}
}
}
namespace "com.example.android.testing.ServiceTestRuleSample"
lint {
abortOnError false
}
}
dependencies {
// Testing-only dependencies
androidTestImplementation "androidx.test:core:" + rootProject.coreVersion;
androidTestImplementation "androidx.test.ext:junit:" + rootProject.extJUnitVersion;
androidTestImplementation "androidx.test:runner:" + rootProject.runnerVersion;
androidTestImplementation "androidx.test:rules:" + rootProject.rulesVersion;
}
================================================
FILE: integration/ServiceTestRuleSample/app/src/androidTest/java/com/example/android/testing/ServiceTestRuleSample/LocalServiceTest.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.ServiceTestRuleSample;
import android.content.Intent;
import android.os.IBinder;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ServiceTestRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeoutException;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static org.hamcrest.CoreMatchers.any;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
/**
* JUnit4 test that uses a {@link ServiceTestRule} to interact with a bound service.
* <p>
* {@link ServiceTestRule} is a JUnit rule that provides a
* simplified mechanism to start and shutdown your service before
* and after the duration of your test. It also guarantees that the service is successfully
* connected when starting (or binding to) a service. The service can be started
* (or bound) using one of the helper methods. It will automatically be stopped (or unbound) after
* the test completes and any methods annotated with
* <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"><code>After</code></a> are
* finished.
* <p>
* Note: This rule doesn't support {@link android.app.IntentService} because it's automatically
* destroyed when {@link android.app.IntentService#onHandleIntent(android.content.Intent)} finishes
* all outstanding commands. So there is no guarantee to establish a successful connection
* in a timely manner.
*/
@MediumTest
@RunWith(AndroidJUnit4.class)
public class LocalServiceTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
@Test
public void testWithBoundService() throws TimeoutException {
// Create the service Intent.
Intent serviceIntent =
new Intent(getApplicationContext(), LocalService.class);
// Data can be passed to the service via the Intent.
serviceIntent.putExtra(LocalService.SEED_KEY, 42L);
// Bind the service and grab a reference to the binder.
IBinder binder = mServiceRule.bindService(serviceIntent);
// Get the reference to the service, or you can call public methods on the binder directly.
LocalService service = ((LocalService.LocalBinder) binder).getService();
// Verify that the service is working correctly.
assertThat(service.getRandomInt(), is(any(Integer.class)));
}
}
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<service android:name=".LocalService"/>
</application>
</manifest>
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/java/com/example/android/testing/ServiceTestRuleSample/LocalService.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.ServiceTestRuleSample;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import java.util.Random;
/**
* {@link Service} that generates random numbers.
* <p>
* A seed for the random number generator can be set via the {@link Intent} passed to
* {@link #onBind(Intent)}.
*/
public class LocalService extends Service {
// Used as a key for the Intent.
public static final String SEED_KEY = "SEED_KEY";
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private Random mGenerator = new Random();
private long mSeed;
@Override
public IBinder onBind(Intent intent) {
// If the Intent comes with a seed for the number generator, apply it.
if (intent.hasExtra(SEED_KEY)) {
mSeed = intent.getLongExtra(SEED_KEY, 0);
mGenerator.setSeed(mSeed);
}
return mBinder;
}
public class LocalBinder extends Binder {
public LocalService getService() {
// Return this instance of LocalService so clients can call public methods.
return LocalService.this;
}
}
/**
* Returns a random integer in [0, 100).
*/
public int getRandomInt() {
return mGenerator.nextInt(100);
}
}
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">ServiceTestRule Basic Sample</string>
</resources>
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Light"/>
</resources>
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/res/values-v13/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light"/>
</resources>
================================================
FILE: integration/ServiceTestRuleSample/app/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Material.Light"/>
</resources>
================================================
FILE: integration/ServiceTestRuleSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.agpVersion = "8.5.0"
repositories {
// Insert local test repo here
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$agpVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// Insert local test repo here
google()
mavenCentral()
}
}
ext {
coreVersion = "1.6.1"
extJUnitVersion = "1.2.1"
runnerVersion = "1.6.1"
rulesVersion = "1.6.1"
}
================================================
FILE: integration/ServiceTestRuleSample/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: integration/ServiceTestRuleSample/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.useAndroidX=true
================================================
FILE: integration/ServiceTestRuleSample/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: integration/ServiceTestRuleSample/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: integration/ServiceTestRuleSample/settings.gradle
================================================
include ':app'
================================================
FILE: projects.conf
================================================
integration/ServiceTestRuleSample
runner/AndroidJunitRunnerSample
runner/AndroidTestOrchestratorSample
ui/espresso/AccessibilitySample
ui/espresso/BasicSample
ui/espresso/CustomMatcherSample
ui/espresso/DataAdapterSample
ui/espresso/EspressoDeviceSample
ui/espresso/FragmentScenarioSample
ui/espresso/IdlingResourceSample
ui/espresso/IntentsAdvancedSample
ui/espresso/IntentsBasicSample
ui/espresso/MultiWindowSample
ui/espresso/MultiProcessSample
ui/espresso/RecyclerViewSample
ui/espresso/ScreenshotSample
ui/espresso/WebBasicSample
ui/uiautomator/BasicSample
unit/BasicNativeAndroidTest
================================================
FILE: renovate.json
================================================
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>android/.github:renovate-config"
]
}
================================================
FILE: runner/AndroidJunitRunnerSample/.gitignore
================================================
.gradle
/local.properties
.idea
*.iml
.DS_Store
build
================================================
FILE: runner/AndroidJunitRunnerSample/README.md
================================================
# AndroidJUnitRunner sample
The new android test runner brings Junit4 support to android testing. This samples gives a quick
overview of some of the new features like test annotations, parameterized tests and test suite
creation.
1. CalculatorTest.java contains JUnit4 style unit tests for the calculator logic.
1. CalculatorAddParameterizedTest.java contains JUnit4 style tests and uses the @Parameters annotation
to parameterize a single test with different values.
1. CalculatorInstrumentationTest.java uses JUnit4 style tests to test the Ui of the CalculatorActivity
1. OperationHintInstrumentationTest.java uses JUnit3 style tests to test the Ui of the CalculatorActivity
This project uses the Gradle build system. You don't need an IDE to build and execute it but Android Studio is recommended.
1. Download the project code, preferably using `git clone`.
1. Open the Android SDK Manager (*Tools* Menu | *Android*) and make sure you have installed the *Android Support Repository* under *Extras*.
1. In Android Studio, select *File* | *Open...* and point to the top-level `./build.gradle` file.
1. Check out the relevant code:
* The application under test is located in `src/main/java`
* Tests are in `src/androidTest/java`
1. Create the test configuration with a custom runner: `androidx.test.runner.AndroidJUnitRunner`
* Open *Run* menu | *Edit Configurations*
* Add a new *Android Tests* configuration
* Choose a module
* Choose which tests to run. Click on Test: class and select one of the TestSuites
(AndroidTestSuite, UnitTestSuite, InstrumentationTestSuite)
* Add a *Specific instrumentation runner*: `androidx.test.runner.AndroidJUnitRunner`
1. Connect a device or start an emulator
* Turn animations off.
(On your device, under Settings->Developer options disable the following 3 settings: "Window animation scale", "Transition animation scale" and "Animator duration scale")
1. Run the newly created configuration
The application will be started on the device/emulator and a series of actions will be performed automatically.
If you are using Android Studio, the *Run* window will show the test results.
================================================
FILE: runner/AndroidJunitRunnerSample/app/build.gradle
================================================
apply plugin: "com.android.application"
android {
compileSdk 34
defaultConfig {
applicationId "com.example.android.testing.androidjunitrunnersample"
minSdkVersion 21
targetSdkVersion 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
productFlavors {
}
testOptions {
managedDevices {
devices {
// run with ../gradlew nexusOneApi30DebugAndroidTest
nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
// A lower resolution device is used here for better emulator performance
device = "Nexus One"
apiLevel = 30
// Also use the AOSP ATD image for better emulator performance
systemImageSource = "aosp-atd"
}
}
}
}
useLibrary "android.test.runner"
useLibrary "android.test.base"
useLibrary "android.test.mock"
namespace "com.example.android.testing.androidjunitrunnersample"
}
dependencies {
// App's dependencies, including test
implementation "androidx.annotation:annotation:" + rootProject.androidxAnnotationVersion;
implementation "com.google.guava:guava:" + rootProject.guavaVersion
// Testing-only dependencies
androidTestImplementation "androidx.test:core:" + rootProject.coreVersion;
androidTestImplementation "androidx.test.ext:junit:" + rootProject.extJUnitVersion;
androidTestImplementation "androidx.test:runner:" + rootProject.runnerVersion;
androidTestImplementation "androidx.test.espresso:espresso-core:" + rootProject.espressoVersion;
// https://truth.dev/
androidTestImplementation "com.google.truth:truth:" + rootProject.truthVersion;
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorAddParameterizedTest.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.runners.Parameterized.Parameters;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
/**
* JUnit4 tests for the calculator's add logic.
*
* <p> This test uses Junit4s Parameterized tests features which uses annotations to pass
* parameters into a unit test. The way this works is that you have to use the {@link Parameterized}
* runner to run your tests.
* </p>
*/
@RunWith(Parameterized.class)
@SmallTest
public class CalculatorAddParameterizedTest {
/**
* @return {@link Iterable} that contains the values that should be passed to the constructor.
* In this example we are going to use three parameters: operand one, operand two and the
* expected result.
*/
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0, 0, 0},
{0, -1, -1},
{2, 2, 4},
{8, 8, 16},
{16, 16, 32},
{32, 0, 32},
{64, 64, 128}});
}
private final double mOperandOne;
private final double mOperandTwo;
private final double mExpectedResult;
private Calculator mCalculator;
/**
* Constructor that takes in the values specified in
* {@link CalculatorAddParameterizedTest#data()}. The values need to be saved to fields in order
* to reuse them in your tests.
*/
public CalculatorAddParameterizedTest(double operandOne, double operandTwo,
double expectedResult) {
mOperandOne = operandOne;
mOperandTwo = operandTwo;
mExpectedResult = expectedResult;
}
@Before
public void setUp() {
mCalculator = new Calculator();
}
@Test
public void testAdd_TwoNumbers() {
double resultAdd = mCalculator.add(mOperandOne, mOperandTwo);
assertThat(resultAdd).isEqualTo(mExpectedResult);
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorInstrumentationTest.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import junit.framework.TestSuite;
import org.junit.Before;
import org.junit.Test;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.runner.RunWith;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnitRunner;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
/**
* JUnit4 Ui Tests for {@link CalculatorActivity} using the {@link AndroidJUnitRunner}.
* This class uses the JUnit4 syntax for tests.
* <p>
* With the new AndroidJUnit runner you can run both JUnit3 and JUnit4 tests in a single test
* suite. The {@link AndroidRunnerBuilder} which extends JUnit's
* {@link AllDefaultPossibilitiesBuilder} will create a single {@link
* TestSuite} from all tests and run them.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CalculatorInstrumentationTest {
/**
* Use {@link ActivityScenario} to create and launch of the activity.
*/
@Before
public void launchActivity() {
ActivityScenario.launch(CalculatorActivity.class);
}
@Test
public void noOperandShowsComputationError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
onView(withId(R.id.operation_add_btn)).perform(click());
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
@Test
public void typeOperandsAndPerformAddOperation() {
performOperation(R.id.operation_add_btn, "16.0", "16.0", "32.0");
}
@Test
public void typeOperandsAndPerformSubOperation() {
performOperation(R.id.operation_sub_btn, "32.0", "16.0", "16.0");
}
@Test
public void typeOperandsAndPerformDivOperation() {
performOperation(R.id.operation_div_btn, "128.0", "16.0", "8.0");
}
@Test
public void divZeroForOperandTwoShowsError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
performOperation(R.id.operation_div_btn, "128.0", "0.0", expectedResult);
}
@Test
public void typeOperandsAndPerformMulOperation() {
performOperation(R.id.operation_mul_btn, "16.0", "16.0", "256.0");
}
private void performOperation(int btnOperationResId, String operandOne,
String operandTwo, String expectedResult) {
// Type the two operands in the EditText fields
onView(withId(R.id.operand_one_edit_text)).perform(typeText(operandOne),
closeSoftKeyboard());
onView(withId(R.id.operand_two_edit_text)).perform(typeText(operandTwo),
closeSoftKeyboard());
// Click on a given operation button
onView(withId(btnOperationResId)).perform(click());
// Check the expected test is displayed in the Ui
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorTest.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* JUnit4 unit tests for the calculator logic.
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
public class CalculatorTest {
private Calculator mCalculator;
@Before
public void setUp() {
mCalculator = new Calculator();
}
@Test
public void addTwoNumbers() {
double resultAdd = mCalculator.add(1d, 1d);
assertThat(resultAdd).isEqualTo(2d);
}
@Test
public void subTwoNumbers() {
double resultSub = mCalculator.sub(1d, 1d);
assertThat(resultSub).isEqualTo(0d);
}
@Test
public void subWorksWithNegativeResult() {
double resultSub = mCalculator.sub(1d, 17d);
assertThat(resultSub).isEqualTo(-16d);
}
@Test
public void divTwoNumbers() {
double resultDiv = mCalculator.div(32d,2d);
assertThat(resultDiv).isEqualTo(16d);
}
@Test(expected = IllegalArgumentException.class)
public void divDivideByZeroThrows() {
mCalculator.div(32d,0d);
}
@Test
public void mulTwoNumbers() {
double resultMul = mCalculator.mul(32d, 2d);
assertThat(resultMul).isEqualTo(64d);
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/HintMatcher.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import androidx.test.espresso.matcher.BoundedMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import android.view.View;
import android.widget.EditText;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.hamcrest.Matchers.is;
/**
* A custom matcher that checks the hint property of an {@link android.widget.EditText}. It
* accepts either a {@link String} or a {@link org.hamcrest.Matcher}.
*/
public class HintMatcher {
static Matcher<View> withHint(final String substring) {
return withHint(is(substring));
}
static Matcher<View> withHint(final Matcher<String> stringMatcher) {
checkNotNull(stringMatcher);
return new BoundedMatcher<View, EditText>(EditText.class) {
@Override
public boolean matchesSafely(EditText view) {
final CharSequence hint = view.getHint();
return hint != null && stringMatcher.matches(hint.toString());
}
@Override
public void describeTo(Description description) {
description.appendText("with hint: ");
stringMatcher.describeTo(description);
}
};
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintInstrumentationTest.java
================================================
/*
* Copyright 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import junit.framework.TestSuite;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnitRunner;
import android.test.ActivityInstrumentationTestCase2;
import static com.example.android.testing.androidjunitrunnersample.HintMatcher.withHint;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
/**
* JUnit3 Ui Tests for {@link CalculatorActivity} using the {@link AndroidJUnitRunner}. This class
* uses the Junit3 syntax for tests.
*
* <p> With the new AndroidJUnit runner you can run both JUnit3 and JUnit4 tests in a single test
* test suite. The {@link AndroidRunnerBuilder} which extends JUnit's {@link
* AllDefaultPossibilitiesBuilder} will create a single {@link TestSuite} from all tests and run
* them. </p>
*/
@LargeTest
public class OperationHintInstrumentationTest
extends ActivityInstrumentationTestCase2<CalculatorActivity> {
private CalculatorActivity mActivity;
public OperationHintInstrumentationTest() {
super(CalculatorActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
// Espresso does not start the Activity for you we need to do this manually here.
mActivity = getActivity();
}
public void testPreconditions() {
assertThat(mActivity, notNullValue());
}
public void testEditText_OperandOneHint() {
String operandOneHint = mActivity.getString(R.string.type_operand_one_hint);
onView(withId(R.id.operand_one_edit_text)).check(matches(withHint(operandOneHint)));
}
public void testEditText_OperandTwoHint() {
String operandTwoHint = mActivity.getString(R.string.type_operant_two_hint);
onView(withId(R.id.operand_two_edit_text)).check(matches(withHint(operandTwoHint)));
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintLegacyInstrumentationTest.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import junit.framework.TestSuite;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnitRunner;
import android.test.ActivityInstrumentationTestCase2;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static com.example.android.testing.androidjunitrunnersample.HintMatcher.withHint;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
/**
* JUnit3 Ui Tests for {@link CalculatorActivity} using the {@link AndroidJUnitRunner}. This class
* uses the Junit3 syntax for tests and extends {@link ActivityInstrumentationTestCase2}.
* <p>
* With the new AndroidJUnit runner you can run both JUnit3 and JUnit4 tests in a single test
* test suite. The {@link AndroidRunnerBuilder} which extends JUnit's {@link
* AllDefaultPossibilitiesBuilder} will create a single {@link TestSuite} from all tests and run
* them.
* <p>
* ActivityInstrumentationTestCase2 will be deprecated soon. Please use {@link ActivityTestRule}
* when writing new tests. For an example on how to use {@link ActivityTestRule} please see
* {@link CalculatorInstrumentationTest}.
*/
@LargeTest
public class OperationHintLegacyInstrumentationTest
extends ActivityInstrumentationTestCase2<CalculatorActivity> {
private CalculatorActivity mActivity;
public OperationHintLegacyInstrumentationTest() {
super(CalculatorActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
// Espresso does not start the Activity for you we need to do this manually here.
mActivity = getActivity();
}
public void testPreconditions() {
assertThat(mActivity, notNullValue());
}
public void testEditText_OperandOneHint() {
String operandOneHint = mActivity.getString(R.string.type_operand_one_hint);
onView(withId(R.id.operand_one_edit_text)).check(matches(withHint(operandOneHint)));
}
public void testEditText_OperandTwoHint() {
String operandTwoHint = mActivity.getString(R.string.type_operant_two_hint);
onView(withId(R.id.operand_two_edit_text)).check(matches(withHint(operandTwoHint)));
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/AndroidTestSuite.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample.suite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* Test suite that runs all tests, unit + instrumentation tests.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({UnitTestSuite.class, InstrumentationTestSuite.class})
public class AndroidTestSuite {}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/InstrumentationTestSuite.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample.suite;
import com.example.android.testing.androidjunitrunnersample.CalculatorInstrumentationTest;
import com.example.android.testing.androidjunitrunnersample.OperationHintLegacyInstrumentationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* Runs all Junit3 and Junit4 Instrumentation tests.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorInstrumentationTest.class, OperationHintLegacyInstrumentationTest.class})
public class InstrumentationTestSuite {}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/UnitTestSuite.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample.suite;
import com.example.android.testing.androidjunitrunnersample.CalculatorAddParameterizedTest;
import com.example.android.testing.androidjunitrunnersample.CalculatorTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* Runs all unit tests.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorTest.class, CalculatorAddParameterizedTest.class})
public class UnitTestSuite {}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".CalculatorActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/Calculator.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A simple calculator with a basic set of operations.
*/
public class Calculator {
public enum Operator {ADD, SUB, DIV, MUL}
/**
* Addition operation
*/
public double add(double firstOperand, double secondOperand) {
return firstOperand + secondOperand;
}
/**
* Substract operation
*/
public double sub(double firstOperand, double secondOperand) {
return firstOperand - secondOperand;
}
/**
* Divide operation
*/
public double div(double firstOperand, double secondOperand) {
checkArgument(secondOperand != 0, "secondOperand must be != 0, you cannot divide by zero");
return firstOperand / secondOperand;
}
/**
* Multiply operation
*/
public double mul(double firstOperand, double secondOperand) {
return firstOperand * secondOperand;
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/CalculatorActivity.java
================================================
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidjunitrunnersample;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* {@link android.app.Activity} which contains a simple calculator. Numbers can be entered in the
* two {@link EditText} fields and result can be obtained by pressing one of the
* operation {@link Button}s at the bottom.
*/
public class CalculatorActivity extends Activity {
private static final String TAG = "CalculatorActivity";
private Calculator mCalculator;
private EditText mOperandOneEditText;
private EditText mOperandTwoEditText;
private TextView mResultTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
mCalculator = new Calculator();
mResultTextView = (TextView) findViewById(R.id.operation_result_text_view);
mOperandOneEditText = (EditText) findViewById(R.id.operand_one_edit_text);
mOperandTwoEditText = (EditText) findViewById(R.id.operand_two_edit_text);
}
/**
* OnClick method that is called when the add {@link Button} is pressed.
*/
public void onAdd(View view) {
compute(Calculator.Operator.ADD);
}
/**
* OnClick method that is called when the substract {@link Button} is pressed.
*/
public void onSub(View view) {
compute(Calculator.Operator.SUB);
}
/**
* OnClick method that is called when the divide {@link Button} is pressed.
*/
public void onDiv(View view) {
try {
compute(Calculator.Operator.DIV);
} catch (IllegalArgumentException iae) {
Log.e(TAG, "IllegalArgumentException", iae);
mResultTextView.setText(getString(R.string.computationError));
}
}
/**
* OnClick method that is called when the multiply {@link Button} is pressed.
*/
public void onMul(View view) {
compute(Calculator.Operator.MUL);
}
private void compute(Calculator.Operator operator) {
double operandOne;
double operandTwo;
try {
operandOne = getOperand(mOperandOneEditText);
operandTwo = getOperand(mOperandTwoEditText);
} catch (NumberFormatException nfe) {
Log.e(TAG, "NumberFormatException", nfe);
mResultTextView.setText(getString(R.string.computationError));
return;
}
String result;
switch (operator) {
case ADD:
result = String.valueOf(mCalculator.add(operandOne, operandTwo));
break;
case SUB:
result = String.valueOf(mCalculator.sub(operandOne, operandTwo));
break;
case DIV:
result = String.valueOf(mCalculator.div(operandOne, operandTwo));
break;
case MUL:
result = String.valueOf(mCalculator.mul(operandOne, operandTwo));
break;
default:
result = getString(R.string.computationError);
break;
}
mResultTextView.setText(result);
}
/**
* @return the operand value which was entered in an {@link EditText} as a double
*/
private static Double getOperand(EditText operandEditText) {
String operandText = getOperandText(operandEditText);
return Double.valueOf(operandText);
}
/**
* @return the operand text which was entered in an {@link EditText}.
*/
private static String getOperandText(EditText operandEditText) {
String operandText = operandEditText.getText().toString();
if (TextUtils.isEmpty(operandText)) {
throw new NumberFormatException("operand cannot be empty!");
}
return operandText;
}
}
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/layout/activity_calculator.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".CalculatorActivity">
<EditText android:id="@+id/operand_one_edit_text"
android:hint="@string/type_operand_one_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<EditText android:id="@+id/operand_two_edit_text"
android:hint="@string/type_operant_two_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/operation_add_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add_operation_text"
android:onClick="onAdd"/>
<Button android:id="@+id/operation_sub_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sub_operation_text"
android:layout_toRightOf="@id/operation_add_btn"
android:layout_toEndOf="@id/operation_add_btn"
android:onClick="onSub"/>
<Button android:id="@+id/operation_div_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/div_operation_text"
android:layout_below="@id/operation_add_btn"
android:onClick="onDiv"/>
<Button android:id="@+id/operation_mul_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mul_operation_text"
android:layout_below="@id/operation_add_btn"
android:layout_toRightOf="@id/operation_add_btn"
android:layout_toEndOf="@id/operation_add_btn"
android:onClick="onMul"/>
</RelativeLayout>
<TextView android:id="@+id/operation_result_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"/>
</LinearLayout>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">AndroidJunitRunnerSample</string>
<string name="type_operand_one_hint">Type Operand 1</string>
<string name="type_operant_two_hint">Type Operand 2</string>
<string name="add_operation_text">Add</string>
<string name="sub_operation_text">Sub</string>
<string name="div_operation_text">Div</string>
<string name="mul_operation_text">Mul</string>
<string name="computationError">Error</string>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Black"/>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values-v14/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Holo"/>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:ThemeOverlay.Material.Dark"/>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: runner/AndroidJunitRunnerSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.agpVersion = "8.5.0"
repositories {
// Insert local test repo here
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$agpVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// Insert local test repo here
google()
mavenCentral()
}
}
ext {
buildToolsVersion = "32.0.0"
androidxAnnotationVersion = "1.5.0"
guavaVersion = "31.1-android"
coreVersion = "1.6.1"
extJUnitVersion = "1.2.1"
runnerVersion = "1.6.1"
rulesVersion = "1.6.1"
espressoVersion = "3.6.1"
truthVersion = "1.1.3"
}
================================================
FILE: runner/AndroidJunitRunnerSample/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: runner/AndroidJunitRunnerSample/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.useAndroidX=true
android.useAndroidX=true
================================================
FILE: runner/AndroidJunitRunnerSample/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: runner/AndroidJunitRunnerSample/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: runner/AndroidJunitRunnerSample/settings.gradle
================================================
include ':app'
================================================
FILE: runner/AndroidTestOrchestratorSample/.gitignore
================================================
.gradle
/local.properties
.idea
*.iml
.DS_Store
build
================================================
FILE: runner/AndroidTestOrchestratorSample/README.md
================================================
# AndroidTestOrchestrator sample
The Android Test Orchestrator allows you to run each of your app's tests in isolation, enabling greater relability.
See https://developer.android.com/training/testing/junit-runner#using-android-test-orchestrator for more background.
This sample is a subset of the AndroidJUnitRunner sample, but it
illustrates how to enable the Android Test Orchestrator in the app/build.gradle file.
This project uses the Gradle build system. You don't need an IDE to build and execute it but Android Studio is recommended.
1. Download the project code, preferably using `git clone`.
1. Open the Android SDK Manager (*Tools* Menu | *Android*).
1. In Android Studio, select *File* | *Open...* and point to the top-level `./build.gradle` file.
1. Check out the relevant code:
* The application under test is located in `src/main/java`
* Tests are in `src/androidTest/java`
1. Create the test configuration
* Open *Run* menu | *Edit Configurations*
* Add a new *Android Tests* configuration
* Choose a module
1. Connect a device or start an emulator
* Turn animations off.
(On your device, under Settings->Developer options disable the following 3 settings: "Window animation scale", "Transition animation scale" and "Animator duration scale")
1. Run the newly created configuration
The application will be started on the device/emulator and a series of actions will be performed automatically.
If you are using Android Studio, the *Run* window will show the test results.
================================================
FILE: runner/AndroidTestOrchestratorSample/app/build.gradle
================================================
apply plugin: "com.android.application"
android {
compileSdk 34
defaultConfig {
applicationId "com.example.android.testing.androidtestorchestratorsample"
minSdkVersion 21
targetSdkVersion 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: "true"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
productFlavors {
}
testOptions {
execution "ANDROIDX_TEST_ORCHESTRATOR"
managedDevices {
devices {
// run with ../gradlew nexusOneApi30DebugAndroidTest
nexusOneApi30(com.android.build.api.dsl.ManagedVirtualDevice) {
// A lower resolution device is used here for better emulator performance
device = "Nexus One"
apiLevel = 30
// Also use the AOSP ATD image for better emulator performance
systemImageSource = "aosp-atd"
}
}
}
}
namespace "com.example.android.testing.androidtestorchestratorsample"
}
dependencies {
// App's dependencies, including test
implementation "androidx.annotation:annotation:" + rootProject.androidxAnnotationVersion;
implementation "com.google.guava:guava:" + rootProject.guavaVersion
// Testing-only dependencies
androidTestImplementation "androidx.test:core:" + rootProject.coreVersion;
androidTestImplementation "androidx.test.ext:junit:" + rootProject.extJUnitVersion;
androidTestImplementation "androidx.test:runner:" + rootProject.runnerVersion;
androidTestImplementation "androidx.test:monitor:" + rootProject.monitorVersion;
androidTestImplementation "androidx.test.espresso:espresso-core:" + rootProject.espressoVersion;
androidTestImplementation "com.google.truth:truth:" + rootProject.truthVersion;
androidTestUtil "androidx.test:orchestrator:" + rootProject.orchestratorVersion;
}
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import static com.google.common.truth.Truth.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import androidx.test.filters.SmallTest;
import java.lang.Iterable;
import java.util.Arrays;
import static org.junit.runners.Parameterized.Parameters;
/**
* JUnit4 tests for the calculator's add logic.
*
* <p> This test uses a Junit4s Parameterized tests features which uses annotations to pass
* parameters into a unit test. The way this works is that you have to use the {@link Parameterized}
* runner to run your tests.
* </p>
*/
@RunWith(Parameterized.class)
@SmallTest
public class CalculatorAddParameterizedTest {
/**
* @return {@link Iterable} that contains the values that should be passed to the constructor.
* In this example we are going to use three parameters: operand one, operand two and the
* expected result.
*/
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0, 0, 0},
{0, -1, -1},
{2, 2, 4},
{8, 8, 16},
{16, 16, 32},
{32, 0, 32},
{64, 64, 128}});
}
private final double mOperandOne;
private final double mOperandTwo;
private final double mExpectedResult;
private Calculator mCalculator;
/**
* Constructor that takes in the values specified in
* {@link CalculatorAddParameterizedTest#data()}. The values need to be saved to fields in order
* to reuse them in your tests.
*/
public CalculatorAddParameterizedTest(double operandOne, double operandTwo,
double expectedResult) {
mOperandOne = operandOne;
mOperandTwo = operandTwo;
mExpectedResult = expectedResult;
}
@Before
public void setUp() {
mCalculator = new Calculator();
}
@Test
public void testAdd_TwoNumbers() {
double resultAdd = mCalculator.add(mOperandOne, mOperandTwo);
assertThat(resultAdd).isEqualTo(mExpectedResult);
}
}
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import androidx.test.platform.graphics.HardwareRendererCompat;
import junit.framework.TestSuite;
import org.junit.Before;
import org.junit.Test;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.runner.RunWith;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnitRunner;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
/**
* JUnit4 Ui Tests for {@link CalculatorActivity} using the {@link AndroidJUnitRunner} with the
* Android Test Orchestrator.
* This class uses the JUnit4 syntax for tests.
* <p>
* With the new AndroidJUnit runner you can run both JUnit3 and JUnit4 tests in a single test
* suite. The {@link AndroidRunnerBuilder} which extends JUnit's
* {@link AllDefaultPossibilitiesBuilder} will create a single {@link
* TestSuite} from all tests and run them.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CalculatorInstrumentationTest {
/**
* Use {@link ActivityScenario} to create and launch of the activity.
*/
@Before
public void launchActivity() {
ActivityScenario.launch(CalculatorActivity.class);
}
@Test
public void noOperandShowsComputationError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
onView(withId(R.id.operation_add_btn)).perform(click());
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
@Test
public void typeOperandsAndPerformAddOperation() {
performOperation(R.id.operation_add_btn, "16.0", "16.0", "32.0");
}
@Test
public void typeOperandsAndPerformSubOperation() {
performOperation(R.id.operation_sub_btn, "32.0", "16.0", "16.0");
}
@Test
public void typeOperandsAndPerformDivOperation() {
performOperation(R.id.operation_div_btn, "128.0", "16.0", "8.0");
}
@Test
public void divZeroForOperandTwoShowsError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
performOperation(R.id.operation_div_btn, "128.0", "0.0", expectedResult);
}
@Test
public void typeOperandsAndPerformMulOperation() {
performOperation(R.id.operation_mul_btn, "16.0", "16.0", "256.0");
}
private void performOperation(int btnOperationResId, String operandOne,
String operandTwo, String expectedResult) {
// Type the two operands in the EditText fields
onView(withId(R.id.operand_one_edit_text)).perform(typeText(operandOne),
closeSoftKeyboard());
onView(withId(R.id.operand_two_edit_text)).perform(typeText(operandTwo),
closeSoftKeyboard());
// Click on a given operation button
onView(withId(btnOperationResId)).perform(click());
// Check the expected test is displayed in the Ui
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
}
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".CalculatorActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A simple calculator with a basic set of operations.
*/
public class Calculator {
public enum Operator {ADD, SUB, DIV, MUL}
/**
* Addition operation
*/
public double add(double firstOperand, double secondOperand) {
return firstOperand + secondOperand;
}
/**
* Substract operation
*/
public double sub(double firstOperand, double secondOperand) {
return firstOperand - secondOperand;
}
/**
* Divide operation
*/
public double div(double firstOperand, double secondOperand) {
checkArgument(secondOperand != 0, "secondOperand must be != 0, you cannot divide by zero");
return firstOperand / secondOperand;
}
/**
* Multiply operation
*/
public double mul(double firstOperand, double secondOperand) {
return firstOperand * secondOperand;
}
}
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* {@link android.app.Activity} which contains a simple calculator. Numbers can be entered in the
* two {@link EditText} fields and result can be obtained by pressing one of the
* operation {@link Button}s at the bottom.
*/
public class CalculatorActivity extends Activity {
private static final String TAG = "CalculatorActivity";
private Calculator mCalculator;
private EditText mOperandOneEditText;
private EditText mOperandTwoEditText;
private TextView mResultTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
mCalculator = new Calculator();
mResultTextView = (TextView) findViewById(R.id.operation_result_text_view);
mOperandOneEditText = (EditText) findViewById(R.id.operand_one_edit_text);
mOperandTwoEditText = (EditText) findViewById(R.id.operand_two_edit_text);
}
/**
* OnClick method that is called when the add {@link Button} is pressed.
*/
public void onAdd(View view) {
compute(Calculator.Operator.ADD);
}
/**
* OnClick method that is called when the substract {@link Button} is pressed.
*/
public void onSub(View view) {
compute(Calculator.Operator.SUB);
}
/**
* OnClick method that is called when the divide {@link Button} is pressed.
*/
public void onDiv(View view) {
try {
compute(Calculator.Operator.DIV);
} catch (IllegalArgumentException iae) {
Log.e(TAG, "IllegalArgumentException", iae);
mResultTextView.setText(getString(R.string.computationError));
}
}
/**
* OnClick method that is called when the multiply {@link Button} is pressed.
*/
public void onMul(View view) {
compute(Calculator.Operator.MUL);
}
private void compute(Calculator.Operator operator) {
double operandOne;
double operandTwo;
try {
operandOne = getOperand(mOperandOneEditText);
operandTwo = getOperand(mOperandTwoEditText);
} catch (NumberFormatException nfe) {
Log.e(TAG, "NumberFormatException", nfe);
mResultTextView.setText(getString(R.string.computationError));
return;
}
String result;
switch (operator) {
case ADD:
result = String.valueOf(mCalculator.add(operandOne, operandTwo));
break;
case SUB:
result = String.valueOf(mCalculator.sub(operandOne, operandTwo));
break;
case DIV:
result = String.valueOf(mCalculator.div(operandOne, operandTwo));
break;
case MUL:
result = String.valueOf(mCalculator.mul(operandOne, operandTwo));
break;
default:
result = getString(R.string.computationError);
break;
}
mResultTextView.setText(result);
}
/**
* @return the operand value which was entered in an {@link EditText} as a double
*/
private static Double getOperand(EditText operandEditText) {
String operandText = getOperandText(operandEditText);
return Double.valueOf(operandText);
}
/**
* @return the operand text which was entered in an {@link EditText}.
*/
private static String getOperandText(EditText operandEditText) {
String operandText = operandEditText.getText().toString();
if (TextUtils.isEmpty(operandText)) {
throw new NumberFormatException("operand cannot be empty!");
}
return operandText;
}
}
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/layout/activity_calculator.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".CalculatorActivity">
<EditText android:id="@+id/operand_one_edit_text"
android:hint="@string/type_operand_one_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<EditText android:id="@+id/operand_two_edit_text"
android:hint="@string/type_operant_two_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/operation_add_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add_operation_text"
android:onClick="onAdd"/>
<Button android:id="@+id/operation_sub_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sub_operation_text"
android:layout_toRightOf="@id/operation_add_btn"
android:layout_toEndOf="@id/operation_add_btn"
android:onClick="onSub"/>
<Button android:id="@+id/operation_div_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/div_operation_text"
android:layout_below="@id/operation_add_btn"
android:onClick="onDiv"/>
<Button android:id="@+id/operation_mul_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mul_operation_text"
android:layout_below="@id/operation_add_btn"
android:layout_toRightOf="@id/operation_add_btn"
android:layout_toEndOf="@id/operation_add_btn"
android:onClick="onMul"/>
</RelativeLayout>
<TextView android:id="@+id/operation_result_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"/>
</LinearLayout>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">AndroidTestOrchestratorSample</string>
<string name="type_operand_one_hint">Type Operand 1</string>
<string name="type_operant_two_hint">Type Operand 2</string>
<string name="add_operation_text">Add</string>
<string name="sub_operation_text">Sub</string>
<string name="div_operation_text">Div</string>
<string name="mul_operation_text">Mul</string>
<string name="computationError">Error</string>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Black"/>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values-v14/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:Theme.Holo"/>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="AppTheme" parent="android:ThemeOverlay.Material.Dark"/>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: runner/AndroidTestOrchestratorSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.agpVersion = "8.5.0"
repositories {
// Insert local test repo here
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$agpVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// Insert local test repo here
google()
mavenCentral()
}
}
ext {
androidxAnnotationVersion = "1.5.0"
guavaVersion = "31.1-android"
coreVersion = "1.6.1"
extJUnitVersion = "1.2.1"
runnerVersion = "1.6.1"
monitorVersion = "1.7.1"
rulesVersion = "1.6.1"
espressoVersion = "3.6.1"
orchestratorVersion = "1.5.0"
truthVersion = "1.1.3"
}
================================================
FILE: runner/AndroidTestOrchestratorSample/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: runner/AndroidTestOrchestratorSample/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.useAndroidX=true
android.useAndroidX=true
================================================
FILE: runner/AndroidTestOrchestratorSample/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: runner/AndroidTestOrchestratorSample/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: runner/AndroidTestOrchestratorSample/settings.gradle
================================================
include ':app'
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/.gitignore
================================================
.gradle
/local.properties
.idea
*.iml
.DS_Store
build
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/README.md
================================================
# AndroidTestOrchestrator with test coverage sample
The Android Test Orchestrator allows you to run each of your app's tests in isolation, enabling greater reliability.
See https://developer.android.com/training/testing/junit-runner#using-android-test-orchestrator for more background.
This sample is a subset of the AndroidJUnitRunner sample, but it
illustrates how to enable Jacoco test coverage report with the Android Test Orchestrator in the app/build.gradle file.
This project uses the Gradle build system. You don't need an IDE to build and execute it but Android Studio is recommended.
1. Download the project code, preferably using `git clone`.
1. Open the Android SDK Manager (*Tools* Menu | *Android*).
1. In Android Studio, select *File* | *Open...* and point to the top-level `./build.gradle` file.
1. Check out the relevant code:
* The application under test is located in `src/main/java`
* Tests are in `src/androidTest/java`
1. Connect a device or start an emulator:
* Turn animations off.
(On your device, under Settings->Developer options disable the following 3 settings: "Window animation scale", "Transition animation scale" and "Animator duration scale")
1. Run the newly created configuration.
The application will be started on the device/emulator and a series of actions will be performed automatically.
If you are using Android Studio, the *Run* window will show the test results.
The test coverage report will be generated in `app/build/reports/coverage/androidTest/debug/index.html`.
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/build.gradle
================================================
apply plugin: "com.android.application"
android {
compileSdk 33
defaultConfig {
applicationId "com.example.android.testing.androidtestorchestratorsample"
minSdkVersion 14
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: "true"
testInstrumentationRunnerArguments useTestStorageService: "true"
}
buildTypes {
debug {
testCoverageEnabled true
}
}
testOptions {
execution "ANDROIDX_TEST_ORCHESTRATOR"
}
namespace "com.example.android.testing.androidtestorchestratorsample"
}
dependencies {
// App's dependencies, including test
implementation "androidx.annotation:annotation:" + rootProject.androidxAnnotationVersion
implementation "com.google.guava:guava:" + rootProject.guavaVersion
// Testing-only dependencies
androidTestImplementation "androidx.test:core:" + rootProject.coreVersion
androidTestImplementation "androidx.test.ext:junit:" + rootProject.extJUnitVersion
androidTestImplementation "androidx.test:runner:" + rootProject.runnerVersion
androidTestImplementation "androidx.test.espresso:espresso-core:" + rootProject.espressoVersion
androidTestImplementation "com.google.truth:truth:" + rootProject.truthVersion;
androidTestUtil "androidx.test:orchestrator:" + rootProject.orchestratorVersion
androidTestUtil "androidx.test.services:test-services:" + rootProject.testServicesVersion
}
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import static com.google.common.truth.Truth.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import androidx.test.filters.SmallTest;
import java.lang.Iterable;
import java.util.Arrays;
import static org.junit.runners.Parameterized.Parameters;
/**
* JUnit4 tests for the calculator's add logic.
*
* <p> This test uses a Junit4s Parameterized tests features which uses annotations to pass
* parameters into a unit test. The way this works is that you have to use the {@link Parameterized}
* runner to run your tests.
* </p>
*/
@RunWith(Parameterized.class)
@SmallTest
public class CalculatorAddParameterizedTest {
/**
* @return {@link Iterable} that contains the values that should be passed to the constructor.
* In this example we are going to use three parameters: operand one, operand two and the
* expected result.
*/
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0, 0, 0},
{0, -1, -1},
{2, 2, 4},
{8, 8, 16},
{16, 16, 32},
{32, 0, 32},
{64, 64, 128}});
}
private final double mOperandOne;
private final double mOperandTwo;
private final double mExpectedResult;
private Calculator mCalculator;
/**
* Constructor that takes in the values specified in
* {@link CalculatorAddParameterizedTest#data()}. The values need to be saved to fields in order
* to reuse them in your tests.
*/
public CalculatorAddParameterizedTest(double operandOne, double operandTwo,
double expectedResult) {
mOperandOne = operandOne;
mOperandTwo = operandTwo;
mExpectedResult = expectedResult;
}
@Before
public void setUp() {
mCalculator = new Calculator();
}
@Test
public void testAdd_TwoNumbers() {
double resultAdd = mCalculator.add(mOperandOne, mOperandTwo);
assertThat(resultAdd).isEqualTo(mExpectedResult);
}
}
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import junit.framework.TestSuite;
import org.junit.Before;
import org.junit.Test;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
import org.junit.runner.RunWith;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnitRunner;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
/**
* JUnit4 Ui Tests for {@link CalculatorActivity} using the {@link AndroidJUnitRunner} with the
* Android Test Orchestrator.
* This class uses the JUnit4 syntax for tests.
* <p>
* With the new AndroidJUnit runner you can run both JUnit3 and JUnit4 tests in a single test
* suite. The {@link AndroidRunnerBuilder} which extends JUnit's
* {@link AllDefaultPossibilitiesBuilder} will create a single {@link
* TestSuite} from all tests and run them.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CalculatorInstrumentationTest {
/**
* Use {@link ActivityScenario} to create and launch of the activity.
*/
@Before
public void launchActivity() {
ActivityScenario.launch(CalculatorActivity.class);
}
@Test
public void noOperandShowsComputationError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
onView(withId(R.id.operation_add_btn)).perform(click());
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
@Test
public void typeOperandsAndPerformAddOperation() {
performOperation(R.id.operation_add_btn, "16.0", "16.0", "32.0");
}
@Test
public void typeOperandsAndPerformSubOperation() {
performOperation(R.id.operation_sub_btn, "32.0", "16.0", "16.0");
}
@Test
public void typeOperandsAndPerformDivOperation() {
performOperation(R.id.operation_div_btn, "128.0", "16.0", "8.0");
}
@Test
public void divZeroForOperandTwoShowsError() {
final String expectedResult = getApplicationContext().getString(R.string.computationError);
performOperation(R.id.operation_div_btn, "128.0", "0.0", expectedResult);
}
@Test
public void typeOperandsAndPerformMulOperation() {
performOperation(R.id.operation_mul_btn, "16.0", "16.0", "256.0");
}
private void performOperation(int btnOperationResId, String operandOne,
String operandTwo, String expectedResult) {
// Type the two operands in the EditText fields
onView(withId(R.id.operand_one_edit_text)).perform(typeText(operandOne),
closeSoftKeyboard());
onView(withId(R.id.operand_two_edit_text)).perform(typeText(operandTwo),
closeSoftKeyboard());
// Click on a given operation button
onView(withId(btnOperationResId)).perform(click());
// Check the expected test is displayed in the Ui
onView(withId(R.id.operation_result_text_view)).check(matches(withText(expectedResult)));
}
}
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".CalculatorActivity"
android:label="@string/app_name"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import static com.google.common.base.Preconditions.checkArgument;
/**
* A simple calculator with a basic set of operations.
*/
public class Calculator {
public enum Operator {ADD, SUB, DIV, MUL}
/**
* Addition operation
*/
public double add(double firstOperand, double secondOperand) {
return firstOperand + secondOperand;
}
/**
* Substract operation
*/
public double sub(double firstOperand, double secondOperand) {
return firstOperand - secondOperand;
}
/**
* Divide operation
*/
public double div(double firstOperand, double secondOperand) {
checkArgument(secondOperand != 0, "secondOperand must be != 0, you cannot divide by zero");
return firstOperand / secondOperand;
}
/**
* Multiply operation
*/
public double mul(double firstOperand, double secondOperand) {
return firstOperand * secondOperand;
}
}
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java
================================================
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.testing.androidtestorchestratorsample;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* {@link android.app.Activity} which contains a simple calculator. Numbers can be entered in the
* two {@link EditText} fields and result can be obtained by pressing one of the
* operation {@link Button}s at the bottom.
*/
public class CalculatorActivity extends Activity {
private static final String TAG = "CalculatorActivity";
private Calculator mCalculator;
private EditText mOperandOneEditText;
private EditText mOperandTwoEditText;
private TextView mResultTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
mCalculator = new Calculator();
mResultTextView = (TextView) findViewById(R.id.operation_result_text_view);
mOperandOneEditText = (EditText) findViewById(R.id.operand_one_edit_text);
mOperandTwoEditText = (EditText) findViewById(R.id.operand_two_edit_text);
}
/**
* OnClick method that is called when the add {@link Button} is pressed.
*/
public void onAdd(View view) {
compute(Calculator.Operator.ADD);
}
/**
* OnClick method that is called when the substract {@link Button} is pressed.
*/
public void onSub(View view) {
compute(Calculator.Operator.SUB);
}
/**
* OnClick method that is called when the divide {@link Button} is pressed.
*/
public void onDiv(View view) {
try {
compute(Calculator.Operator.DIV);
} catch (IllegalArgumentException iae) {
Log.e(TAG, "IllegalArgumentException", iae);
mResultTextView.setText(getString(R.string.computationError));
}
}
/**
* OnClick method that is called when the multiply {@link Button} is pressed.
*/
public void onMul(View view) {
compute(Calculator.Operator.MUL);
}
private void compute(Calculator.Operator operator) {
double operandOne;
double operandTwo;
try {
operandOne = getOperand(mOperandOneEditText);
operandTwo = getOperand(mOperandTwoEditText);
} catch (NumberFormatException nfe) {
Log.e(TAG, "NumberFormatException", nfe);
mResultTextView.setText(getString(R.string.computationError));
return;
}
String result;
switch (operator) {
case ADD:
result = String.valueOf(mCalculator.add(operandOne, operandTwo));
break;
case SUB:
result = String.valueOf(mCalculator.sub(operandOne, operandTwo));
break;
case DIV:
result = String.valueOf(mCalculator.div(operandOne, operandTwo));
break;
case MUL:
result = String.valueOf(mCalculator.mul(operandOne, operandTwo));
break;
default:
result = getString(R.string.computationError);
break;
}
mResultTextView.setText(result);
}
/**
* @return the operand value which was entered in an {@link EditText} as a double
*/
private static Double getOperand(EditText operandEditText) {
String operandText = getOperandText(operandEditText);
return Double.valueOf(operandText);
}
/**
* @return the operand text which was entered in an {@link EditText}.
*/
private static String getOperandText(EditText operandEditText) {
String operandText = operandEditText.getText().toString();
if (TextUtils.isEmpty(operandText)) {
throw new NumberFormatException("operand cannot be empty!");
}
return operandText;
}
}
================================================
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/layout/activity_calculator.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".CalculatorActivity">
<EditText android:id="@+id/operand_one_edit_text"
android:hint="@string/type_operand_one_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<EditText android:id="@+id/operand_two_edit_text"
android:hint="@string/type_operant_two_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/operation_add_btn"
android:layout_width="wrap_con
gitextract_2qqpyglt/ ├── .bazelrc ├── .github/ │ ├── ci-gradle.properties │ └── workflows/ │ ├── composescreenshot.yml │ ├── copy-branch.yml │ ├── gradle-wrapper-validation.yml │ └── test-all.yml ├── .gitignore ├── BUILD.bazel ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── WORKSPACE ├── bazelci/ │ └── buildkite-pipeline.yml ├── common_defs.bzl ├── integration/ │ └── ServiceTestRuleSample/ │ ├── .gitignore │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── ServiceTestRuleSample/ │ │ │ └── LocalServiceTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── ServiceTestRuleSample/ │ │ │ └── LocalService.java │ │ └── res/ │ │ ├── values/ │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v13/ │ │ │ └── styles.xml │ │ └── values-v21/ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── projects.conf ├── renovate.json ├── runner/ │ ├── AndroidJunitRunnerSample/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── androidjunitrunnersample/ │ │ │ │ ├── CalculatorAddParameterizedTest.java │ │ │ │ ├── CalculatorInstrumentationTest.java │ │ │ │ ├── CalculatorTest.java │ │ │ │ ├── HintMatcher.java │ │ │ │ ├── OperationHintInstrumentationTest.java │ │ │ │ ├── OperationHintLegacyInstrumentationTest.java │ │ │ │ └── suite/ │ │ │ │ ├── AndroidTestSuite.java │ │ │ │ ├── InstrumentationTestSuite.java │ │ │ │ └── UnitTestSuite.java │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── androidjunitrunnersample/ │ │ │ │ ├── Calculator.java │ │ │ │ └── CalculatorActivity.java │ │ │ └── res/ │ │ │ ├── layout/ │ │ │ │ └── activity_calculator.xml │ │ │ ├── values/ │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── values-v14/ │ │ │ │ └── styles.xml │ │ │ ├── values-v21/ │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── AndroidTestOrchestratorSample/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── androidtestorchestratorsample/ │ │ │ │ ├── CalculatorAddParameterizedTest.java │ │ │ │ └── CalculatorInstrumentationTest.java │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── androidtestorchestratorsample/ │ │ │ │ ├── Calculator.java │ │ │ │ └── CalculatorActivity.java │ │ │ └── res/ │ │ │ ├── layout/ │ │ │ │ └── activity_calculator.xml │ │ │ ├── values/ │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── values-v14/ │ │ │ │ └── styles.xml │ │ │ ├── values-v21/ │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ └── AndroidTestOrchestratorWithTestCoverageSample/ │ ├── .gitignore │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── androidtestorchestratorsample/ │ │ │ ├── CalculatorAddParameterizedTest.java │ │ │ └── CalculatorInstrumentationTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── androidtestorchestratorsample/ │ │ │ ├── Calculator.java │ │ │ └── CalculatorActivity.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_calculator.xml │ │ ├── values/ │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v14/ │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── test_all.sh ├── ui/ │ ├── PreviewScreenshot/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── compose/ │ │ │ │ │ └── previewscreenshot/ │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ └── ui/ │ │ │ │ │ └── theme/ │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── Theme.kt │ │ │ │ │ └── Type.kt │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── mipmap-anydpi-v26/ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── themes.xml │ │ │ │ ├── values-es/ │ │ │ │ │ └── strings.xml │ │ │ │ └── xml/ │ │ │ │ ├── backup_rules.xml │ │ │ │ └── data_extraction_rules.xml │ │ │ └── screenshotTest/ │ │ │ └── kotlin/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── compose/ │ │ │ └── previewscreenshot/ │ │ │ └── MainScreen.kt │ │ ├── build.gradle.kts │ │ ├── gradle/ │ │ │ ├── libs.versions.toml │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle.kts │ ├── espresso/ │ │ ├── AccessibilitySample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── AccessibilitySample/ │ │ │ │ │ └── AccessibilityChecksTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── AccessibilitySample/ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v13/ │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── BasicSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── BasicSample/ │ │ │ │ │ ├── ChangeTextBehaviorKtTest.kt │ │ │ │ │ └── ChangeTextBehaviorTest.java │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── AppManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── android/ │ │ │ │ │ │ └── testing/ │ │ │ │ │ │ └── espresso/ │ │ │ │ │ │ └── BasicSample/ │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── ShowTextActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── layout/ │ │ │ │ │ │ ├── activity_main.xml │ │ │ │ │ │ └── activity_show_text.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v13/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v21/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-w820dp/ │ │ │ │ │ └── dimens.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── BasicSample/ │ │ │ │ └── ChangeTextBehaviorLocalTest.java │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── CustomMatcherSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── AppManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── android/ │ │ │ │ │ │ └── testing/ │ │ │ │ │ │ └── espresso/ │ │ │ │ │ │ └── CustomMatcherSample/ │ │ │ │ │ │ └── MainActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ ├── correct.xml │ │ │ │ │ │ └── incorrect.xml │ │ │ │ │ ├── layout/ │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v13/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v21/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-w820dp/ │ │ │ │ │ └── dimens.xml │ │ │ │ └── sharedTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── CustomMatcherSample/ │ │ │ │ ├── HintMatcher.java │ │ │ │ └── HintMatchersTest.java │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── DataAdapterSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── AppManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── android/ │ │ │ │ │ │ └── testing/ │ │ │ │ │ │ └── espresso/ │ │ │ │ │ │ └── DataAdapterSample/ │ │ │ │ │ │ └── LongListActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── layout/ │ │ │ │ │ │ ├── list_activity.xml │ │ │ │ │ │ └── list_item.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v21/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-w820dp/ │ │ │ │ │ └── dimens.xml │ │ │ │ └── sharedTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── DataAdapterSample/ │ │ │ │ └── LongListActivityTest.java │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── EspressoDeviceSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── EspressoDeviceSample/ │ │ │ │ │ ├── RequiresDisplayTest.kt │ │ │ │ │ └── ResizeDisplayTest.kt │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── EspressoDeviceSample/ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v13/ │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── FragmentScenarioSample/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── .gitignore │ │ │ │ ├── build.gradle │ │ │ │ ├── proguard-rules.pro │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── android/ │ │ │ │ │ │ └── testing/ │ │ │ │ │ │ └── espresso/ │ │ │ │ │ │ └── fragmentscenario/ │ │ │ │ │ │ ├── SampleDialogFragment.kt │ │ │ │ │ │ └── SampleFragment.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── layout/ │ │ │ │ │ │ └── fragment_sample.xml │ │ │ │ │ └── values/ │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── sharedTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── fragmentscenario/ │ │ │ │ ├── SampleDialogFragmentTest.kt │ │ │ │ └── SampleFragmentTest.kt │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── IdlingResourceSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── IdlingResourceSample/ │ │ │ │ │ └── ChangeTextBehaviorTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── IdlingResourceSample/ │ │ │ │ │ ├── IdlingResource/ │ │ │ │ │ │ └── SimpleIdlingResource.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MessageDelayer.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v13/ │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── IntentsAdvancedSample/ │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── intents/ │ │ │ │ │ └── AdvancedSample/ │ │ │ │ │ ├── ImageViewHasDrawableMatcher.java │ │ │ │ │ └── ImageViewerActivityTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── intents/ │ │ │ │ │ └── AdvancedSample/ │ │ │ │ │ └── ImageViewerActivity.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_image_viewer.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v13/ │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── IntentsBasicSample/ │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── AppManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── android/ │ │ │ │ │ │ └── testing/ │ │ │ │ │ │ └── espresso/ │ │ │ │ │ │ └── IntentsBasicSample/ │ │ │ │ │ │ ├── ContactsActivity.java │ │ │ │ │ │ └── DialerActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── layout/ │ │ │ │ │ │ ├── activity_contacts.xml │ │ │ │ │ │ └── activity_dialer.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v13/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── values-v21/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-w820dp/ │ │ │ │ │ └── dimens.xml │ │ │ │ └── sharedTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── IntentsBasicSample/ │ │ │ │ └── DialerActivityTest.java │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── MultiProcessSample/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── .gitignore │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── multiprocesssample/ │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── multiprocesssample/ │ │ │ │ │ ├── DefaultProcessActivity.java │ │ │ │ │ ├── PrivateProcessActivity.java │ │ │ │ │ └── Util.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ ├── activity_default_process.xml │ │ │ │ │ └── activity_private_process.xml │ │ │ │ └── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── MultiWindowSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── MultiWindowSample/ │ │ │ │ │ └── MultiWindowTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── MultiWindowSample/ │ │ │ │ │ └── SuggestActivity.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── suggest_activity.xml │ │ │ │ └── values/ │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── RecyclerViewSample/ │ │ │ ├── .gitignore │ │ │ ├── BUILD.bazel │ │ │ ├── README.md │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── RecyclerViewSample/ │ │ │ │ │ └── RecyclerViewSampleTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── AppManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── RecyclerViewSample/ │ │ │ │ │ ├── CustomAdapter.java │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ ├── activity_main.xml │ │ │ │ │ └── text_row_item.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v13/ │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── ScreenshotSample/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── .gitignore │ │ │ │ ├── build.gradle │ │ │ │ ├── proguard-rules.pro │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── screenshotsample/ │ │ │ │ │ ├── ScreenshotJavaTest.java │ │ │ │ │ └── ScreenshotTest.kt │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── espresso/ │ │ │ │ │ └── screenshotsample/ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── drawable-v24/ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── mipmap-anydpi-v26/ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── themes.xml │ │ │ │ └── values-night/ │ │ │ │ └── themes.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ └── WebBasicSample/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── web/ │ │ │ │ └── BasicSample/ │ │ │ │ └── WebViewActivityTest.java │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets/ │ │ │ │ ├── web_form.html │ │ │ │ └── web_form_response.html │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── espresso/ │ │ │ │ └── web/ │ │ │ │ └── BasicSample/ │ │ │ │ └── WebViewActivity.java │ │ │ └── res/ │ │ │ ├── layout/ │ │ │ │ └── activity_web_view.xml │ │ │ ├── values/ │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── values-v13/ │ │ │ │ └── styles.xml │ │ │ ├── values-v21/ │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ └── uiautomator/ │ └── BasicSample/ │ ├── .gitignore │ ├── BUILD.bazel │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── androidTest/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── uiautomator/ │ │ │ └── BasicSample/ │ │ │ └── ChangeTextBehaviorTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── AppManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── uiautomator/ │ │ │ └── BasicSample/ │ │ │ ├── MainActivity.java │ │ │ └── ShowTextActivity.java │ │ └── res/ │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ └── activity_show_text.xml │ │ ├── values/ │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v13/ │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── unit/ │ ├── BasicNativeAndroidTest/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── android/ │ │ │ │ └── testing/ │ │ │ │ └── nativesample/ │ │ │ │ └── AdderTest.kt │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── cpp/ │ │ │ ├── CMakeLists.txt │ │ │ ├── include/ │ │ │ │ └── adder │ │ │ ├── src/ │ │ │ │ └── adder.cpp │ │ │ └── test/ │ │ │ └── adder_test.cpp │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── BasicSample/ │ │ ├── .google/ │ │ │ └── packaging.yaml │ │ ├── README.md │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── unittesting/ │ │ │ │ │ └── BasicSample/ │ │ │ │ │ ├── EmailValidator.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── SharedPreferenceEntry.java │ │ │ │ │ └── SharedPreferencesHelper.java │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── unittesting/ │ │ │ └── BasicSample/ │ │ │ ├── EmailValidatorTest.java │ │ │ └── SharedPreferencesHelperTest.java │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── BasicSample-kotlinApp/ │ │ ├── .google/ │ │ │ └── packaging.yaml │ │ ├── README.md │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── android/ │ │ │ │ │ └── testing/ │ │ │ │ │ └── unittesting/ │ │ │ │ │ └── BasicSample/ │ │ │ │ │ ├── EmailValidator.kt │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── SharedPreferenceEntry.kt │ │ │ │ │ └── SharedPreferencesHelper.kt │ │ │ │ └── res/ │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── values-v21/ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── values-w820dp/ │ │ │ │ └── dimens.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── unittesting/ │ │ │ └── BasicSample/ │ │ │ ├── EmailValidatorTest.kt │ │ │ └── SharedPreferencesHelperTest.kt │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ └── BasicUnitAndroidTest/ │ ├── .gitignore │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── unittesting/ │ │ │ └── basicunitandroidtest/ │ │ │ └── LogHistoryAndroidUnitTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── android/ │ │ │ └── testing/ │ │ │ └── unittesting/ │ │ │ └── basicunitandroidtest/ │ │ │ ├── LogHistory.java │ │ │ └── MainActivity.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ ├── values/ │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle └── update_versions.sh
SYMBOL INDEX (332 symbols across 69 files)
FILE: integration/ServiceTestRuleSample/app/src/androidTest/java/com/example/android/testing/ServiceTestRuleSample/LocalServiceTest.java
class LocalServiceTest (line 53) | @MediumTest
method testWithBoundService (line 59) | @Test
FILE: integration/ServiceTestRuleSample/app/src/main/java/com/example/android/testing/ServiceTestRuleSample/LocalService.java
class LocalService (line 32) | public class LocalService extends Service {
method onBind (line 44) | @Override
class LocalBinder (line 54) | public class LocalBinder extends Binder {
method getService (line 56) | public LocalService getService() {
method getRandomInt (line 65) | public int getRandomInt() {
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorAddParameterizedTest.java
class CalculatorAddParameterizedTest (line 40) | @RunWith(Parameterized.class)
method data (line 49) | @Parameters
method CalculatorAddParameterizedTest (line 72) | public CalculatorAddParameterizedTest(double operandOne, double operan...
method setUp (line 80) | @Before
method testAdd_TwoNumbers (line 85) | @Test
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorInstrumentationTest.java
class CalculatorInstrumentationTest (line 49) | @RunWith(AndroidJUnit4.class)
method launchActivity (line 56) | @Before
method noOperandShowsComputationError (line 61) | @Test
method typeOperandsAndPerformAddOperation (line 68) | @Test
method typeOperandsAndPerformSubOperation (line 73) | @Test
method typeOperandsAndPerformDivOperation (line 78) | @Test
method divZeroForOperandTwoShowsError (line 83) | @Test
method typeOperandsAndPerformMulOperation (line 89) | @Test
method performOperation (line 94) | private void performOperation(int btnOperationResId, String operandOne,
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorTest.java
class CalculatorTest (line 33) | @RunWith(AndroidJUnit4.class)
method setUp (line 39) | @Before
method addTwoNumbers (line 44) | @Test
method subTwoNumbers (line 50) | @Test
method subWorksWithNegativeResult (line 56) | @Test
method divTwoNumbers (line 62) | @Test
method divDivideByZeroThrows (line 68) | @Test(expected = IllegalArgumentException.class)
method mulTwoNumbers (line 73) | @Test
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/HintMatcher.java
class HintMatcher (line 34) | public class HintMatcher {
method withHint (line 36) | static Matcher<View> withHint(final String substring) {
method withHint (line 40) | static Matcher<View> withHint(final Matcher<String> stringMatcher) {
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintInstrumentationTest.java
class OperationHintInstrumentationTest (line 43) | @LargeTest
method OperationHintInstrumentationTest (line 49) | public OperationHintInstrumentationTest() {
method setUp (line 53) | @Override
method testPreconditions (line 61) | public void testPreconditions() {
method testEditText_OperandOneHint (line 65) | public void testEditText_OperandOneHint() {
method testEditText_OperandTwoHint (line 70) | public void testEditText_OperandTwoHint() {
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintLegacyInstrumentationTest.java
class OperationHintLegacyInstrumentationTest (line 47) | @LargeTest
method OperationHintLegacyInstrumentationTest (line 53) | public OperationHintLegacyInstrumentationTest() {
method setUp (line 57) | @Override
method testPreconditions (line 65) | public void testPreconditions() {
method testEditText_OperandOneHint (line 69) | public void testEditText_OperandOneHint() {
method testEditText_OperandTwoHint (line 74) | public void testEditText_OperandTwoHint() {
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/AndroidTestSuite.java
class AndroidTestSuite (line 25) | @RunWith(Suite.class)
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/InstrumentationTestSuite.java
class InstrumentationTestSuite (line 28) | @RunWith(Suite.class)
FILE: runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/UnitTestSuite.java
class UnitTestSuite (line 28) | @RunWith(Suite.class)
FILE: runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/Calculator.java
class Calculator (line 24) | public class Calculator {
type Operator (line 26) | public enum Operator {ADD, SUB, DIV, MUL}
method add (line 31) | public double add(double firstOperand, double secondOperand) {
method sub (line 38) | public double sub(double firstOperand, double secondOperand) {
method div (line 45) | public double div(double firstOperand, double secondOperand) {
method mul (line 53) | public double mul(double firstOperand, double secondOperand) {
FILE: runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/CalculatorActivity.java
class CalculatorActivity (line 33) | public class CalculatorActivity extends Activity {
method onCreate (line 44) | @Override
method onAdd (line 57) | public void onAdd(View view) {
method onSub (line 64) | public void onSub(View view) {
method onDiv (line 71) | public void onDiv(View view) {
method onMul (line 83) | public void onMul(View view) {
method compute (line 87) | private void compute(Calculator.Operator operator) {
method getOperand (line 123) | private static Double getOperand(EditText operandEditText) {
method getOperandText (line 131) | private static String getOperandText(EditText operandEditText) {
FILE: runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java
class CalculatorAddParameterizedTest (line 42) | @RunWith(Parameterized.class)
method data (line 51) | @Parameters
method CalculatorAddParameterizedTest (line 74) | public CalculatorAddParameterizedTest(double operandOne, double operan...
method setUp (line 82) | @Before
method testAdd_TwoNumbers (line 87) | @Test
FILE: runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java
class CalculatorInstrumentationTest (line 51) | @RunWith(AndroidJUnit4.class)
method launchActivity (line 58) | @Before
method noOperandShowsComputationError (line 63) | @Test
method typeOperandsAndPerformAddOperation (line 70) | @Test
method typeOperandsAndPerformSubOperation (line 75) | @Test
method typeOperandsAndPerformDivOperation (line 80) | @Test
method divZeroForOperandTwoShowsError (line 85) | @Test
method typeOperandsAndPerformMulOperation (line 91) | @Test
method performOperation (line 96) | private void performOperation(int btnOperationResId, String operandOne,
FILE: runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java
class Calculator (line 24) | public class Calculator {
type Operator (line 26) | public enum Operator {ADD, SUB, DIV, MUL}
method add (line 31) | public double add(double firstOperand, double secondOperand) {
method sub (line 38) | public double sub(double firstOperand, double secondOperand) {
method div (line 45) | public double div(double firstOperand, double secondOperand) {
method mul (line 53) | public double mul(double firstOperand, double secondOperand) {
FILE: runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java
class CalculatorActivity (line 33) | public class CalculatorActivity extends Activity {
method onCreate (line 44) | @Override
method onAdd (line 57) | public void onAdd(View view) {
method onSub (line 64) | public void onSub(View view) {
method onDiv (line 71) | public void onDiv(View view) {
method onMul (line 83) | public void onMul(View view) {
method compute (line 87) | private void compute(Calculator.Operator operator) {
method getOperand (line 123) | private static Double getOperand(EditText operandEditText) {
method getOperandText (line 131) | private static String getOperandText(EditText operandEditText) {
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java
class CalculatorAddParameterizedTest (line 42) | @RunWith(Parameterized.class)
method data (line 51) | @Parameters
method CalculatorAddParameterizedTest (line 74) | public CalculatorAddParameterizedTest(double operandOne, double operan...
method setUp (line 82) | @Before
method testAdd_TwoNumbers (line 87) | @Test
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java
class CalculatorInstrumentationTest (line 50) | @RunWith(AndroidJUnit4.class)
method launchActivity (line 57) | @Before
method noOperandShowsComputationError (line 62) | @Test
method typeOperandsAndPerformAddOperation (line 69) | @Test
method typeOperandsAndPerformSubOperation (line 74) | @Test
method typeOperandsAndPerformDivOperation (line 79) | @Test
method divZeroForOperandTwoShowsError (line 84) | @Test
method typeOperandsAndPerformMulOperation (line 90) | @Test
method performOperation (line 95) | private void performOperation(int btnOperationResId, String operandOne,
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java
class Calculator (line 24) | public class Calculator {
type Operator (line 26) | public enum Operator {ADD, SUB, DIV, MUL}
method add (line 31) | public double add(double firstOperand, double secondOperand) {
method sub (line 38) | public double sub(double firstOperand, double secondOperand) {
method div (line 45) | public double div(double firstOperand, double secondOperand) {
method mul (line 53) | public double mul(double firstOperand, double secondOperand) {
FILE: runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java
class CalculatorActivity (line 33) | public class CalculatorActivity extends Activity {
method onCreate (line 44) | @Override
method onAdd (line 57) | public void onAdd(View view) {
method onSub (line 64) | public void onSub(View view) {
method onDiv (line 71) | public void onDiv(View view) {
method onMul (line 83) | public void onMul(View view) {
method compute (line 87) | private void compute(Calculator.Operator operator) {
method getOperand (line 123) | private static Double getOperand(EditText operandEditText) {
method getOperandText (line 131) | private static String getOperandText(EditText operandEditText) {
FILE: ui/espresso/AccessibilitySample/app/src/androidTest/java/com/example/android/testing/espresso/AccessibilitySample/AccessibilityChecksTest.java
class AccessibilityChecksTest (line 34) | @RunWith(AndroidJUnit4.class)
method accessibilityChecks (line 38) | @Test
FILE: ui/espresso/AccessibilitySample/app/src/main/java/com/example/android/testing/espresso/AccessibilitySample/MainActivity.java
class MainActivity (line 32) | public class MainActivity extends Activity implements View.OnClickListen...
method onCreate (line 34) | @Override
method onClick (line 41) | @Override
FILE: ui/espresso/BasicSample/app/src/androidTest/java/com/example/android/testing/espresso/BasicSample/ChangeTextBehaviorTest.java
class ChangeTextBehaviorTest (line 46) | @RunWith(AndroidJUnit4.class)
method changeText_sameActivity (line 59) | @Test
method changeText_newActivity (line 70) | @Test
FILE: ui/espresso/BasicSample/app/src/main/java/com/example/android/testing/espresso/BasicSample/MainActivity.java
class MainActivity (line 31) | public class MainActivity extends Activity implements View.OnClickListen...
method onCreate (line 39) | @Override
method onClick (line 52) | @Override
FILE: ui/espresso/BasicSample/app/src/main/java/com/example/android/testing/espresso/BasicSample/ShowTextActivity.java
class ShowTextActivity (line 30) | public class ShowTextActivity extends Activity {
method onCreate (line 36) | @Override
method newStartIntent (line 55) | static protected Intent newStartIntent(Context context, String message) {
FILE: ui/espresso/BasicSample/app/src/test/java/com/example/android/testing/espresso/BasicSample/ChangeTextBehaviorLocalTest.java
class ChangeTextBehaviorLocalTest (line 23) | @RunWith(AndroidJUnit4.class)
method intentsInit (line 34) | @Before
method intentsTeardown (line 40) | @After
method changeText_sameActivity (line 46) | @Test
method changeText_newActivity (line 58) | @Test
FILE: ui/espresso/CustomMatcherSample/app/src/main/java/com/example/android/testing/espresso/CustomMatcherSample/MainActivity.java
class MainActivity (line 34) | public class MainActivity extends Activity implements View.OnClickListen...
method onCreate (line 47) | @Override
method onClick (line 61) | @Override
method showResult (line 72) | private void showResult(boolean isValidResult) {
method validateText (line 77) | private static boolean validateText(String inputText) {
FILE: ui/espresso/CustomMatcherSample/app/src/sharedTest/java/com/example/android/testing/espresso/CustomMatcherSample/HintMatcher.java
class HintMatcher (line 32) | public class HintMatcher {
method withHint (line 34) | static Matcher<View> withHint(final String substring) {
method withHint (line 38) | static Matcher<View> withHint(final Matcher<String> stringMatcher) {
FILE: ui/espresso/CustomMatcherSample/app/src/sharedTest/java/com/example/android/testing/espresso/CustomMatcherSample/HintMatchersTest.java
class HintMatchersTest (line 46) | @RunWith(AndroidJUnit4.class)
method initValidStrings (line 72) | @Before
method hint_isDisplayedInEditText (line 84) | @Test
method hint_endsWith (line 94) | @SuppressWarnings("unchecked")
method editText_canBeTypedInto (line 103) | @Test
method validation_resultIsOneOfTheValidStrings (line 110) | @Test
method validation_resultHasCorrectEnding (line 122) | @Test
method validation_resultIsIncorrect (line 134) | @Test
FILE: ui/espresso/DataAdapterSample/app/src/main/java/com/example/android/testing/espresso/DataAdapterSample/LongListActivity.java
class LongListActivity (line 40) | public class LongListActivity extends Activity {
method onCreate (line 58) | @Override
method makeItem (line 76) | @VisibleForTesting
method populateData (line 84) | private void populateData() {
class LongListAdapter (line 90) | private class LongListAdapter extends SimpleAdapter {
method LongListAdapter (line 92) | public LongListAdapter(String[] from, int[] to) {
method getView (line 96) | @Override
FILE: ui/espresso/DataAdapterSample/app/src/sharedTest/java/com/example/android/testing/espresso/DataAdapterSample/LongListActivityTest.java
class LongListActivityTest (line 54) | @RunWith(AndroidJUnit4.class)
method lastItem_NotDisplayed (line 78) | @Test
method list_Scrolls (line 87) | @Test
method row_Click (line 95) | @Test
method toggle_Click (line 108) | @Test
method toggle_ClickDoesntPropagate (line 120) | @Test
method onRow (line 143) | private static DataInteraction onRow(String str) {
FILE: ui/espresso/EspressoDeviceSample/app/src/main/java/com/example/android/testing/espresso/EspressoDeviceSample/MainActivity.java
class MainActivity (line 25) | public class MainActivity extends Activity {
method onCreate (line 26) | @Override
FILE: ui/espresso/IdlingResourceSample/app/src/androidTest/java/com/example/android/testing/espresso/IdlingResourceSample/ChangeTextBehaviorTest.java
class ChangeTextBehaviorTest (line 42) | @RunWith(AndroidJUnit4.class)
method registerIdlingResource (line 56) | @Before
method changeText_sameActivity (line 69) | @Test
method unregisterIdlingResource (line 80) | @After
FILE: ui/espresso/IdlingResourceSample/app/src/main/java/com/example/android/testing/espresso/IdlingResourceSample/IdlingResource/SimpleIdlingResource.java
class SimpleIdlingResource (line 31) | public class SimpleIdlingResource implements IdlingResource {
method getName (line 38) | @Override
method isIdleNow (line 43) | @Override
method registerIdleTransitionCallback (line 48) | @Override
method setIdleState (line 57) | public void setIdleState(boolean isIdleNow) {
FILE: ui/espresso/IdlingResourceSample/app/src/main/java/com/example/android/testing/espresso/IdlingResourceSample/MainActivity.java
class MainActivity (line 34) | public class MainActivity extends Activity implements View.OnClickListener,
method onCreate (line 46) | @Override
method onClick (line 58) | @Override
method onDone (line 71) | @Override
method getIdlingResource (line 80) | @VisibleForTesting
FILE: ui/espresso/IdlingResourceSample/app/src/main/java/com/example/android/testing/espresso/IdlingResourceSample/MessageDelayer.java
class MessageDelayer (line 31) | class MessageDelayer {
type DelayerCallback (line 35) | interface DelayerCallback {
method onDone (line 36) | void onDone(String text);
method processMessage (line 44) | static void processMessage(final String message, final DelayerCallback...
FILE: ui/espresso/IntentsAdvancedSample/app/src/androidTest/java/com/example/android/testing/espresso/intents/AdvancedSample/ImageViewHasDrawableMatcher.java
class ImageViewHasDrawableMatcher (line 29) | public class ImageViewHasDrawableMatcher {
method hasDrawable (line 31) | public static Matcher<View> hasDrawable() {
FILE: ui/espresso/IntentsAdvancedSample/app/src/androidTest/java/com/example/android/testing/espresso/intents/AdvancedSample/ImageViewerActivityTest.java
class ImageViewerActivityTest (line 50) | @RunWith(AndroidJUnit4.class)
method stubCameraIntent (line 62) | @Before
method tearDown (line 73) | @After
method takePhoto_drawableIsApplied (line 79) | @Test
method createImageCaptureActivityResultStub (line 91) | private ActivityResult createImageCaptureActivityResultStub() {
FILE: ui/espresso/IntentsAdvancedSample/app/src/main/java/com/example/android/testing/espresso/intents/AdvancedSample/ImageViewerActivity.java
class ImageViewerActivity (line 31) | public class ImageViewerActivity extends Activity {
method onCreate (line 40) | @Override
method dispatchTakePictureIntent (line 47) | private void dispatchTakePictureIntent() {
method onOpenCamera (line 54) | public void onOpenCamera(View view) {
method onActivityResult (line 58) | @Override
FILE: ui/espresso/IntentsBasicSample/app/src/main/java/com/example/android/testing/espresso/IntentsBasicSample/ContactsActivity.java
class ContactsActivity (line 28) | public class ContactsActivity extends Activity {
method onCreate (line 32) | @Override
method createResultData (line 40) | @VisibleForTesting
FILE: ui/espresso/IntentsBasicSample/app/src/main/java/com/example/android/testing/espresso/IntentsBasicSample/DialerActivity.java
class DialerActivity (line 39) | public class DialerActivity extends Activity {
method onCreate (line 45) | @Override
method onCall (line 52) | public void onCall(View view) {
method onPickContact (line 62) | public void onPickContact(View view) {
method createCallIntentFromNumber (line 67) | private Intent createCallIntentFromNumber() {
method onActivityResult (line 74) | @Override
FILE: ui/espresso/IntentsBasicSample/app/src/sharedTest/java/com/example/android/testing/espresso/IntentsBasicSample/DialerActivityTest.java
class DialerActivityTest (line 57) | @RunWith(AndroidJUnit4.class)
method stubAllExternalIntents (line 81) | @Before
method typeNumber_ValidInput_InitiatesCall (line 88) | @Test
method typeNumber_ValidInput_InitiatesCall_truth (line 105) | @Test
method pickContactButton_click_SelectsPhoneNumber (line 119) | @Test
FILE: ui/espresso/MultiProcessSample/app/src/androidTest/java/com/example/android/testing/espresso/multiprocesssample/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 40) | @RunWith(AndroidJUnit4.class)
method launchActivity (line 48) | @Before
method verifyAssertingOnViewInRemoteProcessIsSuccessful (line 53) | @Test
FILE: ui/espresso/MultiProcessSample/app/src/main/java/com/example/android/testing/espresso/multiprocesssample/DefaultProcessActivity.java
class DefaultProcessActivity (line 30) | public class DefaultProcessActivity extends Activity {
method onCreate (line 34) | @Override
method onStartActivityBtnClick (line 42) | public void onStartActivityBtnClick(View view) {
FILE: ui/espresso/MultiProcessSample/app/src/main/java/com/example/android/testing/espresso/multiprocesssample/PrivateProcessActivity.java
class PrivateProcessActivity (line 37) | public class PrivateProcessActivity extends Activity implements OnItemCl...
method onCreate (line 42) | @Override
method onBtnClick (line 58) | public void onBtnClick(View view) {
method onItemClick (line 63) | @Override
FILE: ui/espresso/MultiProcessSample/app/src/main/java/com/example/android/testing/espresso/multiprocesssample/Util.java
class Util (line 30) | public class Util {
method setCurrentRunningProcess (line 37) | public static void setCurrentRunningProcess(TextView textView, Context...
FILE: ui/espresso/MultiWindowSample/app/src/androidTest/java/com/example/android/testing/espresso/MultiWindowSample/MultiWindowTest.java
class MultiWindowTest (line 67) | @RunWith(AndroidJUnit4.class)
method setActivity (line 88) | @Before
method autoCompleteTextView_twoSuggestions (line 93) | @Test
method autoCompleteTextView_oneSuggestion (line 108) | @Test
method autoCompleteTextView_clickAndCheck (line 125) | @Test
method autoCompleteTextView_onDataClickAndCheck (line 141) | @Test
FILE: ui/espresso/MultiWindowSample/app/src/main/java/com/example/android/testing/espresso/MultiWindowSample/SuggestActivity.java
class SuggestActivity (line 26) | public class SuggestActivity extends Activity {
method onCreate (line 28) | @Override
method setUpAutoCompleteTextView (line 39) | private void setUpAutoCompleteTextView() {
FILE: ui/espresso/RecyclerViewSample/app/src/androidTest/java/com/example/android/testing/espresso/RecyclerViewSample/RecyclerViewSampleTest.java
class RecyclerViewSampleTest (line 47) | @RunWith(AndroidJUnit4.class)
method itemWithText_doesNotExist (line 61) | @Test(expected = PerformException.class)
method scrollToItemBelowFold_checkItsText (line 71) | @Test
method itemInMiddleOfList_hasSpecialText (line 83) | @Test
method isInTheMiddle (line 98) | private static Matcher<CustomAdapter.ViewHolder> isInTheMiddle() {
FILE: ui/espresso/RecyclerViewSample/app/src/main/java/com/example/android/testing/espresso/RecyclerViewSample/CustomAdapter.java
class CustomAdapter (line 31) | public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.Vi...
class ViewHolder (line 41) | static class ViewHolder extends RecyclerView.ViewHolder {
method ViewHolder (line 47) | ViewHolder(View v) {
method getTextView (line 52) | TextView getTextView() {
method getIsInTheMiddle (line 56) | boolean getIsInTheMiddle() {
method setIsInTheMiddle (line 60) | void setIsInTheMiddle(boolean isInTheMiddle) {
method CustomAdapter (line 70) | CustomAdapter(List<String> dataSet, Context context) {
method onCreateViewHolder (line 75) | @Override
method onBindViewHolder (line 84) | @Override
method getItemCount (line 96) | @Override
FILE: ui/espresso/RecyclerViewSample/app/src/main/java/com/example/android/testing/espresso/RecyclerViewSample/MainActivity.java
class MainActivity (line 30) | public class MainActivity extends Activity {
method onCreate (line 34) | @Override
FILE: ui/espresso/ScreenshotSample/app/src/androidTest/java/com/example/android/testing/espresso/screenshotsample/ScreenshotJavaTest.java
class ScreenshotJavaTest (line 26) | @RunWith(AndroidJUnit4.class)
method saveActivityBitmap (line 39) | @Test
method saveViewBitmap (line 56) | @Test
method saveDeviceScreenBitmap (line 75) | @Test
FILE: ui/espresso/WebBasicSample/app/src/androidTest/java/com/example/android/testing/espresso/web/BasicSample/WebViewActivityTest.java
class WebViewActivityTest (line 49) | @LargeTest
method afterActivityLaunched (line 70) | @Override
method typeTextInInput_clickButton_SubmitsForm (line 79) | @Test
method typeTextInInput_clickButton_ChangesText (line 103) | @Test
method withWebFormIntent (line 130) | private static Intent withWebFormIntent() {
FILE: ui/espresso/WebBasicSample/app/src/main/java/com/example/android/testing/espresso/web/BasicSample/WebViewActivity.java
class WebViewActivity (line 35) | public class WebViewActivity extends Activity {
method onCreate (line 44) | @Override
method urlFromIntent (line 60) | private static String urlFromIntent(@NonNull Intent intent) {
FILE: ui/uiautomator/BasicSample/app/src/androidTest/java/com/example/android/testing/uiautomator/BasicSample/ChangeTextBehaviorTest.java
class ChangeTextBehaviorTest (line 45) | @RunWith(AndroidJUnit4.class)
method startMainActivityFromHomeScreen (line 58) | @Before
method checkPreconditions (line 82) | @Test
method testChangeText_sameActivity (line 87) | @Test
method testChangeText_newActivity (line 102) | @Test
method getLauncherPackageName (line 122) | private String getLauncherPackageName() {
FILE: ui/uiautomator/BasicSample/app/src/main/java/com/example/android/testing/uiautomator/BasicSample/MainActivity.java
class MainActivity (line 31) | public class MainActivity extends Activity implements View.OnClickListen...
method onCreate (line 39) | @Override
method onClick (line 52) | @Override
FILE: ui/uiautomator/BasicSample/app/src/main/java/com/example/android/testing/uiautomator/BasicSample/ShowTextActivity.java
class ShowTextActivity (line 30) | public class ShowTextActivity extends Activity {
method onCreate (line 36) | @Override
method newStartIntent (line 55) | static protected Intent newStartIntent(Context context, String message) {
FILE: unit/BasicNativeAndroidTest/app/src/main/cpp/src/adder.cpp
function add (line 1) | int add(int a, int b) {
FILE: unit/BasicNativeAndroidTest/app/src/main/cpp/test/adder_test.cpp
function TEST (line 4) | TEST(adder, pass) {
function TEST (line 8) | TEST(foo, fail) {
FILE: unit/BasicSample/app/src/main/java/com/example/android/testing/unittesting/BasicSample/EmailValidator.java
class EmailValidator (line 27) | public class EmailValidator implements TextWatcher {
method isValid (line 44) | public boolean isValid() {
method isValidEmail (line 54) | public static boolean isValidEmail(CharSequence email) {
method afterTextChanged (line 58) | @Override
method beforeTextChanged (line 63) | @Override
method onTextChanged (line 66) | @Override
FILE: unit/BasicSample/app/src/main/java/com/example/android/testing/unittesting/BasicSample/MainActivity.java
class MainActivity (line 36) | public class MainActivity extends Activity {
method onCreate (line 56) | @Override
method populateUi (line 81) | private void populateUi() {
method onSaveClick (line 95) | public void onSaveClick(View view) {
method onRevertClick (line 126) | public void onRevertClick(View view) {
FILE: unit/BasicSample/app/src/main/java/com/example/android/testing/unittesting/BasicSample/SharedPreferenceEntry.java
class SharedPreferenceEntry (line 24) | public class SharedPreferenceEntry {
method SharedPreferenceEntry (line 35) | public SharedPreferenceEntry(String name, Calendar dateOfBirth, String...
method getName (line 41) | public String getName() {
method getDateOfBirth (line 45) | public Calendar getDateOfBirth() {
method getEmail (line 49) | public String getEmail() {
FILE: unit/BasicSample/app/src/main/java/com/example/android/testing/unittesting/BasicSample/SharedPreferencesHelper.java
class SharedPreferencesHelper (line 26) | public class SharedPreferencesHelper {
method SharedPreferencesHelper (line 41) | public SharedPreferencesHelper(SharedPreferences sharedPreferences) {
method savePersonalInfo (line 53) | public boolean savePersonalInfo(SharedPreferenceEntry sharedPreference...
method getPersonalInfo (line 70) | public SharedPreferenceEntry getPersonalInfo() {
FILE: unit/BasicSample/app/src/test/java/com/example/android/testing/unittesting/BasicSample/EmailValidatorTest.java
class EmailValidatorTest (line 28) | public class EmailValidatorTest {
method emailValidator_CorrectEmailSimple_ReturnsTrue (line 31) | @Test
method emailValidator_CorrectEmailSubDomain_ReturnsTrue (line 36) | @Test
method emailValidator_InvalidEmailNoTld_ReturnsFalse (line 41) | @Test
method emailValidator_InvalidEmailDoubleDot_ReturnsFalse (line 46) | @Test
method emailValidator_InvalidEmailNoUsername_ReturnsFalse (line 51) | @Test
method emailValidator_EmptyString_ReturnsFalse (line 56) | @Test
method emailValidator_NullEmail_ReturnsFalse (line 61) | @Test
FILE: unit/BasicSample/app/src/test/java/com/example/android/testing/unittesting/BasicSample/SharedPreferencesHelperTest.java
class SharedPreferencesHelperTest (line 36) | @RunWith(MockitoJUnitRunner.class)
method initMocks (line 67) | @Before
method sharedPreferencesHelper_SaveAndReadPersonalInformation (line 80) | @Test
method sharedPreferencesHelper_SavePersonalInformationFailed_ReturnsFalse (line 106) | @Test
method createMockSharedPreference (line 118) | private SharedPreferencesHelper createMockSharedPreference() {
method createBrokenMockSharedPreference (line 139) | private SharedPreferencesHelper createBrokenMockSharedPreference() {
FILE: unit/BasicUnitAndroidTest/app/src/androidTest/java/com/example/android/testing/unittesting/basicunitandroidtest/LogHistoryAndroidUnitTest.java
class LogHistoryAndroidUnitTest (line 35) | @RunWith(AndroidJUnit4.class)
method createLogHistory (line 43) | @Before
method logHistory_ParcelableWriteRead (line 48) | @Test
FILE: unit/BasicUnitAndroidTest/app/src/main/java/com/example/android/testing/unittesting/basicunitandroidtest/LogHistory.java
class LogHistory (line 28) | public class LogHistory implements Parcelable {
method LogHistory (line 34) | public LogHistory() { }
method describeContents (line 36) | @Override
method writeToParcel (line 41) | @Override
method createFromParcel (line 63) | @Override
method newArray (line 68) | @Override
method getData (line 77) | public List<Pair<String, Long>> getData() {
method addEntry (line 86) | public void addEntry(String text, long timestamp) {
method LogHistory (line 91) | private LogHistory(Parcel in) {
FILE: unit/BasicUnitAndroidTest/app/src/main/java/com/example/android/testing/unittesting/basicunitandroidtest/MainActivity.java
class MainActivity (line 35) | public class MainActivity extends Activity {
method updateHistory (line 47) | public void updateHistory(View view) {
method onCreate (line 63) | @Override
method onRestoreInstanceState (line 82) | @Override
method onSaveInstanceState (line 87) | @Override
method appendEntryToView (line 93) | private void appendEntryToView(String text, long timestamp) {
Condensed preview — 577 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,040K chars).
[
{
"path": ".bazelrc",
"chars": 2971,
"preview": "# Configurations for testing with Bazel\n# Select a configuration by running `bazel test //my:target --config={headless, "
},
{
"path": ".github/ci-gradle.properties",
"chars": 0,
"preview": ""
},
{
"path": ".github/workflows/composescreenshot.yml",
"chars": 665,
"preview": "# Workflow name\nname: Compose Preview Screenshot\non:\n workflow_dispatch:\n push:\n branches: [ main ]\n # When it wil"
},
{
"path": ".github/workflows/copy-branch.yml",
"chars": 1014,
"preview": "# Duplicates default main branch to the old master branch\n\nname: Duplicates main to old master branch\n\n# Controls when t"
},
{
"path": ".github/workflows/gradle-wrapper-validation.yml",
"chars": 291,
"preview": "name: Validate Gradle Wrapper\n\non:\n workflow_dispatch:\n push:\n branches: [ main ]\n\n pull_request:\n branches: [ "
},
{
"path": ".github/workflows/test-all.yml",
"chars": 1248,
"preview": "# Workflow name\nname: Build + Test all\non:\n workflow_dispatch:\n push:\n branches: [ main ]\n # When it will be trigg"
},
{
"path": ".gitignore",
"chars": 117,
"preview": ".idea\n*.iml\nlocal.properties\nbuild\n.gradle\n# Eclipse project files\n.project\n.settings/\t\n.classpath\nbazel-*\n.DS_Store\n"
},
{
"path": "BUILD.bazel",
"chars": 1989,
"preview": "load(\"@rules_jvm_external//:defs.bzl\", \"artifact\")\nload(\"//:common_defs.bzl\", \"androidxLibVersion\", \"coreVersion\", \"espr"
},
{
"path": "CODEOWNERS",
"chars": 16,
"preview": "* @josealcerreca"
},
{
"path": "CONTRIBUTING.md",
"chars": 2417,
"preview": "# How to become a contributor and submit your own code\n\nTo contribute with a small fix, simply create a pull request. If"
},
{
"path": "LICENSE",
"chars": 11361,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 8941,
"preview": "Android testing samples\n===================================\n\nA collection of samples demonstrating different frameworks "
},
{
"path": "WORKSPACE",
"chars": 4145,
"preview": "load(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:jvm.bzl\","
},
{
"path": "bazelci/buildkite-pipeline.yml",
"chars": 9854,
"preview": "# https://github.com/googlesamples/android-testing#experimental-bazel-support\n---\nplatforms:\n ubuntu1804:\n build_tar"
},
{
"path": "common_defs.bzl",
"chars": 447,
"preview": "# Common constants for bazel builds\n\n# keep naming convention consistent with gradle variables, so version numbers can b"
},
{
"path": "integration/ServiceTestRuleSample/.gitignore",
"chars": 53,
"preview": ".gradle\nlocal.properties\n.idea\n.DS_Store\nbuild\n*.iml\n"
},
{
"path": "integration/ServiceTestRuleSample/README.md",
"chars": 1534,
"preview": "# Basic sample for ServiceTestRule\n\nThis rule provides a simplified mechanism to start and shutdown your service before "
},
{
"path": "integration/ServiceTestRuleSample/app/build.gradle",
"chars": 1453,
"preview": "apply plugin: \"com.android.application\"\n\nandroid {\n compileSdk 34\n defaultConfig {\n applicationId \"com.exam"
},
{
"path": "integration/ServiceTestRuleSample/app/src/androidTest/java/com/example/android/testing/ServiceTestRuleSample/LocalServiceTest.java",
"chars": 3135,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/AndroidManifest.xml",
"chars": 937,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/java/com/example/android/testing/ServiceTestRuleSample/LocalService.java",
"chars": 2007,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/res/values/strings.xml",
"chars": 734,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/res/values/styles.xml",
"chars": 762,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/res/values-v13/styles.xml",
"chars": 730,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "integration/ServiceTestRuleSample/app/src/main/res/values-v21/styles.xml",
"chars": 735,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "integration/ServiceTestRuleSample/build.gradle",
"chars": 713,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "integration/ServiceTestRuleSample/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "integration/ServiceTestRuleSample/gradle.properties",
"chars": 992,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "integration/ServiceTestRuleSample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "integration/ServiceTestRuleSample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "integration/ServiceTestRuleSample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "projects.conf",
"chars": 590,
"preview": "integration/ServiceTestRuleSample\nrunner/AndroidJunitRunnerSample\nrunner/AndroidTestOrchestratorSample\nui/espresso/Acces"
},
{
"path": "renovate.json",
"chars": 133,
"preview": "{\n \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n \"extends\": [\n \"local>android/.github:renovate-c"
},
{
"path": "runner/AndroidJunitRunnerSample/.gitignore",
"chars": 54,
"preview": ".gradle\n/local.properties\n.idea\n*.iml\n.DS_Store\nbuild\n"
},
{
"path": "runner/AndroidJunitRunnerSample/README.md",
"chars": 2169,
"preview": "# AndroidJUnitRunner sample\n\nThe new android test runner brings Junit4 support to android testing. This samples gives a "
},
{
"path": "runner/AndroidJunitRunnerSample/app/build.gradle",
"chars": 2023,
"preview": "apply plugin: \"com.android.application\"\n\n\nandroid {\n compileSdk 34\n defaultConfig {\n applicationId \"com.exa"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorAddParameterizedTest.java",
"chars": 2813,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorInstrumentationTest.java",
"chars": 4177,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/CalculatorTest.java",
"chars": 2061,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/HintMatcher.java",
"chars": 1907,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintInstrumentationTest.java",
"chars": 2782,
"preview": "/*\n * Copyright 2014, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/OperationHintLegacyInstrumentationTest.java",
"chars": 3080,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/AndroidTestSuite.java",
"chars": 955,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/InstrumentationTestSuite.java",
"chars": 1174,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/androidTest/java/com/example/android/testing/androidjunitrunnersample/suite/UnitTestSuite.java",
"chars": 1088,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/AndroidManifest.xml",
"chars": 1262,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/Calculator.java",
"chars": 1630,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/java/com/example/android/testing/androidjunitrunnersample/CalculatorActivity.java",
"chars": 4657,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/layout/activity_calculator.xml",
"chars": 3335,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values/dimens.xml",
"chars": 854,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values/strings.xml",
"chars": 1117,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values/styles.xml",
"chars": 726,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values-v14/styles.xml",
"chars": 725,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values-v21/styles.xml",
"chars": 741,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 1001,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidJunitRunnerSample/build.gradle",
"chars": 877,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "runner/AndroidJunitRunnerSample/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "runner/AndroidJunitRunnerSample/gradle.properties",
"chars": 1017,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "runner/AndroidJunitRunnerSample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "runner/AndroidJunitRunnerSample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "runner/AndroidJunitRunnerSample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "runner/AndroidTestOrchestratorSample/.gitignore",
"chars": 54,
"preview": ".gradle\n/local.properties\n.idea\n*.iml\n.DS_Store\nbuild\n"
},
{
"path": "runner/AndroidTestOrchestratorSample/README.md",
"chars": 1521,
"preview": "# AndroidTestOrchestrator sample\n\nThe Android Test Orchestrator allows you to run each of your app's tests in isolation,"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/build.gradle",
"chars": 2184,
"preview": "apply plugin: \"com.android.application\"\n\nandroid {\n compileSdk 34\n defaultConfig {\n applicationId \"com.exam"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java",
"chars": 2816,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java",
"chars": 4283,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/AndroidManifest.xml",
"chars": 1262,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java",
"chars": 1635,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java",
"chars": 4662,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/layout/activity_calculator.xml",
"chars": 3335,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values/dimens.xml",
"chars": 854,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values/strings.xml",
"chars": 1122,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values/styles.xml",
"chars": 726,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values-v14/styles.xml",
"chars": 725,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values-v21/styles.xml",
"chars": 741,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 1001,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorSample/build.gradle",
"chars": 907,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "runner/AndroidTestOrchestratorSample/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "runner/AndroidTestOrchestratorSample/gradle.properties",
"chars": 1017,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "runner/AndroidTestOrchestratorSample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "runner/AndroidTestOrchestratorSample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "runner/AndroidTestOrchestratorSample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/.gitignore",
"chars": 54,
"preview": ".gradle\n/local.properties\n.idea\n*.iml\n.DS_Store\nbuild\n"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/README.md",
"chars": 1534,
"preview": "# AndroidTestOrchestrator with test coverage sample\n\nThe Android Test Orchestrator allows you to run each of your app's "
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/build.gradle",
"chars": 1598,
"preview": "apply plugin: \"com.android.application\"\n\nandroid {\n compileSdk 33\n defaultConfig {\n applicationId \"com.exam"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorAddParameterizedTest.java",
"chars": 2816,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/androidTest/java/com/example/android/testing/androidtestorchestratorsample/CalculatorInstrumentationTest.java",
"chars": 4220,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/AndroidManifest.xml",
"chars": 1263,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/Calculator.java",
"chars": 1635,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/java/com/example/android/testing/androidtestorchestratorsample/CalculatorActivity.java",
"chars": 4662,
"preview": "/*\n * Copyright 2020, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/layout/activity_calculator.xml",
"chars": 3335,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values/dimens.xml",
"chars": 854,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values/strings.xml",
"chars": 1122,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values/styles.xml",
"chars": 726,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values-v14/styles.xml",
"chars": 725,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values-v21/styles.xml",
"chars": 741,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 1001,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2020 The Android Open Source Project\n\n Licensed under the Apach"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/build.gradle",
"chars": 970,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/gradle/wrapper/gradle-wrapper.properties",
"chars": 230,
"preview": "#Wed Jun 01 11:09:45 PDT 2022\ndistributionBase=GRADLE_USER_HOME\ndistributionUrl=https\\://services.gradle.org/distributio"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/gradle.properties",
"chars": 1033,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "runner/AndroidTestOrchestratorWithTestCoverageSample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "test_all.sh",
"chars": 579,
"preview": "#!/bin/bash\n\nset -e # Exit immediately if a command exits with a non-zero status.\n\nfor p in $(cat projects.conf); do\n "
},
{
"path": "ui/PreviewScreenshot/.gitignore",
"chars": 225,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor."
},
{
"path": "ui/PreviewScreenshot/README.md",
"chars": 409,
"preview": "# Compose Preview Screenshot Testing tool\n\nExperimental: Compose Preview Screenshot Testing is still in development. Its"
},
{
"path": "ui/PreviewScreenshot/app/.gitignore",
"chars": 6,
"preview": "/build"
},
{
"path": "ui/PreviewScreenshot/app/build.gradle.kts",
"chars": 2708,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/app/proguard-rules.pro",
"chars": 750,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "ui/PreviewScreenshot/app/src/main/AndroidManifest.xml",
"chars": 1725,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/java/com/example/compose/previewscreenshot/MainActivity.kt",
"chars": 2272,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/app/src/main/java/com/example/compose/previewscreenshot/ui/theme/Color.kt",
"chars": 923,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/app/src/main/java/com/example/compose/previewscreenshot/ui/theme/Theme.kt",
"chars": 2305,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/app/src/main/java/com/example/compose/previewscreenshot/ui/theme/Type.kt",
"chars": 1628,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 6244,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/drawable/ic_launcher_foreground.xml",
"chars": 2341,
"preview": "<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed under the Apache License, Version 2.0 (the "
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 982,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 982,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/values/colors.xml",
"chars": 1017,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/values/strings.xml",
"chars": 807,
"preview": "<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed under the Apache License, Version 2.0 (the "
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/values/themes.xml",
"chars": 817,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/values-es/strings.xml",
"chars": 707,
"preview": "<!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed under the Apache License, Version 2.0 (the "
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/xml/backup_rules.xml",
"chars": 1117,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed under"
},
{
"path": "ui/PreviewScreenshot/app/src/main/res/xml/data_extraction_rules.xml",
"chars": 1190,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n ~ Copyright (C) 2024 The Android Open Source Project\n ~\n ~ Licensed under"
},
{
"path": "ui/PreviewScreenshot/app/src/screenshotTest/kotlin/com/example/compose/previewscreenshot/MainScreen.kt",
"chars": 1166,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/build.gradle.kts",
"chars": 850,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/PreviewScreenshot/gradle/libs.versions.toml",
"chars": 1814,
"preview": "[versions]\nagp = \"8.5.0-beta01\"\nkotlin = \"1.9.23\"\ncoreKtx = \"1.13.1\"\njunit = \"4.13.2\"\njunitVersion = \"1.1.5\"\nespressoCor"
},
{
"path": "ui/PreviewScreenshot/gradle/wrapper/gradle-wrapper.properties",
"chars": 835,
"preview": "#\n# Copyright (C) 2024 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "ui/PreviewScreenshot/gradle.properties",
"chars": 2086,
"preview": "#\n# Copyright (C) 2024 The Android Open Source Project\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "ui/PreviewScreenshot/gradlew",
"chars": 5769,
"preview": "#!/usr/bin/env sh\n\n#\n# Copyright (C) 2024 The Android Open Source Project\n#\n# Licensed under the Apache License, Version"
},
{
"path": "ui/PreviewScreenshot/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "ui/PreviewScreenshot/settings.gradle.kts",
"chars": 1186,
"preview": "/*\n * Copyright (C) 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/espresso/AccessibilitySample/.gitignore",
"chars": 53,
"preview": ".gradle\nlocal.properties\n.idea\n.DS_Store\nbuild\n*.iml\n"
},
{
"path": "ui/espresso/AccessibilitySample/BUILD.bazel",
"chars": 2285,
"preview": "licenses([\"notice\"]) # Apache 2.0\n\nload(\"//:common_defs.bzl\", \"minSdkVersion\", \"targetSdkVersion\")\nload(\"@rules_jvm_ext"
},
{
"path": "ui/espresso/AccessibilitySample/README.md",
"chars": 1531,
"preview": "# Basic sample for Espresso\n\n*If you are new to Espresso, try this sample first.*\n\nThis project uses the Gradle build sy"
},
{
"path": "ui/espresso/AccessibilitySample/app/build.gradle",
"chars": 2473,
"preview": "apply plugin: \"com.android.application\"\n\nandroid {\n compileSdk 34\n defaultConfig {\n applicationId \"com.exam"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/androidTest/AndroidManifest.xml",
"chars": 1104,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2018 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/AccessibilitySample/app/src/androidTest/java/com/example/android/testing/espresso/AccessibilitySample/AccessibilityChecksTest.java",
"chars": 1541,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/AndroidManifest.xml",
"chars": 1314,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2015 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/AppManifest.xml",
"chars": 875,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2018 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/java/com/example/android/testing/espresso/AccessibilitySample/MainActivity.java",
"chars": 1629,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/layout/activity_main.xml",
"chars": 1854,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values/dimens.xml",
"chars": 873,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values/strings.xml",
"chars": 880,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2019 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values/styles.xml",
"chars": 792,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values-v13/styles.xml",
"chars": 760,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values-v21/styles.xml",
"chars": 759,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 1031,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/AccessibilitySample/build.gradle",
"chars": 962,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "ui/espresso/AccessibilitySample/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "ui/espresso/AccessibilitySample/gradle.properties",
"chars": 994,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "ui/espresso/AccessibilitySample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/espresso/AccessibilitySample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "ui/espresso/AccessibilitySample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "ui/espresso/BasicSample/.gitignore",
"chars": 53,
"preview": ".gradle\nlocal.properties\n.idea\n.DS_Store\nbuild\n*.iml\n"
},
{
"path": "ui/espresso/BasicSample/BUILD.bazel",
"chars": 1778,
"preview": "licenses([\"notice\"]) # Apache 2.0\n\nload(\"//:common_defs.bzl\", \"minSdkVersion\", \"targetSdkVersion\")\nload(\"@rules_jvm_ext"
},
{
"path": "ui/espresso/BasicSample/README.md",
"chars": 1531,
"preview": "# Basic sample for Espresso\n\n*If you are new to Espresso, try this sample first.*\n\nThis project uses the Gradle build sy"
},
{
"path": "ui/espresso/BasicSample/app/build.gradle",
"chars": 2750,
"preview": "apply plugin: \"com.android.application\"\n\napply plugin: \"kotlin-android\"\n\nandroid {\n compileSdk 34\n defaultConfig {"
},
{
"path": "ui/espresso/BasicSample/app/src/androidTest/AndroidManifest.xml",
"chars": 1088,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2018 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/BasicSample/app/src/androidTest/java/com/example/android/testing/espresso/BasicSample/ChangeTextBehaviorKtTest.kt",
"chars": 3066,
"preview": "/*\n * Copyright 2018, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/BasicSample/app/src/androidTest/java/com/example/android/testing/espresso/BasicSample/ChangeTextBehaviorTest.java",
"chars": 3165,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/BasicSample/app/src/main/AndroidManifest.xml",
"chars": 1407,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2015 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/BasicSample/app/src/main/AppManifest.xml",
"chars": 867,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n~ Copyright (C) 2018 The Android Open Source Project\n~\n~ Licensed under the "
},
{
"path": "ui/espresso/BasicSample/app/src/main/java/com/example/android/testing/espresso/BasicSample/MainActivity.java",
"chars": 2642,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/BasicSample/app/src/main/java/com/example/android/testing/espresso/BasicSample/ShowTextActivity.java",
"chars": 2179,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/layout/activity_main.xml",
"chars": 2449,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/layout/activity_show_text.xml",
"chars": 1206,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values/dimens.xml",
"chars": 873,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values/strings.xml",
"chars": 1012,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values/styles.xml",
"chars": 792,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values-v13/styles.xml",
"chars": 760,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values-v21/styles.xml",
"chars": 759,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 1031,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n ~ Copyright (C) 2015 The Android Open Source Project\n ~\n ~ Licensed unde"
},
{
"path": "ui/espresso/BasicSample/app/src/test/java/com/example/android/testing/espresso/BasicSample/ChangeTextBehaviorLocalTest.java",
"chars": 2500,
"preview": "package com.example.android.testing.espresso.BasicSample;\n\n\nimport static androidx.test.espresso.Espresso.onView;\nimport"
},
{
"path": "ui/espresso/BasicSample/build.gradle",
"chars": 962,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "ui/espresso/BasicSample/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "ui/espresso/BasicSample/gradle.properties",
"chars": 993,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "ui/espresso/BasicSample/gradlew",
"chars": 8047,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "ui/espresso/BasicSample/gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "ui/espresso/BasicSample/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "ui/espresso/CustomMatcherSample/.gitignore",
"chars": 53,
"preview": ".gradle\nlocal.properties\n.idea\n.DS_Store\nbuild\n*.iml\n"
},
{
"path": "ui/espresso/CustomMatcherSample/BUILD.bazel",
"chars": 2070,
"preview": "load(\"@rules_jvm_external//:defs.bzl\", \"artifact\")\nload(\"//:common_defs.bzl\", \"minSdkVersion\", \"targetSdkVersion\")\n\nlice"
},
{
"path": "ui/espresso/CustomMatcherSample/README.md",
"chars": 1479,
"preview": "# Custom matchers sample for Espresso\n\n*Extending Espresso is easy! This sample shows how to match the \"hint\" property o"
},
{
"path": "ui/espresso/CustomMatcherSample/app/build.gradle",
"chars": 2675,
"preview": "apply plugin: \"com.android.application\"\n\nandroid {\n compileSdk 34\n defaultConfig {\n applicationId \"com.exam"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/androidTest/AndroidManifest.xml",
"chars": 497,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/AndroidManifest.xml",
"chars": 729,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <appli"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/AppManifest.xml",
"chars": 274,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n pa"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/java/com/example/android/testing/espresso/CustomMatcherSample/MainActivity.java",
"chars": 3142,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/drawable/correct.xml",
"chars": 1147,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/drawable/incorrect.xml",
"chars": 1147,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/layout/activity_main.xml",
"chars": 2981,
"preview": "<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values/dimens.xml",
"chars": 842,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values/strings.xml",
"chars": 1072,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values/styles.xml",
"chars": 753,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values-v13/styles.xml",
"chars": 787,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values-v21/styles.xml",
"chars": 735,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/main/res/values-w820dp/dimens.xml",
"chars": 950,
"preview": "<!--\n Copyright 2015, The Android Open Source Project\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/sharedTest/java/com/example/android/testing/espresso/CustomMatcherSample/HintMatcher.java",
"chars": 1881,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/CustomMatcherSample/app/src/sharedTest/java/com/example/android/testing/espresso/CustomMatcherSample/HintMatchersTest.java",
"chars": 5817,
"preview": "/*\n * Copyright 2015, The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "ui/espresso/CustomMatcherSample/build.gradle",
"chars": 849,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
}
]
// ... and 377 more files (download for full content)
About this extraction
This page contains the full source code of the android/testing-samples GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 577 files (923.0 KB), approximately 252.8k tokens, and a symbol index with 332 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.