Presentation is loading. Please wait.

Presentation is loading. Please wait.

Android – tESTING L. Grewe.

Similar presentations


Presentation on theme: "Android – tESTING L. Grewe."— Presentation transcript:

1 Android – tESTING L. Grewe

2 Testing and Software Development
Testing an important “step” in SW development

3 Testing Strategy in General
Start with Unit Test and end with System Tests

4 Another view of testing strategies
For each “level” of design we have a corresponding “kind” of testing that can exercise/test the fulfillment of the design in the code

5 Some Terms B C A Unit Testing: D E Integration Testing:
Units/Modules showing connectivity Unit Testing: Testing a module by itself. Just test A alone or E along Integration Testing: tests groups of modules that have passed unit testing. Test A,B then A, C and so on System Testing: Full integration testing, testing of complete system Acceptance Testing: process of testing system in its real environment with real data

6 What kind of testing are we covering???
Unit Testing Which is good because that is most of the testing you may do (see recommendation 70%) and it is the first kind of testing to do

7 Setting up for Unit Testing
With Android Studio

8 Setup Configurations STEP 1:Run->Edit Configurations
STEP 2: Hit + in Config window and add Android Tests

9 Setup continued All test methods MUST start with the “test-” prefix or Android Studio will not detect them as tests and you will get all kinds of weird errors and nothing will work. Step 3: Now configure Testing configuration to point to the module of your app select“All in Module” and Android Studio will automatically find any test inside your whole Module!  You can also get more specific and select “Class” or even “Method” option to narrow the scope of your testing down further.

10 Setup finished Step 4: after saving config in Step 3 you can see it is an option for running (now we have the app itself and the testing classes)  NEXT how do we make the testing code

11 When you create Project –you have testing directories (test and androidTest)
Look at this example for a simple HelloApp app Have androidTest and test

12 JVM = java/test Android= androidTest/
2 kinds of Unit Tests- JVM run (plain old jUnit) and Android Run (Instrumentation) JVM = java/test Android= androidTest/

13 Stop ---why 2 test directories???
2 kinds of Unit Testing in Android: androidTest/java & Tests Stop ---why 2 test directories??? androidTest/java: Used for Android classes test/java: Used for Plain Old Java classes –that have no Android code in them

14 test/java Tests Run on computer’s JVM
To allow running Android unit tests on the JVM, the Android Gradle plug-in creates a special version of the android.jar (also known as the Android mockable jar). test/java Tests Run on computer’s JVM Use these tests to minimize execution time when your tests have no Android framework dependencies or when you can mock the Android framework dependencies

15 androidTest/java Tests
Called androidTest or instrumentation Testing –as run on “instrument” emulator or hardware device androidTest/java Tests Run on Android emulator/hardware device Use these tests when writing integration and functional UI tests to automate user interaction, or when your tests have Android dependencies that mock objects cannot satisfy.

16 androidTest or test??? androidTest = when need calls to Android system
If classes do not call the Android API  you can use the JUnit test framework without any restrictions. If you have dependencies to the Android API  these dependencies in your code must be replaced for the unit tests via a mocking framework like Mockito.  androidTest or test??? test = when not making calls to Android system need to test androidTest = when need calls to Android system

17 An Example: androidTest or test???
Assume a button in an Android activity is used to start another activity. (test/java) test = would determine, if the corresponding intent was issued, not if the second activity was started (androidTest/java) test = would be able to see if intent was issued AND if second activity started

18 Creating A Testing Class
Setting up in Android Studio

19 Steps to generate a Test Class
Step1: Open up the class you want to create a test class for Step 2: select name of class and hit “Cntrl-Shift-T” and a pop-up will ask you to make a new test class

20 Steps to generate a Test Class
Step 3: change name (if desire) of test class, select methods you wish to create test cases for Step3 : ALSO choose the directory test OR androidTest NOTE: there are different Testing Libraries the Android Studio will support and generate…we are using JUnit4 Choose which directory test = runs on JVM androidTest =runs on android

21 Steps to generate a Test Class
Step 4: you will see the new Test Class in the directory you specified We choose to put it in the androidTest –so will run on Android instead of local JVM

