Skip to content

Commit 05f6714

Browse files
committed
testing tutorials
1 parent ee3324f commit 05f6714

File tree

11 files changed

+290
-5
lines changed

11 files changed

+290
-5
lines changed

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,40 @@ public class PassDataInActivityTest {
176176
}
177177
````
178178

179+
180+
#Tutorial 5
181+
Responding to external intents like gallery picks
182+
It's hard to control external apps as with device applications can have different views so it's not steady like your UI. in this condition what you can do is develop dependency injected code where you can mock the intents results or you can give result of intents in testing.
183+
184+
Let's check without DI(Dependency Injection)
185+
-----------------
186+
187+
For this you need to have espresso intents dependency in build.gradle file
188+
````
189+
androidTestCompile ('com.android.support.test.espresso:espresso-intents:2.2.2', {
190+
exclude group: 'com.android.support', module: 'support-annotations'
191+
})
192+
````
193+
194+
excludes are important to exclude support libraries inside the espresso and use libs what you have included.
195+
196+
Now after dependency added we can move on to the main course which is to mock the intent results.
197+
<br/>
198+
199+
2 things to keep in mind is <kbd>intending</kbd> and <kbd>intended</kbd>
200+
1. Intending
201+
It is used for specifying Espresso that when unit test wants to open this type of intent please respond with intended result which i'm giving you to give.
202+
</br>
203+
2. Intended
204+
It is used to check if the event intended to open some activity or package? we can check that thing by this.
205+
206+
```
207+
Intent resultData = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
208+
resultData.setData(Uri.parse(("content://media/external/images/media/162")));
209+
Matcher<Intent> MediaPickIntent = allOf(hasAction(Intent.ACTION_PICK), hasData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
210+
Intents.init();
211+
intending(MediaPickIntent).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));
212+
```
213+
214+
In above example we have action pick event matcher which gives espresso hint that i'm finding this intent and by initlizing the intent we are starting intent checks for every intents.
215+
while intending tells that when I intend to do respond with the intent i'm giving.

app/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ dependencies {
3333
compile 'com.android.support:appcompat-v7:25.1.0'
3434
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta1'
3535
testCompile 'junit:junit:4.12'
36+
compile 'com.github.bumptech.glide:glide:3.7.0'
3637
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.testingandroid.Tutorial5;
2+
3+
4+
import android.app.Activity;
5+
import android.app.Instrumentation;
6+
import android.content.Intent;
7+
import android.net.Uri;
8+
import android.support.test.espresso.intent.Intents;
9+
import android.support.test.rule.ActivityTestRule;
10+
import android.support.test.runner.AndroidJUnit4;
11+
12+
import com.testingandroid.login.LoginActivity;
13+
14+
import org.hamcrest.Matcher;
15+
import org.junit.Before;
16+
import org.junit.Rule;
17+
import org.junit.Test;
18+
import org.junit.runner.RunWith;
19+
20+
import java.io.File;
21+
22+
import static android.support.test.espresso.Espresso.onView;
23+
import static android.support.test.espresso.action.ViewActions.click;
24+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
25+
import static android.support.test.espresso.intent.Intents.intended;
26+
import static android.support.test.espresso.intent.Intents.intending;
27+
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
28+
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData;
29+
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
30+
import static android.support.test.espresso.matcher.ViewMatchers.withText;
31+
import static org.hamcrest.Matchers.allOf;
32+
33+
@RunWith(AndroidJUnit4.class)
34+
public class GalleryPickerTesting {
35+
36+
@Rule
37+
public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class,true);
38+
39+
40+
@Before
41+
public void initThingsHere() {
42+
//do stuff like database or preference or image copying here
43+
}
44+
45+
@Test
46+
public void checkTextOnScreen() {
47+
//to check view on screen
48+
49+
Intent resultData = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
50+
resultData.setData(Uri.parse(("content://media/external/images/media/162")));
51+
Matcher<Intent> MediaPickIntent = allOf(hasAction(Intent.ACTION_PICK), hasData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
52+
Intents.init();
53+
intending(MediaPickIntent).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));
54+
55+
onView(withText("Gallery")).perform(click());
56+
onView(withText("gallery pick")).perform(click());
57+
intended(MediaPickIntent);
58+
try{
59+
Thread.sleep(4500);
60+
} catch (InterruptedException e) {
61+
e.printStackTrace();
62+
}
63+
}
64+
65+
66+
}

app/src/main/AndroidManifest.xml

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.testingandroid">
44

