Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.gradle
/local.properties
.idea
*.iml
.DS_Store
build
25 changes: 25 additions & 0 deletions runner/AndroidTestOrchestratorWithTestCoverageSample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 31
buildToolsVersion rootProject.buildToolsVersion
defaultConfig {
applicationId "com.example.android.testing.androidtestorchestratorsample"
minSdkVersion 14
targetSdkVersion 31
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'
}
}

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
androidTestUtil 'androidx.test:orchestrator:' + rootProject.runnerVersion
androidTestUtil 'androidx.test.services:test-services:' + rootProject.testServicesVersion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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 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.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
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, is(equalTo(mExpectedResult)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* 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)));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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"
package="com.example.android.testing.androidtestorchestratorsample" >

<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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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;
}
}
Loading