单元测试——Android(入门篇)

本文介绍了Android单元测试的基础,包括简单示例、Android四大组件的测试方法、UI测试的探讨,以及Espresso和Roboletric的区别。还推荐了一篇深入的单元测试文章。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Android中单元测试的基础使用

①、简单示例:(在android中测试加法)

public final class MathUtils {
    private MathUtils(){
        throw new IllegalArgumentException("该类无法实例化");
    }

    public static int addition(int a,int b){
        return a+b;
    }
}
测试类:

public class MathUtilsTest extends TestCase{

    public void testMathUtils(){
        assertEquals(0,MathUtils.addition(1,-1));
        assertEquals(2,MathUtils.addition(1,1));
    }
}

如果使用AndroidStudio会自动加载junit包

在build下能够看到:

testCompile 'junit:junit:4.12'

③、测试类如何拥有Context

作用:使用AndroidTestCase就能够为我们提供context了。

1、首先需要在build.gradle中加上,才能使用AndroidTestCase

android {
    // ...
    testOptions { 
        unitTests.returnDefaultValues = true
    }
}
2、使用

public class ContextTest extends AndroidTestCase {
    public void testContext(){
        //自带了context,初始化为null,context需要设置
        assertNotNull(mContext);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        //创建Context,如果不使用该语句,Context默认为null
        mContext = new MockContext();
    }
}

二、Android四大组件测试

前言:本人查找的大部分文章都是使用Android自带的测试包android.test进行对四大组件的测试。但是本人使用android.test中的测试类,无法获取四大组件的对象,且找不到文档解决该问题。所以使用Robolectric框架进行单元测试,如果大家没有这种问题的话,可以尝试使用android自带的单元测试包(没找到太好的关于介绍原生单元测试的文章。。。)
例:
public class ActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public ActivityTest() {
        super(MainActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        assertNotNull(getInstrumentation());//返回null
        assertNotNull(getActivity());//返回null
    }

    public void testActivity(){

    }
}
1、Android提供的测试环境

①、测试文件的保存位置



首先会发现该项目中的src文件夹下多了两个文件夹androidTest与test。(稍后使用)
androidTest:主要用于进行UI测试的文件夹,存放进行UI测试的测试类。
test:主要用于进行四大组件的单元测试的文件夹,存放进行单元测试的测试类
(两个文件夹下存储的类不能重名,原因本质上是在一个文件夹下)

②、测试文件的环境
如果你的Android Studio版本是在2.0以下的话,那么还需要修改Build Variants(默认是在左下角)
例:

如果不存在则在View——>ToolWindow——>Build Variants中添加

然后打开Build Variants中的 Test Artifact,其中有两个选项:
Andorid Instrumentition Test:表示启用androidTest文件夹下的测试文件(同时 test文件夹下的测试文件将会不能使用,并变成灰色)
Unit Test:作用与上述相反。

但是如果是AS2.0以上的环境,支持同时启用androidTest和test文件夹下的测试文件。(也就是不需要使用Bulid Variants 切换测试环境了)

2、Robolectric环境配置
在项目的build.gradle中添加依赖(当前最新的是3.1.1)
    testCompile 'junit:junit:4.12'
    testCompile "org.robolectric:robolectric:3.1.1"
这里使用的是testCompile而不是平常的compile。testCompile表示是添加在test文件夹下的依赖,所以只能test文件夹下的类才能使用该依赖。所以main文件夹和androidTest文件夹是无法使用robolectric这个包的。

3、使用Robolectric测试

①、测试Activity
需求:用EditText输入文字,然后通过Button执行,显示在TextView上
制作MainActivity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <EditText
        android:hint="Enter your name here"
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"/>
    <Button
        android:id="@+id/btnSubmit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Say hello!"
        android:layout_below="@+id/editText"
        android:onClick="sayHello"/>   //这里Button注册了MainActivity的sayHello()点击监听
</RelativeLayout>
public class MainActivity extends AppCompatActivity {

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

    }

    /**
     * 处理Button的点击事件
     */
    public void sayHello(View v){
        TextView textView = (TextView) findViewById(R.id.textView);
        EditText editText = (EditText) findViewById(R.id.editText);
        textView.setText("Hello, " + editText.getText().toString() + "!");
    }
}

进行测试:(自带的时候没有test这个文件夹的,可以使用单击右键->goTo->Test)
然后按照这种方式进行配置:



这里选择路径要多说依据,如果是AS 2.0一下使用Build Variant的伙伴,这里的路径直接点确定就好了,因为该路径已经根据你选择的Test Artifact确定好了是(创建在test文件夹,还是创建在androidTest文件夹)。
//格式,必须这样填
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)

public class MainActivityTest {
    private MainActivity mActivity;
    private TextView mTvContent;
    private EditText mEtText;
    private Button mBtnSubmit;
    //表示在程序运行前执行
    @Before
    public void setUp() throws Exception {
        //通过该方法获取Activity实例,内部执行了Activity的生命周期
        mActivity = Robolectric.setupActivity(MainActivity.class);
        //检查View控件是否出错。
        checkWidgets();
    }

    private void checkWidgets(){
        mTvContent = (TextView) mActivity.findViewById(R.id.textView);
        Assert.assertNotNull(mTvContent);
        mEtText = (EditText) mActivity.findViewById(R.id.editText);
        Assert.assertNotNull(mEtText);
        mBtnSubmit= (Button) mActivity.findViewById(R.id.btnSubmit);
        Assert.assertNotNull(mBtnSubmit);
    }
    //表示在程序运行时执行
    @Test
    public void testSayHello() throws Exception {
        //通过代码执行UI,设置EditText的数据
        mEtText.setText("Peter");
        //模拟点击
        mBtnSubmit.performClick();
        String str = "Hello, " + mEtText.getText().toString() + "!";
        //需要通过Assert类来执行断言,而不是直接使用assertEquals
        Assert.assertEquals(mTvContent.getText(),str);
    }
}
最后,单击右键运行。

详细文档:
Android单元测试框架Robolectric3.0介绍(一):四大组件如何测试
Android单元测试框架Robolectric3.0介绍(二):日志如何输出、网络请求、数据库操作如何测试

三、Android的UI测试

1、配置Espresso的依赖
    androidTestCompile 'com.android.support.test:runner:0.2'
    androidTestCompile 'com.android.support.test:rules:0.2'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
如果你的Android Studio版本不是API 22 的话,需要添加下面这句话,才能使用
    androidTestCompile 'com.android.support:support-annotations:23.4.0'//annotations:为你当前版本号,本人为23.4.0
还需要在android.defaultConfig中加入:
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
2、简单的使用espresso
//格式,固定格式
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityInstrumentationTest {

    private static final String STRING_TO_BE_TYPED = "Peter";

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    @Test
    public void sayHello(){
        onView(withId(R.id.editText)).perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); //line 1
        onView(withText("Say hello!")).perform(click()); //line 2
        String expectedText = "Hello, " + STRING_TO_BE_TYPED + "!";
        onView(withId(R.id.textView)).check(matches(withText(expectedText))); //line 3
    }
}
详细资料: Espresso的详细使用

四、Espresso与Roboletric的区别

Espresso作为Google推出的Instrumentation UI测试框架,在API支持方面有着天然的优势,在推出后很大程度上替代了Robotium。而Robolectric由于只在Java虚拟机中运行,速度很快,虽然在API支持上无法和Espresso相比,但速度有很大优势,适合单元测试,尤其是TDD时使用。

五、优秀的单元测试文章

http://chriszou.com/2016/06/07/android-unit-testing-everything-you-need-to-know.html










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值