Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Junit4 test on UI thread

Tags:

android

junit4

I'm writing unit tests for Android using Junit4 syntax, via android test support library(here). I want to test my custom view. The test involves clicking on a checkbox and making sure that a value in another place gets properly updated, but I'm getting this error when I try to run the test:

android.util.AndroidRuntimeException: Animators may only be run on Looper threads
at android.animation.ValueAnimator.start(ValueAnimator.java:1002)
at android.animation.ValueAnimator.start(ValueAnimator.java:1050)
at android.animation.ObjectAnimator.start(ObjectAnimator.java:829)
at android.graphics.drawable.AnimatedStateListDrawable$AnimationDrawableTransition.start(AnimatedStateListDrawable.java:294)
at android.graphics.drawable.AnimatedStateListDrawable.selectTransition(AnimatedStateListDrawable.java:226)
at android.graphics.drawable.AnimatedStateListDrawable.onStateChange(AnimatedStateListDrawable.java:145)
at android.graphics.drawable.Drawable.setState(Drawable.java:599)
at android.widget.CompoundButton.drawableStateChanged(CompoundButton.java:438)
at android.view.View.refreshDrawableState(View.java:16032)
at android.widget.CompoundButton.setChecked(CompoundButton.java:143)
at android.widget.CompoundButton.toggle(CompoundButton.java:113)

I'm not defining any custom animations and I don't really care about them for this test, but I assume it's Android 5.0 material theme that creates a checkbox animation.

I'm assuming the exception is thrown because the test doesn't run on a UI thread and the animator can't animate. So how do I run the test on a UI thread?

like image 241
Anton Cherkashyn Avatar asked Apr 15 '15 23:04

Anton Cherkashyn


1 Answers

Use InstrumentationRegistry.getInstrumentation().runOnMainSync():

/***
    Copyright (c) 2008-2015 CommonsWare, LLC
    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License. You may obtain a copy
    of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
    by applicable law or agreed to in writing, software distributed under the
    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
    OF ANY KIND, either express or implied. See the License for the specific
    language governing permissions and limitations under the License.

    From _The Busy Coder's Guide to Android Development_
        http://commonsware.com/Android
 */

package com.commonsware.android.abf.test;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.AndroidTestCase;
import android.test.UiThreadTest;
import android.view.LayoutInflater;
import android.view.View;
import com.commonsware.android.abf.R;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class DemoContextTest {
  private View field=null;
  private View root=null;

  @Before
  public void init() {
    InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
      @Override
      public void run() {
        LayoutInflater inflater=LayoutInflater
            .from(InstrumentationRegistry.getTargetContext());

        root=inflater.inflate(R.layout.add, null);
      }
    });

    root.measure(800, 480);
    root.layout(0, 0, 800, 480);

    field=root.findViewById(R.id.title);
  }

  @Test
  public void exists() {
    init();
    Assert.assertNotNull(field);
  }

  @Test
  public void position() {
    init();
    Assert.assertEquals(0, field.getTop());
    Assert.assertEquals(0, field.getLeft());
  }
}

(from this sample project)

like image 89
CommonsWare Avatar answered Sep 19 '22 14:09

CommonsWare