1 / 51

Android – tESTING

Android – tESTING. L. Grewe. Testing and Software Development. Testing an important “step” in SW development. Testing Strategy in General. Start with Unit Test and end with System Tests. Another view of testing strategies.

ghalls
Download Presentation

Android – tESTING

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 • 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 Units/Modules showing connectivity B C A D E

  6. What kind of testing are we covering??? Unit Testing Which is good because that ismost of the testing you may do (see recommendation 70%) and it isthe 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 Studiowill automaticallyfind any test insideyour whole Module! You can also get morespecific 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. 2 kinds of Unit Tests- JVM run (plain old jUnit) and Android Run (Instrumentation) JVM = java/test Android= androidTest/

  13. 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. 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. 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. 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 directorytest OR androidTest NOTE: there are different TestingLibraries the Android Studio willsupport and generate…we are usingJUnit4 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.gradlefile) should include: IMPORTANT: depending on whether yourtest cases are in androitTest/java or test/javayou 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: addthe following tobuild 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 http://g.co/androidstudio/app-test-app-conflict 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.gradlefile) 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 TestCaseclass 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/javadirectory 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/2016. */public class NumberManipulationFunctionsTest { @Testpublic void testNumberMars() throws Exception {int value = 3;int expected = value*value;assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Testpublic void testNumberOcean() throws Exception {int value = 3;int expected = value/20;assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), 0.000001); }} NumberManimulationFunction Class: package computervision.grewe.helloapp;/** * Various Silly static methods for doing number manipulations * Created by Lynne on 9/26/2016. */public class NumberManipulationFunctions {/** * silly calculate number on Mars as n^2 * @param n* @return*/public static intnumberMars(intn){return n*n; }/** * silly calculate number in Ocean * @param n* @return*/public static float numberOcean(intn){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 { @Testpublic void testNumberMars() throws Exception {int value = 3;int expected = value*value;assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Testpublic void testNumberOcean() throws Exception {int value = 3;int expected = value/20;assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), 0.000001); }}

  32. Change the code so shouldFail 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 { @Testpublic void testNumberMars() throws Exception {int value = 3;int expected = value;assertEquals("Conversion to Mars number failed", expected, NumberManipulationFunctions.numberMars(value)); } @Testpublic void testNumberOcean() throws Exception {int value = 3;int expected = value/10;assertEquals("Conversion to Ocean number failed", expected, NumberManipulationFunctions.numberOcean(value), 0.000001); }}

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

  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 thepieces of Instrumentationtesting but, notall

  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

  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; @Overrideprotected 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 buttonb.setOnClickListener(this); }//method invoked when button is hitpublic 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"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="computervision.grewe.helloapp.MainActivity"> <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hit Button"android:id="@+id/textView_Message" /> <Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Do It"android:id="@+id/button_DO_IT"android:layout_below="@+id/textView_Message"android:layout_alignParentStart="true"android:layout_marginTop="87dp" /> <EditTextandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/editText_Input"android:layout_below="@+id/textView_Message"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/2016. */@RunWith(AndroidJUnit4.class)@LargeTestpublic class MainActivityTest2 { @Rulepublic ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class); Testing UI of Activity – runs andtypes “SAMPLE” into the editText /** test the Activities UI by typing into the editText_Input text field */@Testpublic 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. DEPRICATED in API 24 OPTION 2 AndroidTestCase class • http://developer.android.com/reference/android/test/AndroidTestCase.html •  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 • http://developer.android.com/tools/testing/testing_android.html • Testing Activities ---read this http://developer.android.com/tools/testing/activity_testing.html

  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 positionassertEquals(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 theactual 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 .

More Related