|
1 | 1 | # AndroidTestingTutorial |
2 | 2 | Getting started with Espresso Unit Testing |
| 3 | + |
| 4 | +#Why Testing? |
| 5 | +testing is the process of evaluation a software item to detect differences between given input and expected output. |
| 6 | + |
| 7 | +#Categories of Testing |
| 8 | +1. Black box testing |
| 9 | +2. White box testing<br> |
| 10 | +etc... others can be found <a href="http://www.softwaretestinghelp.com/types-of-software-testing/">here</a> |
| 11 | + |
| 12 | +#Black box testing |
| 13 | +Tests are based on requirements and functionality. |
| 14 | + |
| 15 | +#White box testing |
| 16 | +Tests are based on coverage of code statements, branches, paths, conditions. |
| 17 | + |
| 18 | +#TDD |
| 19 | +Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: requirements are turned into very specific test cases, then the software is improved to pass the new tests, only. |
| 20 | + |
| 21 | +#Android Testing Tools |
| 22 | +1. <a href="https://developer.android.com/training/testing/ui-testing/espresso-testing.html">Espresso by google team</a> |
| 23 | +2. <a href="http://robolectric.org/">Roboletric</a> |
| 24 | +3. <a href="https://appium.io/slate/en/tutorial/android.html?ruby#">Appium</a> |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +#Espresso |
| 29 | +Mainly focused on UI and Thread idealization, which helps the unit tests to run without worring about api response state |
| 30 | +It checks the threads and waits for ui thread to be idealize which is dismiss progress bar or any event which shows that activity is performing some event. |
| 31 | + |
| 32 | +#Why Espresso |
| 33 | +Other tools like Roboletric is also famous for testing android apps but it has it's own android jar which is our basic android kit classes. |
| 34 | +As google updates their support library often it's hard to keep in update for Roboletric. |
| 35 | +And to mock the android classes becomes hard with Roboletric. |
| 36 | +Check out link here <a href="http://blog.triona.de/development/java/selecting-the-appropriate-android-test-framework.html">Roboletric vs Espresso</a> for more details. |
| 37 | + |
| 38 | + Let's start with testing |
| 39 | +------------------------------------- |
| 40 | +Let's check how to write test so in Espresso we have |
| 41 | + |
| 42 | +```` |
| 43 | +@Rule |
| 44 | +public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true); |
| 45 | +```` |
| 46 | +Above test rule defines for which activity you'r going to write test class |
| 47 | +<br/> |
| 48 | +Now <kbd>new ActivityTestRule<>(LoginActivity.class, true);</kbd> if you do want to open activity which is not launcher activity then pass true in constructor else pass nothing for second parameter <kbd>new ActivityTestRule<>(LoginActivity.class);</kbd> |
| 49 | +<br/> |
| 50 | +There is multiple ways to open activity so do checkout <a href="https://developer.android.com/training/testing/ui-testing/espresso-testing.html">Espresso Doc</a>. |
| 51 | + |
| 52 | +```` |
| 53 | + |
| 54 | +@RunWith(AndroidJUnit4.class) |
| 55 | +public class PerfomClickAndCheckTextError { |
| 56 | + |
| 57 | + @Rule |
| 58 | + public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true); |
| 59 | + ....... |
| 60 | +} |
| 61 | +```` |
| 62 | + |
| 63 | +You need to define that your going to use junit4 test class to run with below test class. |
| 64 | +if your test case is large then mention <kbd>@LargeTest</kbd> above class |
| 65 | + |
| 66 | +Now before going any further with real test code other things to mention here is if we want to run some method before activity launches you can do it by specifying <kbd>@Before</kbd> annotation above your method. |
| 67 | + |
| 68 | +```` |
| 69 | + |
| 70 | +@RunWith(AndroidJUnit4.class) |
| 71 | +public class PerfomClickAndCheckTextError { |
| 72 | + |
| 73 | + @Rule |
| 74 | + public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class, true); |
| 75 | + |
| 76 | + //To get resources in testing |
| 77 | + Resources resources; |
| 78 | + |
| 79 | + @Before |
| 80 | + public void initThingsHere() { |
| 81 | + //do stuff like database or preference or image copying here |
| 82 | + resources = InstrumentationRegistry.getTargetContext().getResources(); |
| 83 | + } |
| 84 | +} |
| 85 | +```` |
| 86 | + |
| 87 | +Like above I had taken resources. |
| 88 | + |
| 89 | +#Tutorial 1 |
| 90 | +We have started programming with hello world! program and for testing we will do the same. Simple step check the text is on the screen. |
| 91 | +but before that let's check how to <kbd>find view</kbd> from the screen in Espresso |
| 92 | + |
| 93 | +To check there is 2 steps: |
| 94 | +1. find view on screen |
| 95 | +2. check if exists or displayed |
| 96 | +<br/> |
| 97 | + |
| 98 | +Find view on screen |
| 99 | +----------------------------------- |
| 100 | + |
| 101 | +<br/> |
| 102 | +As we have findViewById in android, so in background what android system will do is it will check for that id view from rootview and give it back, |
| 103 | +we have <kbd>onView()</kbd> but to find views we can use multiple methods not by just ids. |
| 104 | +we have <kbd>withId(), withText(), withTagKey()</kbd> etc. |
| 105 | + |
| 106 | +Check if exists or displayed |
| 107 | +------------------------------- |
| 108 | + |
| 109 | +</br> |
| 110 | +To check we have <kbd>check()</kbd> method in which we will give matcher which will conditionalize the view like if it displayed or not. |
| 111 | + |
| 112 | +So we have |
| 113 | +```` |
| 114 | +onView(withText("Hello Floks!")).check(matches(isDisplayed())); |
| 115 | +```` |
| 116 | + |
| 117 | +above code checked that screen has some textview having text Hello Floks! |
| 118 | + |
| 119 | + |
| 120 | +<br/> |
| 121 | +<br/> |
| 122 | + |
| 123 | +#Tutorial 2 |
| 124 | +Now that we have successed in finding view and performing checks we will move to step 2 which is perform events like typing and clicking. |
| 125 | +to click |
| 126 | +```` |
| 127 | +onView(withText("Login")).perform(click()); |
| 128 | +```` |
| 129 | +<br/> |
| 130 | +<br/> |
| 131 | + |
| 132 | +#Tutorial 3 |
| 133 | +Merge click and checks in one |
| 134 | +```` |
| 135 | + onView(withId(R.id.btnLoginButton)).perform(click()); |
| 136 | + onView(withId(R.id.edUsername)).check(matches(hasErrorText(resources.getString(R.string.msg_enter_valid_email)))); |
| 137 | +```` |
| 138 | +<br/> |
| 139 | +<br/> |
| 140 | + |
| 141 | +#Tutorial 4 |
| 142 | +open activity with data in bundle as it's important to pass data with activity |
| 143 | + |
| 144 | +you want to check activity with custom data |
| 145 | +so before writing test if |
| 146 | + |
| 147 | +```` |
| 148 | +@RunWith(AndroidJUnit4.class) |
| 149 | +public class PassDataInActivityTest { |
| 150 | + |
| 151 | + @Rule |
| 152 | + public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<LoginActivity>(LoginActivity.class, true) { |
| 153 | + @Override |
| 154 | + protected Intent getActivityIntent() { |
| 155 | + Log.d(PassDataInActivityTest.class.getCanonicalName(), "getActivityIntent() called"); |
| 156 | + Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); |
| 157 | + Intent intent = new Intent(targetContext, LoginActivity.class); |
| 158 | + intent.putExtra("testingcheck", true); |
| 159 | + return intent; |
| 160 | + } |
| 161 | + }; |
| 162 | + |
| 163 | + |
| 164 | + @Before |
| 165 | + public void initThingsHere() { |
| 166 | + //do stuff like database or preference or image copying here |
| 167 | + } |
| 168 | + |
| 169 | + @Test |
| 170 | + public void checkBlankEmailError() { |
| 171 | + //to check view on screen |
| 172 | + Bundle bundle = mActivityTestRule.getActivity().getIntent().getExtras(); |
| 173 | + assertThat(bundle.getBoolean("testingcheck"), is(true)); |
| 174 | + System.out.println("testingcheck:" + bundle.getBoolean("testingcheck")); |
| 175 | + } |
| 176 | +} |
| 177 | +```` |
| 178 | + |
0 commit comments