The app test started with Robolectric

The app test started with Robolectric_第1张图片
image.png
  1. Set up android dev env
Android Studio 3.0+
  1. Building with gradle
android {
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
} 
dependencies {
testImplementation "org.robolectric:robolectric:3.6.1"
}
  1. New test file in app/src/test.
@RunWith(RobolectricTestRunner.class)
public class
SimpleRobolectricTest {
}

If you use it in app/src/androidTest, it will can not resolve symbol "RobolectricTestRunner".

  1. Give you an example test
  • For example I want to test a user clicks on a back icon in MyMessageActivity, the app launches the MyHorizontalCoordinatorNtbActivity
public class MessageActivity extends SwipeBackActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);
        initView();
    }

    private void initView() {
        ImageView iv_back = (ImageView) findViewById(R.id.iv_back);
        iv_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MessageActivity.this, MyHorizontalCoordinatorNtbActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}
  • In order to test this, we can check that when a user clicks on the “back” icon, we start the correct intent. Because Robolectric is a unit testing framework, the MyHorizontalCoordinatorNtbActivity will not actually be started, but we can check that the MyMessageActivity fired the correct intent:
import android.content.Intent;

import com.koko.prototype.alert.activity.MessageActivity;
import com.koko.prototype.alert.activity.MyHorizontalCoordinatorNtbActivity;
import com.koko.prototype.alert.dao.Message;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowApplication;

import static junit.framework.Assert.assertEquals;

/**
 * Created by emily on 2018/1/17
 */

@RunWith(RobolectricTestRunner.class)
public class
SimpleRobolectricTest {

    @Test
    public void clickingLogin_shouldStartLoginActivity(){
        MessageActivity activity = Robolectric.setupActivity(MessageActivity.class);
        activity.findViewById(R.id.iv_back).performClick();

        Intent expectedIntent = new Intent(activity, MyHorizontalCoordinatorNtbActivity.class);
        Intent actual = ShadowApplication.getInstance().getNextStartedActivity();
        assertEquals(expectedIntent.getComponent(), actual.getComponent());
    }
}

  • And then click run
The app test started with Robolectric_第2张图片
image.png
  • Operation result
The app test started with Robolectric_第3张图片
image.png
  1. Robolectric
    Robolectric is a unit test framework that de-fangs the Android SDK jar so you can test-drive the development of your Android app. Tests run inside the JVM on your workstation in seconds.

  2. Some Issue

  • Some methods can not be resolved
    solution:
    Alt+Enter (Mac)
The app test started with Robolectric_第4张图片
image.png

The app test started with Robolectric_第5张图片
image.png
  1. More about robolectric
    [1] test textView
TextView mTextView =(TextView) activity.findViewById(R.id.tv_title);
assertThat(mTextView.getText().toString()).isEqualTo("Title");

[2] test activity lifecycle

Activity activity = Robolectric.buildActivity(MessageActivity.class).create().start().resume().visible().get();

[3] test restore saved instance state

Bundle savedInstanceState = new Bundle();
       Activity activity = Robolectric.buildActivity(MessageActivity.class).create().restoreInstanceState(savedInstanceState).get();

[4] using qualified resources
resource qualifiers allow you to change how your resources are loaded based on such factors as the language on the device, to the screen size, to whether it is day or night.
for run tests in different resource qualified contexts.

    @Test
    @Config(qualifiers="en-port")
    public void shouldUseEnglishAndPortraitResources(){
        final Context context = RuntimeEnvironment.application;
        assertThat(context.getString(R.string.not_overridden)).isEqualTo("Not Overridden");
        assertThat(context.getString(R.string.overridden)).isEqualTo("English qualified value");
        assertThat(context.getString(R.string.overridden_twice)).isEqualTo("English portrait qualified value");
    }

[5] set application

    @Config(application = MyApplication.class)
    public void getSandwich_shouldReturnHamSandwich() {
    }

[6] set resource path

   @Config(resourceDir = "other/build/path/ham-sandwich/res")
    public void getSandwich_show() {
    }
  1. Shadow classes
    it's created for extending the behavior of android os's class.
import android.view.ViewGroup;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowView;

/**
 * Created by emily on 2018/1/17
 */

@Implements(ViewGroup.class)
public class ShadowExample extends ShadowView{
    
    @Implementation
    public void setImageResource(int resId){
    }
    
    public ShadowExample(){
        
    }
}
  1. Thank you
  • robolectric.org
  • github.com/robolectric

你可能感兴趣的:(The app test started with Robolectric)