Learn about unit, integration, system, and acceptance testing in Android development. Setup testing configurations in Android Studio. Understand the differences between test and androidTest directories and how to create test classes effectively.
Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation
Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement.Téléchargez la présentation en cliquant sur ce lien.Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.
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
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
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
Setup Configurations • STEP 1:Run->Edit Configurations • STEP 2: Hit + in Config window and add Android Tests
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.
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
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
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
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.
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
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
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
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
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
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*****}
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*****}
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' } } }
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"}
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.
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
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; }}
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); }}
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); }}
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)); }
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
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)
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.
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.
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>
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"));}}
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
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.
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
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
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 .
Connexion au compte
Connectez-vous pour publier votre contenu sur SlideServe.