안 드 로 이 드 유닛 테스트 최 적 실천 상세 설명
충분 한 유닛 테스트 는 코드 품질 을 향상 시 키 는 가장 효과 적 인 수단 중 하나 이다.유닛 테스트 는 코드 의 테스트 가능성 에 심각하게 의존한다.본 고 는 주로 간단 한 DEMO 를 통 해 안 드 로 이 드 네 이 티 브 응용 에 대해 유닛 테스트 를 하 는 방법 을 보 여 주 는 동시에 예제 코드 는 MVP 모델 로 코드 의 가 독성 과 테스트 가능성 을 높 인 다.
간단 한 소개
Android 네 이 티 브 애플 리 케 이 션 개발 에는 로 컬 JVM 테스트 와 Instrumentation 테스트 두 가지 유닛 테스트 가 존재 합 니 다.본 고 는 로 컬 JVM 테스트 만 소개 합 니 다.
로 컬 jvm 단위 테스트
이런 방식 은 운행 속도 가 빠 르 고 운행 환경 에 대해 특별한 요구 가 없 으 며 자동화 테스트 를 편리 하 게 할 수 있 으 며 단원 테스트 에서 가장 선 호 하 는 방법 이다.
계측 테스트
Instrumentation 테스트 는 Android 환경 에서 실행 되 어야 하 며 시 뮬 레이 터 나 휴대 전화 등 실제 장치 일 수 있 습 니 다.이런 방식 은 운행 속도 가 느 리 고 안 드 로 이 드 운행 환경 에 심각하게 의존 하여 통합 테스트 에 더욱 적합 하 다.
준비 하 다.
저 는 간단 한 앱 을 준 비 했 습 니 다.시간 이 걸 리 는 네트워크 요청 을 모 의 하여 데 이 터 를 얻 고 인터페이스 에 표시 합 니 다.이 앱 에 대해 유닛 테스트 사례 를 작성 하고 로 컬 유닛 테스트 를 실시 합 니 다.
앱 실행 효과
의존 라 이브 러 리
의존 라 이브 러 리
역할.
JUnit-4.12
기초 유닛 테스트 프레임 워 크
Robolectric-3.8
Android SDK 테스트 프레임 워 크
PowerMock-1.6.6
테스트 대상 이 의존 하 는 정적 방법 을 모 의 합 니 다.
Mockito-1.10.19
테스트 대상 의존 대상 시 뮬 레이 션
build.gradle 설정
컴 파일 옵션 을 추가 하여 테스트 에 자원 파일 을 포함 합 니 다.
testOptions {
unitTests {
includeAndroidResources true
}
}
테스트 의존 라 이브 러 리 추가
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.8'
testImplementation 'org.robolectric:shadows-supportv4:3.8'
testImplementation 'org.powermock:powermock-module-junit4:1.6.6'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.6'
testImplementation 'org.powermock:powermock-api-mockito:1.6.6'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.6'
testImplementation 'org.mockito:mockito-all:1.10.19'
테스트 활동테스트 Activity 는 주로 각 라 이 프 사이클 의 상태 변화,외부 입력 에 대한 응답 이 기대 에 부합 하 는 지 테스트 하 는 것 입 니 다.Activity 테스트 는 완전히 Android SDK 에 의존 하기 때문에 Robolectric 을 사용 해 야 합 니 다.
Robolectric 은 Android SDK 를 완전히 모 의 하고 JVM 에서 실행 할 수 있 는 오픈 소스 유닛 테스트 프레임 워 크 입 니 다.
UI 는 Persenter 에 의존 합 니 다.Activity 에서 정적 공장 방법 으로 의존 하 는 Presenter 인 스 턴 스 를 만 들 려 면 PowerMock 을 사용 하여 Presenter 생 성 과정 을 모 의 하고 Presenter 시 뮬 레이 션 대상 의 주입 을 완성 해 야 합 니 다.
배치 하 다.
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 21, constants = BuildConfig.class)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
@PrepareForTest({PresenterFactory.class})
@Before
public void setUp() {
appContext = RuntimeEnvironment.application.getApplicationContext();
PowerMockito.mockStatic(PresenterFactory.class);
}
onCreate 용례Robolectric 의 Activity Controller 를 통 해 activity 의 생명 주 기 를 구축 하고 관리 하 며 onCreate 단계 로 실행 한 다음 이 단계 text 1 이 올 바 르 게 초기 화 되 었 는 지 검증 합 니 다.
@Test
public void onCreate_text1() {
MainActivity activity = Robolectric.buildActivity(MainActivity.class).create().get();
String expect = appContext.getString(R.string.hell_world);
assertEquals(expect, ((TextView)activity.findViewById(R.id.lbl_text1)).getText());
}
버튼 1 예 를 클릭 합 니 다Activity 가 완전히 표 시 된 후 button 1 의 click 작업 이 toast 메 시 지 를 표시 하 는 지 확인 합 니 다.
@Test
public void btn1_click() {
MainActivity activity = Robolectric.setupActivity(MainActivity.class);
activity.findViewById(R.id.btn_1).performClick();
String expect = appContext.getString(R.string.hell_world);
assertEquals(expect, ShadowToast.getTextOfLatestToast());
}
버튼 2 예 를 클릭 합 니 다Activity 가 완전히 표 시 된 후,button 2 의 click 작업 이 presenter 의 fetch 방법 을 호출 했 는 지 검증 합 니 다.
@Test
public void btn2_click() {
MainContract.Presenter presenter = Mockito.mock(MainContract.Presenter.class);
PowerMockito.when(PresenterFactory.create(Mockito.any(MainContract.View.class), Mockito.any(AppExecutors.class)))
.thenReturn(presenter);
MainActivity activity = Robolectric.setupActivity(MainActivity.class);
activity.findViewById(R.id.btn_2).performClick();
Mockito.verify(presenter, Mockito.times(1))
.fetch();
}
테스트 발표 자Presenter 의 테스트 는 일반적으로 Android SDK 에 의존 하지 않 아 도 됩 니 다.Presenter 는 바 텀 분야 의 서비스 에 의존 하고 상층 View 에 도 의존 합 니 다.demo 에서 분야 서비스 에 대한 의존 은 구조 함수 방식 으로 주입 되 지 않 고 정적 공장 방법 으로 구축 되 어야 합 니까?아니면 PowerMock 을 사용 해 야 합 니까?
배치 하 다.
@RunWith(PowerMockRunner.class)
@PrepareForTest({ServiceFactory.class})
@Before
public void setUp() {
PowerMockito.mockStatic(ServiceFactory.class);
}
성공 경로 용례View 방법 이 성공 적 으로 호출 되 었 는 지,호출 매개 변수 가 일치 하 는 지 검증 합 니 다.
@Test
public void fetch_success() {
String expected = "hello world";
SlowService service = Mockito.mock(SlowService.class);
Mockito.when(service.fetch()).thenReturn(expected);
PowerMockito.when(ServiceFactory.create())
.thenReturn(service);
MainContract.View view = Mockito.mock(MainContract.View.class);
MainPresenter presenter = new MainPresenter(view, executors);
presenter.fetch();
Mockito.verify(service, Mockito.times(1)).fetch();
Mockito.verify(view, Mockito.times(1)).onFetchStarted();
Mockito.verify(view, Mockito.times(1)).onFetchCompleted();
Mockito.verify(view, Mockito.times(0)).onFetchFailed(Mockito.anyObject());
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
Mockito.verify(view, Mockito.times(1)).onFetchSuccess(captor.capture());
assertEquals(expected, captor.getValue());
}
실패 경로 예
@Test
public void fetch_failed() {
RuntimeException exception = new RuntimeException("fetch failed");
SlowService service = Mockito.mock(SlowService.class);
Mockito.when(service.fetch()).thenThrow(exception);
PowerMockito.when(ServiceFactory.create())
.thenReturn(service);
MainContract.View view = Mockito.mock(MainContract.View.class);
MainPresenter presenter = new MainPresenter(view, executors);
presenter.fetch();
Mockito.verify(service, Mockito.times(1)).fetch();
Mockito.verify(view, Mockito.times(1)).onFetchStarted();
Mockito.verify(view, Mockito.times(1)).onFetchCompleted();
ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class);
Mockito.verify(view, Mockito.times(1)).onFetchFailed(captor.capture());
assertEquals(exception, captor.getValue());
Mockito.verify(view, Mockito.times(0)).onFetchSuccess(Mockito.anyString());
}
테스트 서비스Service 는 상부 에 의존 하지 않 고 JUnit 테스트 를 직접 사용 할 수 있 습 니 다.
public class SlowServiceImplTest {
@Test
public void fetch_data() {
SlowServiceImpl impl = new SlowServiceImpl();
String data = impl.fetch();
assertEquals("from slow service", data);
}
}
자동화 테스트자동화 테스트 는 일반적으로 지속 적 인 집적 환경 에서 명령 을 사용 하여 단원 테스트 를 집행 한다
gradlew :app:testDebugUnitTest
총결산이 demo 를 쓰 고 나 면 Android APP 에 유닛 테스트 를 하 는 것 이 매우 간단 하 다 고 생각 합 니 다.우수한 프로그래머 로 서 어떻게 자신의 코드 품질 에 관심 을 가지 지 않 을 수 있 습 니까?직접 해 보 세 요.
원본 코드 다운로드
https://github.com/hziee514/android-testing
참고 자료
Robolectric
Using PowerMock
Mockito
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.