Upgrade to Pro — share decks privately, control downloads, hide ads and more …

android-testing-bootcamp-1

 android-testing-bootcamp-1

Yuya Kaido

March 23, 2016
Tweet

More Decks by Yuya Kaido

Other Decks in Programming

Transcript

  1. Presentation • Ͳ͏දࣔ͢Δ͔Λهड़ • MVPϞυΩ • Presenter͸Pure Java (ContextҎ֎) •

    Presenter͸JUnit/RobolectricͰςετ • View͸EspressoͰςετ(Robolectric΋ซ༻) 
  2. GithubClient public class GithubClient {
 
 private GithubService githubService;
 


    @Inject
 public GithubClient(GithubService service) {
 this.githubService = service;
 }
 
 public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) {
 return CommonClient.retry(githubService.getGithubContributors(owner, repo));
 }
 
 public Observable<List<GithubContributor>> getGithubContributors() {
 return getGithubContributors("konifar", "droidkaigi2016");
 }
 
 public interface GithubService {
 @GET("/repos/{owner}/{repo}/contributors")
 Observable<List<GithubContributor>> getGithubContributors(
 @Path("owner") String owner, @Path("repo") String repo);
 }
 
 }  ΞϓϦ
  3. GithubClient public class GithubClient {
 
 private GithubService githubService;
 


    @Inject
 public GithubClient(GithubService service) {
 this.githubService = service;
 }
 
 public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) {
 return CommonClient.retry(githubService.getGithubContributors(owner, repo));
 }
 
 public Observable<List<GithubContributor>> getGithubContributors() {
 return getGithubContributors("konifar", "droidkaigi2016");
 }
 
 public interface GithubService {
 @GET("/repos/{owner}/{repo}/contributors")
 Observable<List<GithubContributor>> getGithubContributors(
 @Path("owner") String owner, @Path("repo") String repo);
 }
 
 }  ΞϓϦ
  4. GithubClient public class GithubClient {
 
 private GithubService githubService;
 


    @Inject
 public GithubClient(GithubService service) {
 this.githubService = service;
 }
 
 public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) {
 return CommonClient.retry(githubService.getGithubContributors(owner, repo));
 }
 
 public Observable<List<GithubContributor>> getGithubContributors() {
 return getGithubContributors("konifar", "droidkaigi2016");
 }
 
 public interface GithubService {
 @GET("/repos/{owner}/{repo}/contributors")
 Observable<List<GithubContributor>> getGithubContributors(
 @Path("owner") String owner, @Path("repo") String repo);
 }
 
 }  ΞϓϦ
  5. GithubClient public class GithubClient {
 
 private GithubService githubService;
 


    @Inject
 public GithubClient(GithubService service) {
 this.githubService = service;
 }
 
 public Observable<List<GithubContributor>> getGithubContributors(String owner, String repo) {
 return CommonClient.retry(githubService.getGithubContributors(owner, repo));
 }
 
 public Observable<List<GithubContributor>> getGithubContributors() {
 return getGithubContributors("konifar", "droidkaigi2016");
 }
 
 public interface GithubService {
 @GET("/repos/{owner}/{repo}/contributors")
 Observable<List<GithubContributor>> getGithubContributors(
 @Path("owner") String owner, @Path("repo") String repo);
 }
 
 }  ΞϓϦ
  6. GithubInfraModule @Module
 public class GithubInfraModule {
 
 @Provides
 @Singleton
 public

    GithubClient.GithubService provideGithubService() {
 return ApiClientGenerator.generate(
 GithubClient.GithubService.class,
 "https://api.github.com");
 }
 
 }  ςετ
  7. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  8. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  9. GithubInfraTestModule @Module
 public class GithubInfraTestModule {
 
 @Provides
 public GithubClient.GithubService

    provideGithubService(MockWebServer mockWebServer) {
 return ApiClientGenerator.generate(
 GithubClient.GithubService.class,
 mockWebServer.url("").toString());
 }
 
 }  ςετ
  10. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  11. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  12. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  13. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  14. GithubClientTest public class GithubClientTest extends InfraTest {
 
 @Test
 public

    void getGithubContributorsTest() throws Exception {
 File file = new File("src/test/assets/json/github_contributors.json");
 MockWebServer mockWebServer = new MockWebServer();
 mockWebServer.enqueue(ResponseUtil.createMockResponse(file));
 mockWebServer.start();
 
 GithubInfraTestModule githubInfraTestModule = new GithubInfraTestModule();
 GithubClient githubClient = new GithubClient(
 githubInfraTestModule.provideGithubService(mockWebServer));
 
 TestSubscriber<List<GithubContributor>> testSubscriber = new TestSubscriber<>();
 githubClient.getGithubContributors().subscribe(testSubscriber);
 
 testSubscriber.assertNoErrors();
 testSubscriber.assertCompleted();
 List<GithubContributor> githubContributors = testSubscriber.getOnNextEvents().get(0);
 assertThat(githubContributors.size(), is(1));
 }
 
 }  ςετ
  15. GithubPresenter public class GithubPresenter {
 
 @Inject
 Scheduler scheduler;
 


    private GithubView githubView;
 private GithubUseCase githubUseCase;
 
 public GithubPresenter(Context context, GithubView githubView, GithubUseCase githubUseCase) {
 Genesis.getGenesisComponent(context).inject(this);
 this.githubView = githubView;
 this.githubUseCase = githubUseCase;
 } ʢதུʣ
 
 }  ΞϓϦ
  16. GithubPresenter public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 public void onItemClick(GithubContributor githubContributor) {
 githubView.startWebViewActivity(githubContributor);
 } ʢதུʣ
 
 }  ΞϓϦ
  17. GithubPresenter public class GithubPresenter {
 
 public void refresh() {


    githubUseCase.getGithubContributors()
 .subscribeOn(scheduler)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber<List<GithubContributor>>() {
 @Override
 public void onCompleted() {
 }
 
 @Override
 public void onError(Throwable e) {
 }
 
 @Override
 public void onNext(List<GithubContributor> githubContributors) {
 githubView.setGithubContributors(githubContributors);
 githubView.hideProgressBar();
 }
 });
 } ʢதུʣ
 
 }  ΞϓϦ
  18. GithubPresenterTest public class GithubPresenterTest extends PresentationTest {
 
 private GithubView

    githubView;
 private GithubUseCase githubUseCase;
 private GithubPresenter githubPresenter;
 
 @Override
 public void setUp() {
 super.setUp();
 githubView = mock(GithubView.class);
 githubUseCase = mock(GithubUseCase.class);
 githubPresenter = new GithubPresenter(getContext(), githubView, githubUseCase);
 } ʢதུʣ
 
 }  ςετ
  19. GithubPresenterTest public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onCreateTest() {
 githubPresenter.onCreate();
 
 verify(githubView, times(1)).initViews();
 verify(githubView, times(1)).showProgressBar();
 verify(githubView, times(1)).refresh();
 }
 
 }  ςετ
  20. GithubPresenterTest public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onCreateTest() {
 githubPresenter.onCreate();
 
 verify(githubView, times(1)).initViews();
 verify(githubView, times(1)).showProgressBar();
 verify(githubView, times(1)).refresh();
 }
 
 }  ςετ
  21. GithubPresenterTest public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onCreateTest() {
 githubPresenter.onCreate();
 
 verify(githubView, times(1)).initViews();
 verify(githubView, times(1)).showProgressBar();
 verify(githubView, times(1)).refresh();
 }
 
 }  ςετ
  22. GithubPresenterTest public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onCreateTest() {
 githubPresenter.onCreate();
 
 verify(githubView, times(1)).initViews();
 verify(githubView, times(1)).showProgressBar();
 verify(githubView, times(1)).refresh();
 }
 
 }  ςετ
  23. GithubPresenterTest public class GithubPresenter {
 
 public void onCreate() {


    githubView.initViews();
 githubView.showProgressBar();
 githubView.refresh();
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onCreateTest() {
 githubPresenter.onCreate();
 
 verify(githubView, times(1)).initViews();
 verify(githubView, times(1)).showProgressBar();
 verify(githubView, times(1)).refresh();
 }
 
 }  ςετ
  24. GithubPresenterTest public class GithubPresenter {
 public void refresh() {
 githubUseCase.getGithubContributors()


    .subscribeOn(scheduler)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Action1<List<GithubContributor>>() {
 @Override
 public void call(List<GithubContributor> githubContributors) {
 githubView.setGithubContributors(githubContributors);
 githubView.hideProgressBar();
 }
 });
 }
 } public class GithubPresenterTest extends PresentationTest {
 @Test
 public void refreshTest() {
 Observable<List<GithubContributor>> observable = Observable.create(
 new Observable.OnSubscribe<List<GithubContributor>>() {
 @Override
 public void call(Subscriber<? super List<GithubContributor>> subscriber) {
 subscriber.onNext(new ArrayList<GithubContributor>());
 subscriber.onCompleted();
 }
 }
 );
 when(githubUseCase.getGithubContributors()).thenReturn(observable);
 
 githubPresenter.refresh();
 
 verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>());
 verify(githubView, times(1)).hideProgressBar();
 }
 }  ςετ
  25. GithubPresenterTest public class GithubPresenter {
 public void refresh() {
 githubUseCase.getGithubContributors()


    .subscribeOn(scheduler)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Action1<List<GithubContributor>>() {
 @Override
 public void call(List<GithubContributor> githubContributors) {
 githubView.setGithubContributors(githubContributors);
 githubView.hideProgressBar();
 }
 });
 }
 } public class GithubPresenterTest extends PresentationTest {
 @Test
 public void refreshTest() {
 Observable<List<GithubContributor>> observable = Observable.create(
 new Observable.OnSubscribe<List<GithubContributor>>() {
 @Override
 public void call(Subscriber<? super List<GithubContributor>> subscriber) {
 subscriber.onNext(new ArrayList<GithubContributor>());
 subscriber.onCompleted();
 }
 }
 );
 when(githubUseCase.getGithubContributors()).thenReturn(observable);
 
 githubPresenter.refresh();
 
 verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>());
 verify(githubView, times(1)).hideProgressBar();
 }
 }  ςετ
  26. GithubPresenterTest public class GithubPresenter {
 public void refresh() {
 githubUseCase.getGithubContributors()


    .subscribeOn(scheduler)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Action1<List<GithubContributor>>() {
 @Override
 public void call(List<GithubContributor> githubContributors) {
 githubView.setGithubContributors(githubContributors);
 githubView.hideProgressBar();
 }
 });
 }
 } public class GithubPresenterTest extends PresentationTest {
 @Test
 public void refreshTest() {
 Observable<List<GithubContributor>> observable = Observable.create(
 new Observable.OnSubscribe<List<GithubContributor>>() {
 @Override
 public void call(Subscriber<? super List<GithubContributor>> subscriber) {
 subscriber.onNext(new ArrayList<GithubContributor>());
 subscriber.onCompleted();
 }
 }
 );
 when(githubUseCase.getGithubContributors()).thenReturn(observable);
 
 githubPresenter.refresh();
 
 verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>());
 verify(githubView, times(1)).hideProgressBar();
 }
 }  ςετ
  27. GithubPresenterTest public class GithubPresenter {
 public void refresh() {
 githubUseCase.getGithubContributors()


    .subscribeOn(scheduler)
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Action1<List<GithubContributor>>() {
 @Override
 public void call(List<GithubContributor> githubContributors) {
 githubView.setGithubContributors(githubContributors);
 githubView.hideProgressBar();
 }
 });
 }
 } public class GithubPresenterTest extends PresentationTest {
 @Test
 public void refreshTest() {
 Observable<List<GithubContributor>> observable = Observable.create(
 new Observable.OnSubscribe<List<GithubContributor>>() {
 @Override
 public void call(Subscriber<? super List<GithubContributor>> subscriber) {
 subscriber.onNext(new ArrayList<GithubContributor>());
 subscriber.onCompleted();
 }
 }
 );
 when(githubUseCase.getGithubContributors()).thenReturn(observable);
 
 githubPresenter.refresh();
 
 verify(githubView, times(1)).setGithubContributors(new ArrayList<GithubContributor>());
 verify(githubView, times(1)).hideProgressBar();
 }
 }  ςετ
  28. GithubPresenterTest public class GithubPresenter { 
 public void onItemClick(GithubContributor githubContributor)

    {
 githubView.startWebViewActivity(githubContributor);
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onItemClickTest() {
 githubPresenter.onItemClick(null);
 
 verify(githubView, times(1)).startWebViewActivity(null);
 }
 
 }  ςετ
  29. GithubPresenterTest public class GithubPresenter { 
 public void onItemClick(GithubContributor githubContributor)

    {
 githubView.startWebViewActivity(githubContributor);
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onItemClickTest() {
 githubPresenter.onItemClick(null);
 
 verify(githubView, times(1)).startWebViewActivity(null);
 }
 
 }  ςετ
  30. GithubPresenterTest public class GithubPresenter { 
 public void onItemClick(GithubContributor githubContributor)

    {
 githubView.startWebViewActivity(githubContributor);
 }
 
 } public class GithubPresenterTest extends PresentationTest {
 
 @Test
 public void onItemClickTest() {
 githubPresenter.onItemClick(null);
 
 verify(githubView, times(1)).startWebViewActivity(null);
 }
 
 }  ςετ
  31. CommonClient public class CommonClient {
 
 private static final int

    RETRY_COUNT = 3;
 private static final int RETRY_DELAY = 3;
 
 public static <T> Observable<T> retry(Observable<T> observable) {
 return observable.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
 @Override
 public Observable<?> call(Observable<? extends Throwable> observable) {
 return observable.take(RETRY_COUNT).flatMap(new Func1<Throwable, Observable<?>>() {
 @Override
 public Observable<?> call(Throwable throwable) {
 return Observable.timer(RETRY_DELAY, TimeUnit.SECONDS);
 }
 });
 }
 });
 }
 
 } 
  32. ApiClientGenerator public class ApiClientGenerator {
 
 public static <T> T

    generate(Class<T> clazz, String baseUrl) {
 return new Retrofit.Builder()
 .client(HttpClient.getInstance())
 .baseUrl(baseUrl)
 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
 .addConverterFactory(GsonConverterFactory.create())
 .build()
 .create(clazz);
 }
 
 } 
  33. HttpClient public class HttpClient {
 
 private static OkHttpClient instance;


    
 private HttpClient() {}
 
 public static synchronized OkHttpClient getInstance() {
 if (instance == null) {
 HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
 httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
 instance = new OkHttpClient.Builder()
 .addInterceptor(httpLoggingInterceptor)
 .addNetworkInterceptor(new StethoInterceptor())
 .build();
 }
 
 return instance;
 }
 
 } 
  34. GithubView public interface GithubView {
 
 void initViews();
 void refresh();


    void showProgressBar();
 void hideProgressBar();
 void setGithubContributors(List<GithubContributor> githubContributors);
 void startWebViewActivity(GithubContributor githubContributor);
 
 }