5+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
6+
57
<application
68
android:allowBackup="true"
79
android:icon="@mipmap/ic_launcher"
@@ -16,6 +18,9 @@
1618
<category android:name="android.intent.category.LAUNCHER"/>
1719
</intent-filter>
1820
</activity>
21+
22+
<activity android:name=".login.ImageFromGalleryActivity">
23+
</activity>
1924
</application>
2025

2126
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.testingandroid.databindingadapter;
2+
3+
import android.databinding.ObservableField;
4+
import android.widget.ImageView;
5+
6+
import com.bumptech.glide.Glide;
7+
import com.testingandroid.R;
8+
9+
/**
10+
* Created by Parth Dave on 16/3/17.
11+
* Spaceo Technologies Pvt Ltd.
12+
* parthd.spaceo@gmail.com
13+
*/
14+
15+
public class DatabindingAdapter {
16+
17+
@android.databinding.BindingAdapter("custom:imageFromFile")
18+
public static <T> void viewImage(ImageView view, ObservableField<T> filePath) {
19+
Glide.with(view.getContext()).load("file://" + filePath.get()).placeholder(R.drawable.ic_user_vector).error(R.drawable.ic_user_vector).into(view);
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.testingandroid.login;
2+
3+
import android.content.Intent;
4+
import android.database.Cursor;
5+
import android.databinding.DataBindingUtil;
6+
import android.databinding.ObservableField;
7+
import android.net.Uri;
8+
import android.os.Bundle;
9+
import android.provider.MediaStore;
10+
import android.support.annotation.DrawableRes;
11+
import android.support.v7.app.AppCompatActivity;
12+
import android.view.View;
13+
import android.widget.EditText;
14+
15+
import com.testingandroid.R;
16+
import com.testingandroid.databinding.ActivityGallerypickBinding;
17+
import com.testingandroid.databinding.ActivityLoginBinding;
18+
import com.testingandroid.model.LoginModel;
19+
20+
import java.util.regex.Matcher;
21+
import java.util.regex.Pattern;
22+
23+
public class ImageFromGalleryActivity extends AppCompatActivity {
24+
private ActivityGallerypickBinding activityLoginBinding;
25+
public ObservableField<String> imagePath = new ObservableField<>();
26+
private final int RC_IMAGE_GALLARY = 89;
27+
28+
@Override
29+
protected void onCreate(Bundle savedInstanceState) {
30+
super.onCreate(savedInstanceState);
31+
activityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_gallerypick);
32+
activityLoginBinding.setImagePath(imagePath);
33+
}
34+
35+
public void onGalleryPickClick(View view) {
36+
Intent iGetAvatar = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
37+
startActivityForResult(iGetAvatar, RC_IMAGE_GALLARY);
38+
}
39+
40+
@Override
41+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
42+
super.onActivityResult(requestCode, resultCode, data);
43+
if(requestCode==RC_IMAGE_GALLARY && resultCode==RESULT_OK){
44+
if (data == null)
45+
return;
46+
Uri uri = data.getData();
47+
if(uri==null)
48+
return;
49+
imagePath.set(getRealPathFromURI(uri));
50+
}
51+
}
52+
53+
public String getRealPathFromURI (Uri contentUri) {
54+
String path = null;
55+
String[] proj = { MediaStore.MediaColumns.DATA };
56+
Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
57+
if (cursor.moveToFirst()) {
58+
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
59+
path = cursor.getString(column_index);
60+
}
61+
cursor.close();
62+
return path;
63+
}
64+
}

app/src/main/java/com/testingandroid/login/LoginActivity.java

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.testingandroid.login;
22

3+
import android.content.Intent;
34
import android.databinding.DataBindingUtil;
45
import android.databinding.ObservableField;
56
import android.support.annotation.DrawableRes;
@@ -79,4 +80,7 @@ public boolean noInternetConnection(){
7980
return false;
8081
}
8182

