Android单元测试相关知识点

在这里插入图片描述

1. 测试分类


Android端的单元测试一般分为两类:

  • Local unit tests - 只需要JVM就可以运行的测试(后文简称UnitTest)
  • Instrumented tests - 需要机遇Android系统环境的测试(后文简称InstrumentedTest)
    在这里插入图片描述
    InstrumentedTest依赖Andorid环境,所以一般需要借助Mockito等框架

2. 测试工程结构


在这里插入图片描述

  • app/src/main/java- 业务代码

  • app/src/test/java - UnitTest代码

  • app/src/androidTest/java - InstrumentedTest代码

3. Local Unit Test


3.1 添加依赖

添加依赖如下,Andorid新建工程一般会自动添加:

dependencies {
    
    
    // Unit testing dependencies
    testImplementation 'junit:junit:4.12'
}

3.2 创建测试模板

测试一段温度转换的逻辑,如下:

public class ConverterUtil {
    
    
    // converts to celsius
    public static float convertFahrenheitToCelsius(float fahrenheit) {
    
    
        return ((fahrenheit - 32) * 5 / 9);
    }

    // converts to fahrenheit
    public static float convertCelsiusToFahrenheit(float celsius) {
    
    
        return ((celsius * 9) / 5) + 32;
    }
}

在这里插入图片描述
在被测试代码的文件中,Right click > Go To > Test
在这里插入图片描述

  1. 选择测试类型 JUnit4
  2. 选择是否生成@Before@After方法, 用来进行前/后处理
  3. 手动选择需要测试的方法,回升陈testXXX的模板代码
  4. 选择生成的测试代码路径

生产的测试模板如下:
在这里插入图片描述

3.3 实现测试代码

src/test或者src/androidTest中访问src/main的任何代码,所以可以在上面模板中填充测试逻辑:

扫描二维码关注公众号,回复: 12648742 查看本文章
public class ConverterUtilTest {
    
    

    @Test
    public void testConvertFahrenheitToCelsius() {
    
    
        float actual = ConverterUtil.convertCelsiusToFahrenheit(100);
        // expected value is 212
        float expected = 212;
        // use this method because float is not precise
        assertEquals("Conversion from celsius to fahrenheit failed", expected, actual, 0.001);
    }

    @Test
    public void testConvertCelsiusToFahrenheit() {
    
    
        float actual = ConverterUtil.convertFahrenheitToCelsius(212);
        // expected value is 100
        float expected = 100;
        // use this method because float is not precise
        assertEquals("Conversion from celsius to fahrenheit failed", expected, actual, 0.001);
    }

}

3.4 启动测试

在这里插入图片描述
Run ‘XXXTest’ 后可以看到测试报告

3.5 JUnit4注解介绍

整个测试Case中依靠大量JUnit4的注解完成,注解的主要含义如下:
在这里插入图片描述


4. Android Instrumented Test


4.1 添加依赖

defaultConfig {
    
    
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

dependencies {
    
    
    // Unit testing dependencies
    androidTestCompile 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
    // more stuff, e.g., Mockito
}
  • AndroidJUnitRunner: InstrumentedTest的基础,协助在Android设备上执行JUnit测试:
    • 加载测试代码和业务代码到目标设备
    • 在instrumented环境中执行测试case并报告结果
  • androidx.test:runner : 在Android上执行JUnit4,使用@Runwith(AndroidJUnit4.class)注解声明在对应TestCase上,相对于纯JUnit4来说,提供了一些Espresso测试混合ActivityTestRule时的需要。
  • Espresso:espresso框架主要用来解决重复性的UI操作,例如:
    @Test
    public void runClick(){
    
    
        onView(withText("点击获取城市感冒指数")).perform(click());
        onView(withId(R.id.tv)).check(matches(withText("点击获取城市今天温度")));
    }
  • Mockito:三方框架,相对于Instrumented来说,可以脱离Android设备调试环境,在纯Java环境下面完成Android测试用例,但是测试的局限性加大
  • fragment-testing:Android针对fragment新增的测试库,便于针对Fragment进行测试

4.2 创建测试模板

参考3.2 ,主要测试类型选择 Android Instrumentation Tests,生成位置src/androidTest/

4.3 测试代码

使用ActivityTestRule测试Activity

ActivityTestRule帮助启动一个Activity用于测试,如下

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
    
    

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

    @Test
    public void ensureListViewIsPresent() throws Exception {
    
    
        MainActivity activity = rule.getActivity();
        View viewById = activity.findViewById(R.id.listview);
        assertThat(viewById,notNullValue());
        assertThat(viewById, instanceOf(ListView.class));
        ListView listView = (ListView) viewById;
        ListAdapter adapter = listView.getAdapter();
        assertThat(adapter, instanceOf(ArrayAdapter.class));
        assertThat(adapter.getCount(), greaterThan(5));

    }
}

使用Espresso测试UI

Espresson可以用来访问UI控件并进行测试,如下

public class SimpleViewTest {
    
    
 
  @Rule
  public ActivityTestRule<SimpleViewActivity> mActivityTestRule =
      new ActivityTestRule<SimpleViewActivity>(SimpleViewActivity.class);
 
  @Test
  public void textViewTest() throws Exception {
    
    
    onView(withId(R.id.tv_simple_view))
        .check(matches(withText("111")));
  }
 
  @Test
  public void buttonTest() throws Exception {
    
    
    onView(withId(R.id.btn_simple_view))
        .check(matches(withText("222")))
        .perform(click());
    onView(withId(R.id.tv_simple_view))
        .check(matches(withText("333")));
  }
}

使用FragmentScenario测试Fragment

AndroidX新推出的针对FragmentScenarioActivityScenario可以更简单的创建Activity和Fragment供测试代码访问,以FragmentScenario为例:

@RunWith(AndroidJUnit4::class)
class SampleFragmentTest {
    
    
    @Test
    fun launchFragmentAndVerifyUI() {
    
    
        // use launchInContainer to launch the fragment with UI
        val scenario; = launchFragmentInContainer<SampleFragment>()

		scenario.onFragment{
    
     fragment ->
			        // now use espresso to look for the fragment's text view and verify it is displayed
        onView(withId(R.id.textView)).check(matches(withText("I am a fragment")));
		}
    }
}

参考


https://www.vogella.com/tutorials/AndroidTesting/article.html

猜你喜欢

转载自blog.csdn.net/vitaviva/article/details/113731460
今日推荐