安卓开发 第十三篇 Android 中的测试

I. Android 中的单元测试

一. JUnit:java单元测试框架

  • 在要测试的类中点击右键,选择 Go to > Test > create New Test … ,勾选setUp/@Before和tearDown/@After,勾选要测试的方法,然后OK创建测试类

  • 在setUP方法中做初始化工作,在tearDown中做清理工作,在要测试的方法中写测试代码

  • 在测试类中右键选 Run ‘测试类类名’ 来测试整个类,或选中要测试的方法,右键选 Run ‘方法名()’ 测试单个方法,或者在项目根目录运行 ./gradlew testDebugUnitTest 或者 ./gradlew testReleaseUnitTest 测试整个项目

    ​ junit库引入:

    testCompile 'junit:junit:4.12'

    ​更多用法查看:junit官方地址

    一个例子:

    要测试的类:Caculator

    public class Caculator {
    
      public int add(int param1,int param2){
          return param1+param2;
      }
    
    }

    测试代码:CaculatorTest

    public class CaculatorTest {
    
      Caculator caculator;
    
      @Before
      public void setUp() {
          caculator = new Caculator();
      }
    
      @Test
      public void add() throws Exception {
          int result = caculator.add(1, 2);
    
          Assert.assertEquals(3, result);
      }
    
      @After
      public void tearDown() {
          caculator = null;
      }
    }

二. Mock:对象模拟框架

  • 使用 Mockito.mock(clazz)可以得到一个模拟的clazz类型的对象
  • 使用 Mockito.verify(objectToVerify).methodToVerify(arguments) 验证某个方法得到调用
  • 要验证方法调用次数需在verify 方法中追加参数 Mockito.times(n),Mockito.atMost(n), Mockito.atLeast(n), Mockito.never() 等,如 Mockito.verify(objectToVerify,Mockito.times(n)).methodToVerify(arguments)
  • Mockito提供了一系列的any方法,来表示任意参数,如 Mockito.anyString(),其他还有 anyInt, anyLong, anyDouble,anyObject,any(clazz),anyCollection,anyCollectionOf(clazz), anyList(Map, set), anyListOf(clazz) 等等。
  • 指定mock对象的某个方法返回特定值用 Mockito.when(mockObject.targetMethod(args)).thenReturn(desiredReturnValue)。
  • 指定mock对象执行特定的动作并伴随特地的返回结果处理用 Mockito.doAnswer(desiredAnswer).when(mockObject).targetMethod(args),其他还有 Mockito.doNothing(),Mockito.doThrow(desiredException),Mockito.doCallRealMethod() .

    mockito 库引入

    testCompile 'org.mockito:mockito-core:2.7.22'
    androidTestCompile 'org.mockito:mockito-android:2.7.22'

    更多用法查看:mockito官方地址

    一个例子:

    public class Presenter {
        private Repo repo;
    
        public Presenter(Repo repo) {
            this.repo = repo;
        }
    
    
        public void getData(int id, String name) {
    
            if (id > 0 && name != null) {
                repo.optData(id, name);
            } else {
                repo.optError(id, name);
            }
        }
    
    }
    
    class Repo {
    
    
        public void optData(int id, String name) {
            Log.i("详情", "id:" + id + "-name:" + name);
        }
    
    
        public void optError(int id, String name) {
            Log.i("详情", "id:" + id + "-name:" + name);
        }
    }

    测试代码:

    public class PresenterTest {
    
        Repo repo;
    
        Presenter presenter;
    
    
        @Before
        public void setUp() throws Exception {
            repo = Mockito.mock(Repo.class);
    
            presenter = new Presenter(repo);
        }
    
    
        @Test
        public void getData() throws Exception {
    
            String name = "xiaoming";
    
            int id = 123;
    
            presenter.getData(id, name);
    
            Mockito.verify(repo).optData(id, name);
    
            name = null;
            id = 0;
    
            presenter.getData(id, name);
    
            Mockito.verify(repo).optError(id, name);
    
    
        }
    
        @After
        public void tearDown() throws Exception {
            presenter = null;
            repo = null;
        }
    
    
    }

三. Robolectric:Android代码对象模拟框架

  • 新建测试类,添加注解

    @RunWith(RobolectricTestRunner.class)
  • 其他配置,比如运行sdk版本,manifest文件等等可以通过下面注解配置

    @Config(constants = BuildConfig.class,sdk=...,manifest=...)
  • 使用 Robolectric.setupActivity(clazz) 可以得到一个模拟的clazz 类型的Activity对象

  • 使用 Shadows.shadowOf(activity) 可以得到一个ShadowActivity 的实例

  • 使用Shadows.shadowOf 还可以得到很多shadow对象,比如控件ShadowTextView,ShadowRecyclerView…,四大组件ShadowService,ShadowBroadcastReceiver…,System的Shadow类ShadowSystem…,基本上Android中的类都可以得到对应的Shadow对象。

  • 执行测试 ./gradlew test

    robolectric 库引入

    testCompile "org.robolectric:robolectric:3.3.2"

    更多用法查看:robolectric 官方地址
    一个例子:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.tv_detail).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startActivity(new Intent(MainActivity.this, DetailActivity.class));
                }
            });
    
        }
    }

    测试代码:

    @RunWith(RobolectricTestRunner.class)
    @Config(constants = BuildConfig.class)
    public class MainActivityTest {
    
        @Test
        public void testMainActivity(){
            MainActivity mainActivity= Robolectric.setupActivity(MainActivity.class);
    
            mainActivity.findViewById(R.id.tv_detail).performClick();
    
            Intent intent =new Intent(mainActivity,DetailActivity.class);
    
            ShadowActivity shadowActivity= Shadows.shadowOf(mainActivity);
    
            Assert.assertEquals(intent,shadowActivity.getNextStartedActivity());
        }
    }

II.Android 中的UI测试

UI测试待续。。。。

更多详测试内容:

1.邹小创安卓单元测试系列文章

2.TestDevTalk的在Android Studio中进行单元测试和UI测试

你可能感兴趣的:(安卓开发)