본문

170802(수) - Building Instrumented Unit Tests

Building Instrumented Unit Tests


Instrumented unit test

- run on physical devices and emulators

- instrumentation information (ex. Context)나 real implementation of an Android framework component(ex. Parcelable or SharedPreference Object)에 접근하려면 instrumented unit test를 작성해야 한다.


- reduce the effort required to write and maintain mock code

- 원한다면 mock framework를 이용해서 dependency relationships를 simulate 가능하다.



Set up testing environment

- module-name/src/androidTest/java/.

- should download the Android Testing Support Library setup.

- Testing Support Library include a JUnit 4 test runner (AndroidJUnitRunner) & APIs for UI tests (Espresso and UI Automator)

- simplify한 test를 위해서 Hamcrest library도 포함시켜야 한다.


dependencies {
    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'
}

- support-annotation과 espresso-core library가 충돌한다면, 아래와 같이 수정

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude
group: 'com.android.support', module: 'support-annotations'
})

- JUnit 4 test classes를 사용하기 위해서 AndroidJUnitunner를 default test instrumentation runner로 지정해야 한다.

android {
    defaultConfig
{
        testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
   
}
}


Create an instrumented unit test class

- instrumented unit test class는 JUnit 4 test class로 written 되어야 한다.

- test class definition에 @RunWith(AndroidJUnit4.class) annotation을 add

AndroidJUnitRunner class를 default test runner로 지정해야 한다.


- class가 LogHistory에 의해서 correctly implemented되었는지에 대한 test ex)

import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class LogHistoryAndroidUnitTest {

   
public static final String TEST_STRING = "This is a string";
   
public static final long TEST_LONG = 12345678L;
   
private LogHistory mLogHistory;

   
@Before
   
public void createLogHistory() {
        mLogHistory
= new LogHistory();
   
}

   
@Test
   
public void logHistory_ParcelableWriteRead() {
       
// Set up the Parcelable object to send and receive.
        mLogHistory
.addEntry(TEST_STRING, TEST_LONG);

       
// Write the data.
       
Parcel parcel = Parcel.obtain();
        mLogHistory
.writeToParcel(parcel, mLogHistory.describeContents());

       
// After you're done with writing, you need to reset the parcel for reading.
        parcel
.setDataPosition(0);

       
// Read the data.
       
LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
       
List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData();

       
// Verify that the received data is correct.
        assertThat
(createdFromParcelData.size(), is(1));
        assertThat
(createdFromParcelData.get(0).first, is(TEST_STRING));
        assertThat
(createdFromParcelData.get(0).second, is(TEST_LONG));
   
}
}


Create a test suite

- instrumented unit test를 organize 한다.

- nested가능하며 group을 한꺼번에 실행 가능


- application package와 비슷한 test package에 들어있다.

- test suite package name은 suffix에 .suite가 붙는다.

- ex) com.example.android.testing.mysample.suite

 Suite

import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
import com.example.android.testing.mysample.CalculatorInstrumentationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

// Runs all unit tests.
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorInstrumentationTest.class,
       
CalculatorAddParameterizedTest.class})
public class UnitTestSuite {}


Run instrumented unit tests

1. synchronized with Gradle

2. run test

- single test

project window and then right-click test and click Run.


- test all method test

right-click a class or method test file and click Run.


- run all tests in a directory

right-click on the directory and select Run.


- test는 APK가 모두 설치된 이후에 실행된다.

- instrumented tests나 debug중에는 Instant Run은 기능 해제



Run your tests with Firebase Test Lab

- you can simultaneously many popular Android devices and device configurations (locale, orientation, screen, size, and platform version)


- remote Google data centers

- deploy android studio or command line

- result provide test logs and details app failures.

- need Google account and enroll Firebase project.



Configure a test matrix and run a test

1. Run > Edit Configurations

2. Add New Configuration and select Android Tests

3. dialog

- test name etc. details of test enter or select

- Deployment Target Options의 Target drop down 메뉴에서 Firebase Lab Device Matrix 선택

- Connect to Google Cloud platform

- Cloud project 옆의 button을 클릭하고 목록에서 Firebase project를 선택


4. Create and configure a test matrix

- Matrix configuration drop-down list, click open dialog

- Add New Configuration

- Name field, enter new name.

- select device, android version, locale, screen orientation etc enter informations.

- click Ok to save.


5. click Ok button, Run/Debug configuration dialog.

6. Run!





more about Analyze Firebase Test Lab for Android Results.


※ 결과적으로, 좀 더 많은 옵션의 테스트를 하고싶으면 돈을 내야한다.


Additional Sample code

 Android ActivityInstrumentation Sample.

 Instrumented Unit Tests Code Samples

Unit and UI Testing in Android Studio Codelab

공유

댓글