83+
public void onGalleryPickClick(View view){
84+
startActivity(new Intent(this,ImageFromGalleryActivity.class));
85+
}
8286
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<vector
2+
xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="22dp"
4+
android:height="22dp"
5+
android:alpha="1"
6+
android:viewportHeight="56"
7+
android:viewportWidth="56"
8+
>
9+
<path
10+
android:fillColor="#F07171"
11+
android:pathData="M26.953,0.004C12.32-0.246,0.254,11.414,0.004,26.047C-0.138,34.344,3.56,41.801,9.448,46.76
12+
c0.385-0.336,0.798-0.644,1.257-0.894l7.907-4.313c1.037-0.566,1.683-1.653,1.683-2.835v-3.24c0,0-2.321-2.776-3.206-6.633
13+
c-0.734-0.475-1.226-1.296-1.226-2.231v-3.546c0-0.78,0.347-1.477,0.886-1.965v-5.126c0,0-1.053-7.977,9.75-7.977
14+
s9.75,7.977,9.75,7.977v5.126c0.54,0.488,0.886,1.185,0.886,1.965v3.546c0,1.192-0.8,2.195-1.886,2.53
15+
c-0.605,1.881-1.478,3.674-2.632,5.304c-0.291,0.411-0.563,0.759-0.801,1.03V38.8c0,1.223,0.691,2.342,1.785,2.888l8.467,4.233
16+
c0.508,0.254,0.967,0.575,1.39,0.932c5.71-4.762,9.399-11.882,9.536-19.9C53.246,12.32,41.587,0.254,26.953,0.004z"
17+
android:strokeColor="#F07171"
18+
android:strokeLineCap="round"
19+
android:strokeLineJoin="round"
20+
android:strokeWidth="0.5"/>
21+
22+
<path
23+
android:fillColor="#FFFFFF"
24+
android:pathData="M18.613,41.552l-7.907,4.313c-0.464,0.253-0.881,0.564-1.269,0.903C14.047,50.655,19.998,53,26.5,53
25+
c6.454,0,12.367-2.31,16.964-6.144c-0.424-0.358-0.884-0.68-1.394-0.934l-8.467-4.233c-1.094-0.547-1.785-1.665-1.785-2.888v-3.322
26+
c0.238-0.271,0.51-0.619,0.801-1.03c1.154-1.63,2.027-3.423,2.632-5.304c1.086-0.335,1.886-1.338,1.886-2.53v-3.546
27+
c0-0.78-0.347-1.477-0.886-1.965v-5.126c0,0,1.053-7.977-9.75-7.977s-9.75,7.977-9.75,7.977v5.126
28+
c-0.54,0.488-0.886,1.185-0.886,1.965v3.546c0,0.934,0.491,1.756,1.226,2.231c0.886,3.857,3.206,6.633,3.206,6.633v3.24
29+
C20.296,39.899,19.65,40.986,18.613,41.552z"
30+
android:strokeColor="#F07171"
31+
android:strokeLineCap="round"
32+
android:strokeLineJoin="round"
33+
android:strokeWidth="0.5"/>
34+
35+
</vector>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:app="http://schemas.android.com/apk/res-auto"
5+
xmlns:custom="http://schemas.android.com/apk/res-auto"
6+
xmlns:tools="http://schemas.android.com/tools">
7+
8+
<data>
9+
10+
<variable
11+
name="imagePath"
12+
type="android.databinding.ObservableField"/>
13+
</data>
14+
15+
<LinearLayout
16+
android:id="@+id/clMainContainer"
17+
android:layout_width="match_parent"
18+
android:layout_height="match_parent"
19+
android:orientation="vertical">
20+
21+
<ImageView
22+
android:id="@+id/imageView"
23+
android:layout_width="match_parent"
24+
android:layout_height="0dp"
25+
android:layout_marginBottom="8dp"
26+
android:layout_weight="1"
27+
custom:imageFromFile="@{imagePath}"
28+
app:layout_constraintBottom_toBottomOf="parent"
29+
app:layout_constraintTop_toTopOf="parent"/>
30+
31+
<Button
32+
android:id="@+id/btnLoginButton"
33+
android:layout_width="130dp"
34+
android:layout_height="wrap_content"
35+
android:layout_gravity="center_horizontal"
36+
android:onClick="onGalleryPickClick"
37+
android:text="gallery pick"/>
38+
39+
</LinearLayout>
40+
</layout>

app/src/main/res/layout/activity_login.xml

+11
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,16 @@
6363
app:layout_constraintTop_toBottomOf="@+id/edPassword"
6464
tools:layout_editor_absoluteX="127dp"/>
6565

66+
67+
<Button
68+
android:id="@+id/btnGalleryButton"
69+
android:layout_width="130dp"
70+
android:layout_height="0dp"
71+
android:layout_marginTop="56dp"
72+
android:text="Gallery"
73+
android:onClick="onGalleryPickClick"
74+
app:layout_constraintTop_toBottomOf="@+id/edPassword"
75+
tools:layout_editor_absoluteX="127dp"/>
76+
6677
</android.support.constraint.ConstraintLayout>
6778
</layout>
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
22

33
package="com.testingwithdaggerinjections"
4-
>
5-
6-
<application android:allowBackup="true"
7-
android:label="@string/app_name"
8-
android:supportsRtl="true"
94
>
105

6+
<application
7+
android:allowBackup="true"
8+
android:label="@string/app_name"
9+
android:supportsRtl="true"
10+
>
11+
1112
</application>
1213

1314
</manifest>

0 commit comments

Comments
 (0)