Skip to content

Commit c0e572c

Browse files
authored
feat:UI Tests (#16)
* WIP: UI Tests * feat(test): instrumented testing of demo app behavior * fix(deps): Use consistent appcompat version * chore(gradle): Move deps to dependency.gradle
1 parent 7d29fe0 commit c0e572c

File tree

4 files changed

+195
-0
lines changed

4 files changed

+195
-0
lines changed

app/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ dependencies {
3232
implementation dependency_android.appcompat
3333
implementation dependency_android.design
3434
implementation dependency_android.constraint_layout
35+
36+
androidTestImplementation dependency_android.junit
37+
androidTestImplementation dependency_android.test_rules
38+
androidTestImplementation dependency_android.test_runner
39+
androidTestImplementation dependency_android.espresso
3540
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.algolia.instantsearch.voice.demo;
2+
3+
4+
import android.support.test.filters.LargeTest;
5+
import android.support.test.rule.ActivityTestRule;
6+
import android.support.test.runner.AndroidJUnit4;
7+
8+
import org.junit.Rule;
9+
import org.junit.Test;
10+
import org.junit.runner.RunWith;
11+
12+
import static android.support.test.espresso.Espresso.onView;
13+
import static android.support.test.espresso.action.ViewActions.click;
14+
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
15+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
16+
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
17+
import static android.support.test.espresso.matcher.ViewMatchers.withId;
18+
19+
/**
20+
* Tests the behavior of the application when no permission are set.
21+
* <b>Make sure that no permissions have been granted on the test device!</b>
22+
* If any, reset them with <code>adb shell pm reset-permissions com.algolia.instantsearch.voice.demo</code>
23+
* before running these tests.
24+
*/
25+
@RunWith(AndroidJUnit4.class)
26+
@LargeTest
27+
public class MainActivityNoPermissionTest {
28+
29+
@Rule
30+
public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class);
31+
32+
@Test
33+
public void clickPermissionButton_displaysPermissionOverlay() {
34+
// When clicking on the buttonPermission
35+
onView(withId(R.id.buttonPermission))
36+
.perform(click());
37+
38+
// the permission overlay should display
39+
onView(withId(R.id.voicePermission))
40+
.check(matches(isDisplayed()));
41+
// the input overlay should not
42+
onView(withId(R.id.voiceInput))
43+
.check(doesNotExist());
44+
}
45+
46+
@Test
47+
public void clickInputButton_displaysPermissionOverlay() {
48+
// When clicking on the buttonVoice
49+
onView(withId(R.id.buttonVoice))
50+
.perform(click());
51+
52+
// the permission overlay should display
53+
onView(withId(R.id.voicePermission))
54+
.check(matches(isDisplayed()));
55+
// the input overlay should not
56+
onView(withId(R.id.voiceInput))
57+
.check(doesNotExist());
58+
}
59+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package com.algolia.instantsearch.voice.demo;
2+
3+
4+
import android.Manifest;
5+
import android.support.test.espresso.EspressoException;
6+
import android.support.test.espresso.matcher.ViewMatchers;
7+
import android.support.test.filters.LargeTest;
8+
import android.support.test.rule.ActivityTestRule;
9+
import android.support.test.rule.GrantPermissionRule;
10+
import android.support.test.runner.AndroidJUnit4;
11+
12+
import org.junit.Rule;
13+
import org.junit.Test;
14+
import org.junit.runner.RunWith;
15+
16+
import static android.support.test.espresso.Espresso.onView;
17+
import static android.support.test.espresso.action.ViewActions.click;
18+
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
19+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
20+
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
21+
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
22+
import static android.support.test.espresso.matcher.ViewMatchers.withId;
23+
import static android.support.test.espresso.matcher.ViewMatchers.withText;
24+
import static junit.framework.TestCase.fail;
25+
26+
@RunWith(AndroidJUnit4.class)
27+
@LargeTest
28+
public class MainActivityWithPermissionTest {
29+
30+
@Rule
31+
public ActivityTestRule testRule = new ActivityTestRule<>(MainActivity.class);
32+
33+
@Rule
34+
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(Manifest.permission.RECORD_AUDIO);
35+
36+
@Test
37+
public void clickPermissionButton_displaysPermissionOverlay() {
38+
when_clickButtonPermission();
39+
40+
// the permission overlay should display
41+
onView(withId(R.id.voicePermission))
42+
.check(matches(isDisplayed()));
43+
// the input overlay should not
44+
onView(withId(R.id.voiceInput))
45+
.check(doesNotExist());
46+
}
47+
48+
@Test
49+
public void clickInputButton_displaysInputOverlay() {
50+
when_clickButtonVoice();
51+
52+
check_displaysInputOverlay();
53+
check_displaysListeningOrError();
54+
}
55+
56+
@Test
57+
public void clickInput_thenCancel_displaysError() {
58+
when_clickButtonVoice();
59+
60+
// Then clicking on the mic button
61+
onView(withId(R.id.microphone))
62+
.perform(click());
63+
64+
check_displaysError();
65+
}
66+
67+
//region Helpers
68+
private void when_clickButtonPermission() {
69+
// When clicking on the buttonPermission
70+
onView(withId(R.id.buttonPermission))
71+
.perform(click());
72+
}
73+
74+
private void when_clickButtonVoice() {
75+
// When clicking on the buttonVoice
76+
onView(withId(R.id.buttonVoice))
77+
.perform(click());
78+
}
79+
80+
private void check_displaysInputOverlay() {
81+
// the input overlay should display
82+
onView(withId(R.id.voiceInput))
83+
.check(matches(isDisplayed()));
84+
// the permission overlay should not
85+
onView(withId(R.id.voicePermission))
86+
.check(doesNotExist());
87+
}
88+
89+
private void check_displaysListening() {
90+
// listening should be displayed
91+
onView(withId(R.id.title))
92+
.check(matches(withText(R.string.input_title_listening)));
93+
onView(withId(R.id.subtitle))
94+
.check(matches(withText(R.string.input_subtitle_listening)));
95+
// No hint should be visible
96+
onView(withId(R.id.hint))
97+
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE)));
98+
}
99+
100+
private void check_displaysError() {
101+
// the error should be displayed
102+
onView(withId(R.id.title))
103+
.check(matches(withText(R.string.input_title_error)));
104+
onView(withId(R.id.subtitle))
105+
.check(matches(withText(R.string.input_subtitle_error)));
106+
107+
// And the button to be labeled try again
108+
onView(withId(R.id.hint))
109+
.check(matches(isDisplayed()))
110+
.check(matches(withText(R.string.input_hint_error)));
111+
}
112+
113+
private void check_displaysListeningOrError() {
114+
try {
115+
check_displaysListening();
116+
} catch (Exception e) {
117+
if (e instanceof EspressoException) {
118+
// Maybe we are on emulator -> no SpeechRecognizer?
119+
// in this case, we should see error displayed
120+
check_displaysError();
121+
} else fail(e.getMessage());
122+
}
123+
}
124+
//endregion
125+
}

dependency.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ ext.with {
1919
bintray = '1.8.4'
2020
maven = '2.1'
2121

22+
junit = '4.12'
23+
test = '1.0.2'
24+
2225
dependency_jvm = [
2326
kotlin_stdlib : "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlins",
2427
kotlin_test : "org.jetbrains.kotlin:kotlin-test:$kotlins",
@@ -29,5 +32,8 @@ ext.with {
2932
constraint_layout : "com.android.support.constraint:constraint-layout:$constraintLayout",
3033
espresso : "com.android.support.test.espresso:espresso-core:$espresso",
3134
design : "com.android.support:design:$design"
35+
junit : "junit:junit:$junit",
36+
test_rules : "com.android.support.test:rules:$test",
37+
test_runner : "com.android.support.test:runner:$test"
3238
]
3339
}

0 commit comments

Comments
 (0)