22 Steps to generate a Test Class
Step 5: setup the appropriate Gradle Dependencies in your project so it knows about (in our case Junit 4) the testing library you choose in step 3 Your application’s Build Dependencies (  build.gradle file) should include: IMPORTANT: depending on whether your test cases are in androitTest/java or test/java you will only need the corresponding dependency line (androidTestCompile or testCompile)  THIS for JVM test/java tests dependencies {     // Required for local unit tests (JUnit 4 framework)     testCompile 'junit:junit:4.12‘     // whatever else you have***** }

23 Steps to generate a Test Class
Step 5: showing for Instrumentation test (androidTest/java): IMPORTANT:  This for androidTest/java tests dependencies {     // Required for instrumented tests androidTestCompile 'junit:junit:4.12‘     androidTestCompile 'com.android.support:support-annotations:24.0.0'     androidTestCompile 'com.android.support.test:runner:0.5‘     androidTestCompile 'com.android.support.test:rules:0.5'     // Optional -- Hamcrest library     androidTestCompile 'org.hamcrest:hamcrest-library:1.3'     // Optional -- UI testing with Espresso     androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'     // Optional -- UI testing with UI Automator     androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'     // whatever else you have***** }

24 SPECIAL NOTE: Steps to generate a Test Class
Step 6: if you get an error about the project version and test version not matching  SOLUTION: add the following to build gradle file ERROR looks like This: Error:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (24.2.1) and test app (24.0.0) differ. See for details. android {        // whatever else you have***** configurations.all { resolutionStrategy { force 'com.android.support:support-annotations:23.1.1' } } }

25 SPECIAL NOTE: For androidTest/java tests you need to also add this
Step 5 (only if androidTest instrumentation test) : add the following to your application’s Build defaultConfig(  build.gradle file) should include: defaultConfig {     // whatever else you have********** testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" }

26 JVM Based Unit Tests---test/java
Unit testing on JVM

27 First learn coding for JVM based Unit testing
---this is the test case that will appear in test/java

28 Writing Test classes - Based on JUnit
use plain JUnit to test a class that doesn't call the Android API, JUnit TestCase class to do unit testing on a class that doesn't call Android APIs. Use Android's JUnit extensions to test Android components. Android JUnit extensions provide component-specific test case classes. provide helper methods for creating mock objects and methods that help you control the lifecycle of a component.

29 Testing PLO (plain old java object)
Plain Old Java Objects (i.e. independent of frameworks like Android or J2EE) Test using assert*** = assertTrue, assertEquals to see if value is true or equals some value. import com.android.lab4.Joke; //this is the class we are testing import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; import org.junit.Test; public class JokeTest extends TestCase { @Test public void testJoke() { Joke joke = new Joke(); assertTrue("m_strJoke should be initialized to \"\".", joke.getJoke().equals("")); assertTrue("m_strAuthorName should be initialized to \"\".", joke.getAuthor().equals("")); assertEquals("m_nRating should be initialized to Joke.UNRATED.", Joke.UNRATED, joke.getRating()); } This is a class that can go in test/java directory and run on JVM

30 Using Junit (in test/java) Test
NumberManipulationFunctionsTest TEST Class: package computervision.grewe.helloapp; import org.junit.Test; import static org.junit.Assert.*; /** * Created by Lynne on 9/26/ */ public class NumberManipulationFunctionsTest { @Test public void testNumberMars() throws Exception { int value = 3; int expected = value*value; assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Test public void testNumberOcean() throws Exception { int value = 3; int expected = value/20; assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), ); } } NumberManimulationFunction Class: package computervision.grewe.helloapp; /** * Various Silly static methods for doing number manipulations * Created by Lynne on 9/26/ */ public class NumberManipulationFunctions { /** * silly calculate number on Mars as n^2 n */ public static int numberMars(int n){ return n*n; } /** * silly calculate number in Ocean n */ public static float numberOcean(int n){ return ((float) n) / 20.0f; } }

31 Running previous Test Class Results
As expected it passes NumberManipulationFunctionsTest TEST Class: package computervision.grewe.helloapp; import org.junit.Test; import static org.junit.Assert.*; public class NumberManipulationFunctionsTest { @Test public void testNumberMars() throws Exception { int value = 3; int expected = value*value; assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Test public void testNumberOcean() throws Exception { int value = 3; int expected = value/20; assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), ); } }

32 Change the code so should Fail and Run it again
As expected it FAILS NumberManipulationFunctionsTest TEST Class: package computervision.grewe.helloapp; import org.junit.Test; import static org.junit.Assert.*; public class NumberManipulationFunctionsTest { @Test public void testNumberMars() throws Exception { int value = 3; int expected = value; assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Test public void testNumberOcean() throws Exception { int value = 3; int expected = value/10; assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), ); } }

33 Examing the Values for testNumberMars when Fails
NumberManipulationFunctionsTest TEST Class: package computervision.grewe.helloapp; import org.junit.Test; import static org.junit.Assert.*; public class NumberManipulationFunctionsTest { @Test public void testNumberMars() throws Exception { int value = 3; int expected = value; assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } See values to understand why failed

34 Instrumentation Tests ---androidTest/java
Integration testing

35 NOW lets learn about coding for Instrumentation based Unit testing
---this is the test case that will appear in abdroidTest/java

36 WARNING: We don’t have the time to learn really how to do the more complex Instrumentation Testing But, this will be a start Learning some of the pieces of Instrumentation testing but, not all

37 AndroidTest: instrumentation tests on Android
hooks into the Android component and application life cycle. called the instrumentation API and allow your tests to control the life cycle and user interaction events. Run on emulator OR Android device (not local JVM like previous Junit cases)

38 Instrumentation Tests use
 InstrumentationTestRunner  is the base test runner for Android tests. This test runner starts and loads the test methods. MonkeyRunner: A tool that provides APIs for writing program which control an Android device or emulator outside of Android code.

39 There are multiple options to Instrumentation test writing
OPTION 1: use ActivityRule (newest) OPTION 2: AndroidTestCase (deprecated API 24) ALSO: various packages Mock, Espresso, etc. – not covered e

40 OPTION 1: ActivityRule android.support.test.rule.ActivityTestRule<T extends android.app.Activity> This rule provides functional testing of a single activity. The activity under test will be launched before each test annotated with Test and before methods annotated with Before. It will be terminated after the test is completed and methods annotated with After are finished. During the duration of the test you will be able to manipulate your Activity directly.

41 Example- MainActivity
MainActivity.java LAYOUT FILE public class MainActivity extends AppCompatActivity implements View.OnClickListener { int hits = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button b = (Button) this.findViewById(R.id.button_DO_IT); // register listener for button b.setOnClickListener(this); } //method invoked when button is hit public void onClick(View v) { // do something when the button is clicked  this.hits++; TextView text = (TextView)findViewById(R.id.textView_Message); String s = "You hit me " + this.hits; text.setText(s); } } <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="computervision.grewe.helloapp.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hit Button" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Do It" android:layout_alignParentStart="true" android:layout_marginTop="87dp" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:text="enter name here" /> </RelativeLayout>

42 Example using ActiveRule
import org.junit.Test; import static org.junit.Assert.*; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; import org.junit.Rule; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.matcher.ViewMatchers.withId; /** * Created by Lynne on 10/3/ */ @RunWith(AndroidJUnit4.class) @LargeTest public class MainActivityTest2 { @Rule public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class); Testing UI of Activity – runs and types “SAMPLE” into the editText /** test the Activities UI by typing into the editText_Input text field */ @Test public void testUI_writeTo_editTest_Input() { onView(withId(R.id.editText_Input)).perform(typeText("SAMPLE")); } }

43 NOW want you (< api 24) use ApplicationTestCase
---now use ApplicationTestCase

44 OPTION 2 AndroidTestCase class
DEPRICATED in API 24 OPTION 2 AndroidTestCase class void assertActivityRequiresPermission(String packageName, String className, String permission)Asserts that launching a given activity is protected by a particular permission by attempting to start the activity and validating that a SecurityException is thrown that mentions the permission in its error message. assertReadingContentUriRequiresPermission(Uri uri, String permission)Asserts that reading from the content uri requires a particular permission by querying the uri and ensuring a SecurityException is thrown mentioning the particular permission. assertWritingContentUriRequiresPermission(Uri uri, String permission)Asserts that writing to the content uri requires a particular permission by inserting into the uri and ensuring a SecurityException is thrown mentioning the particular permission. Context getContext() setContext(Context context) testAndroidTestCaseSetupProperly() setup() and teardown()  extends TestCase and Assert, which you can use to test Android-dependent objects. AndroidTestCase offers Android-specific setup, teardown, and helper methods. testing permissions

45 ApplicationTest class
 ApplicationTestCase  test case class to test the setup and teardown of Application objects. can be useful in verifying that the <application> element in the manifest file is correctly set up. Note, however, that this test case does not allow you to control testing of the components within your application package.

46 Notice the Android Studio setups an ApplcationTest class for you

47 Many other classes in android.test
InstrumentationClass ActivityUnitTestCase ActivityInstrumentaitonTestCase* LOOK AT METHODS……read Android guide to testing online oid.html Testing Activities ---read this

48 What would some real test code look like…suppose you have Activity with Spinner
public class myActivityTest extends ActivityInstrumentationTestCase2 { public void test() throws Exception { // Start the main activity of the application under test—gets this from parent class mActivity = getActivity(); // Get a handle to the Activity object's main UI widget, a Spinner mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); // Set the Spinner to a known position mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); // Stop the activity - The onDestroy() method should save the state of the Spinner mActivity.finish(); // Re-start the Activity - the onResume() method should restore the state of the Spinner mActivity = getActivity(); // Get the Spinner's current position int currentPosition = mActivity.getSpinnerPosition(); // Assert that the current position is the same as the starting position assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); All test methods MUST start with the “test-” prefix or Android Studio will not detect them as tests and you will get all kinds of weird errors and nothing will work. How does this connect to the actual Activity class you want to test THROUGH the constructor public ActivityInstrumentationTestCase2 (Class<T> activityClass) where the parameter is the class you want to test

49 Running Tests In Android Studio

50 Running tests Simply run the config you setup earlier (see start of talk) OTHER OPTIONS: OPTION 2: in the Project window, right-click a test and click Run . OPTION 3: In the Code Editor, right-click a class or method in the test file and click Run  to test all methods in the class. OPTION 4: To run all tests, right-click on the test directory and click Run tests .

51 More on your own Other apis part of android.test More Tools
Testing UIs Testing Services Testing ContentProviders More Tools integrating test frameworks such as Mockito to test Android API calls in your local unit tests, Espresso or UI Automator to exercise user interaction in your instrumented tests. You can generate Espresso tests automatically usingEspresso Test Recorder. See


Download ppt "Android – tESTING L. Grewe."

Similar presentations


Ads by Google