简单谈谈android studio 的单元测试

面对android studio Run 一次项目要等好几分钟的痛点,不得不研究一下android studio 的单元测试。

其实我的目的很简单,在不对视图进行操作的前提下,测试一些activity 的生命周期,或网络拉取数据的一些处理,比如解析 json 数据啊,做网络请求啊等等,也就是对 Model层的测试。这些不需要操作视图,但在没有单元测试环境下,比如我们网络请求一些数据,Log 打印看看是否请求成功,却又要 利用模拟器或真机Run 一次项目,花费好几分钟,这是不能容忍的。

于是乎,强大的 android studio 也考虑到了这一点,给我们提供的简单的单元测试类。

让我们来简单的了解学习一下吧。

首先先来了解一下一些名称,方便下面介绍和使用:

在java中咱们有用过 JUnit 的 单元测试 ,那android 也是基于 java 语言编写的,所以也有个 JUnit的单元测试。在做 android 的单元测试需要导入依赖:

androidTestCompile 'junit:junit:4.12'
testCompile 'junit:junit:4.12'

其中, test目录为在本机执行单元测试代码的目录, androidTest为在Android设备上执行单元测试代码的目录。如下图:

Android 自带的 junit单元测试的一些测试类(androidTest测试 需要运行在模拟机或真机上)

1、InstrumentationTestCase框架:

Instrumentation和Activity有点类似,只不过Activity是需要一个界面的,而Instrumentation并不是这样的,我们可以将它理解为一种没有图形界面的,具有启动能力的,用于监控其他类(用Target Package声明)的工具类。

举个例子,利用InstrumentationTestCase 启动一个activity:

在androidTest下新建一个java类,并且继承自InstrumentationTestCase编写一个public void的方法,但是必须要是方法名以test打头,比如testPublishSubject,并不需要@Test注解

public class TestSubject extends InstrumentationTestCase { private static final String LOG_TAG = "test"; public void testPublishSubject() { launchActivity("demo.zts.com.demo",SecondActivity.class,null); } }

2、ApplicationTestCase——测试整个应用程序的类。它允许你注入一个模拟的Context到应用程序中,在应用程序启动之前初始化测试参数,并在应用程序结束之后销毁之前检查应用程序。

使用Context,你可以浏览资源,文件,数据库等等。基类是AndroidTestCase,一般常见的是它的子类,和特定组件关联。

测试代码如下:

public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); String app_name = getResources().getString(R.string.app_name); Log.i("MyApp",".........MyApp....app_name.........."+app_name); } } public class ApplicationTest extends ApplicationTestCase<MyApp> { public ApplicationTest() { super(MyApp.class); } public void testStart() { String str = null; str = mContext.getResources().getString(R.string.app_name); Log.i("..",".............ApplicationTest ...........app_name............."+str); }

Log 日志:

07-22 23:27:10.276 32259-32259/demo.zts.com.demo I/MyApp: .........MyApp....app_name..........demo
 07-22 23:27:10.276 32259-32319/demo.zts.com.demo I/TestRunner: started: testStart(demo.zts.com.demo.ApplicationTest)
 07-22 23:27:10.286 32259-32319/demo.zts.com.demo I/..: .............ApplicationTest..........app_name..............demo

3、ActivityUnitTestCase——对单个Activity进行单一测试的类。使用它,你可以注入模拟的Context或Application,或者两者。它用于对Activity进行单元测试。也就是说你可以用于测试单独的activity ,虽然也需要利用模拟机或真机启动,但你启动的只是你需要做测试的activity,于其他activity无关。
测试代码如下:

要测试的 activity

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); System.out.println("...............MainActivity......onCreate............"); Log.i("MainActivity","................onCreate............................"); } @Override protected void onStart() { super.onStart(); System.out.println("...............MainActivity......onStart............"); Log.i("MainActivity","................onStart............................"); } @Override protected void onStop() { super.onStop(); System.out.println("...............MainActivity......onStop............"); Log.i("MainActivity","................onStop............................"); } @Override protected void onDestroy() { super.onDestroy(); System.out.println("...............MainActivity......onDestroy............"); Log.i("MainActivity","................onDestroy............................"); } }

测试类

public class TestActivity extends ActivityInstrumentationTestCase2<MainActivity> { private Context ctx; public TestActivity() { super(MainActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); ctx = getActivity().getApplicationContext(); } public void testStart() { Intent intent = new Intent(ctx, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ctx.startActivity(intent); Log.i("TestActivity","................startActivity............................"); }

测试 Log 日志:

* 07-22 23:39:44.146 3171-3171/demo.zts.com.demo I/System.out: ...............MainActivity......onCreate............
     07-22 23:39:44.146 3171-3171/demo.zts.com.demo I/MainActivity: ................onCreate............................
     07-22 23:39:44.151 3171-3171/demo.zts.com.demo D/MZPerfObserver: demo.zts.com.demo onCreate consume 153 ms
     07-22 23:39:44.151 3171-3171/demo.zts.com.demo I/System.out: ...............MainActivity......onStart............
     07-22 23:39:44.151 3171-3171/demo.zts.com.demo I/MainActivity: ................onStart............................
     07-22 23:39:44.326 3171-3171/demo.zts.com.demo D/OpenGLRenderer: Enabling debug mode 0
     07-22 23:39:44.361 3171-3171/demo.zts.com.demo I/System.out: ...............MainActivity......onStop............
     07-22 23:39:44.361 3171-3171/demo.zts.com.demo I/MainActivity: ................onStop............................
 
     07-22 23:39:44.421 3171-3224/demo.zts.com.demo I/TestActivity: ................startActivity............................

还有很多常见的测试,比如ServiceTestCase,ProviderTestCase2等,大家需要慢慢琢磨。

Android 自带的 junit单元测试的一些测试类(test 测试 ,不需要模拟机,电脑直接运行)

比如我需要测试一段java代码,而这段java代码跟android没关系,也就是不用到android的资源,如context,activity 等,说白了就是简单的 java 测试,当然,嘿嘿,android studio也是可以做java代码测试的。

测试代码如下,测试 4+4 等于几:

public class ExampleUnitTest { @Test public void testAdd() { int i = 0; i = 4+4; System.out.print(".............. "+i); Log.i("TAG","..................."+i); // 比较 i 是否 等于 8 ,相等的话通过测试!!! Assert.assertEquals(8, i); } }

测试成功:

以上测试类的运行是 -点击测试右键 - 选择 RunXXXXX

/*********************华丽分割线***********************/

看了半天好像也没有解决文章最初提到的一个痛点啊,就是我需要测试android的资源,但又不想运行笨重的模拟机或真机,怎么办呢? 妈蛋,被骗了,还钱 -_-、、、 确实,上面提到的测试方法虽然没有解决拜托模拟机测试的痛点,但基于模拟机单元测试的 androidTest 确实方便我们做一些 单独功能的测试,而且能做 UI 测试,因为需要模拟机或真机嘛,所以 UI 或视图测试是没问题的。 还有test 测试,可以做一些不需要android资源的 java代码测试,也是在android开发当中很方便的,不用在启用eclipse 做测试,直接android studio 既可以了。

忽悠,接着 忽悠 -_-////

其实要想脱离 模拟机或真机,又要做使用android资源的测试,如 使用Context,浏览资源,文件,数据库等等。 也是可以的!!! 那 就只有第三方测试框架了 Robolectric

666,你是来做宣传的吗 -_-、、、不过真的很好用,也能很好的解决咱们的痛点。

接下来利用个需求来讲解 Robolectric 测试,免得我忽悠你们。

拿到 android 目录下的 assets 下的json01.txt文件 是一段json数据,让后进行解析,解析后将数据显示。 分析:这个需求就跟android下的资源有关,而咱们利用 Robolectric 做单元测试,并且不需要模拟机或真机的支持。

其中json数据

{ "name": "coolxing", "age": 24, "male": true, "address": { "street": "huiLongGuan", "city": "beijing", "country": "china" } }

首先需要 Robolectric 依赖,在你的 app module 下注入依赖:

testCompile 'org.robolectric:robolectric:3.0'
注意是 testCompile 而不是 androidTestCompile ,不然你有需要启动模拟器了。并且测试类也是 在 test 下的

测试类:

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class MainActivityTest2 { @Test public void testJson(){ String str = null; str = RuntimeEnvironment.application.getResources().getString(R.string.app_name); AssetManager am = null; am = RuntimeEnvironment.application.getAssets(); String strData = null; try { InputStream inputStream = am.open("json01.txt"); byte buf[] = new byte[1024]; inputStream.read(buf); strData = new String(buf); strData =strData.trim(); strData.trim(); } catch (IOException e) { } jsonBean foo = new Gson().fromJson(strData, jsonBean.class); System.out.println("...............json.................."+foo.name); System.out.println("...............json.................."+foo.address); System.out.println("...............json.................."+foo.age); } }

测试结果:

看,咱们利用application 拿到 android 下的资源,但又不像刚才上面的 androidTestCompile 需要模拟机,是不是很6,我电脑配置比较低,本次测试需要40S多,但不真机快多了。

am = RuntimeEnvironment.application.getAssets();

需要注意几点,类头部需要声明  @ 注解:

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)

并且测试方法是以 textxxx() 开头的,如上面的 testJson() ,方法也需要@Test注解!!!
Robolectric 还可以测试 activity ,如:

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class MainActivityTest2 { @Test public void testMainActivity() { MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class); mainActivity.findViewById(R.id.main_tv).performClick(); Intent expectedIntent = new Intent(mainActivity, SecondActivity.class); ShadowActivity openActivity = Shadows.shadowOf(mainActivity); Intent actualIntent = openActivity .getNextStartedActivity(); // Assert.assertEquals(expectedIntent, actualIntent); }

其中

MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);

这句代码就是启动了MainActivity 的生命周期

Robolectric 单元测试类 的 启动 也是跟 上面test 测试类一样,选择 -MainActivityTest2 --右键 -- 选择 Run MainActivityTest2

好了,单元测试就介绍到这里,

其实我也只是初步理解,上面那些基本的也是我做项目的需要我才去学习使用的,还有好多强大的功能大家慢慢探索。

时间: 2024-10-02 13:42:26

简单谈谈android studio 的单元测试的相关文章

简单谈谈android studio 的单元测试_Android

面对android studio Run 一次项目要等好几分钟的痛点,不得不研究一下android studio 的单元测试. 其实我的目的很简单,在不对视图进行操作的前提下,测试一些activity 的生命周期,或网络拉取数据的一些处理,比如解析 json 数据啊,做网络请求啊等等,也就是对 Model层的测试.这些不需要操作视图,但在没有单元测试环境下,比如我们网络请求一些数据,Log 打印看看是否请求成功,却又要 利用模拟器或真机Run 一次项目,花费好几分钟,这是不能容忍的. 于是乎,强

简单谈谈Android中SP与DP的区别_Android

从一开始写Android程序,就被告知这些常识 一.dp(或者dip device independent pixels) 一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp=1px.不同设备有不同的显示效果,这个和设备硬件有关. 二.sp(Scaled Pixels) 主要用于字体显示,与刻度无关的一种像素,与dp类似,但是可以根据用户的字体大小首选项进行缩放. 简单的说 长度宽度的数值要使用dp作为单位放入dimens.xml文件中 字体大小的数值要使用sp作为单位,也放入dim

小结Android Studio常用设置说明教程

特别说明一下,Android Studio 要求的Android SDK的版本不低于Version22,同时还需要Build Tools的版本不低于Version17,否则在创建新工程的时候会出现错误.但是导入工程是没有问题的. 先贴个File菜单的截图,以供大家查看 1.中文乱码 在打开的窗口中,找到IDE Settings下的Appearance,在右侧勾选上"Override default fonts by",然后在第一个下拉框中选择字体为"simsun",

Android Studio简单设置(转)

Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以选择使用炫酷的黑色界面.Settings --> Appearance --> Theme ,选择 Darcula 主题即可. 字体设置 系统字体设置 如果你的Android Studio界面中,中文显示有问题,或者选择中文目录显示有问题,或者想修改菜单栏的字体,可以这么设置.Settings --> Appearance ,勾选 Override default fonts by (

Android Studio初探:不只是一个简单的IDE

对于Android 开发者来说,日常开发对于他们来说是干脆直接的.你只需要下载Eclipse并且安装Android Developer工具插件就可以了.Android的Eclipse插件为开发者完成了不少工作,而且或多或少能符合大多数开发者期望那样.但现在,Google最新发布的Android Studio 搅局了,这款Android IDE开发工具对任何Android 开发者而言,都是极大的飞跃. 虽然拥有"Android Studio"的名称,并且软件直接来自Google的,但大多

Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

原文:Android零基础入门第11节:简单几步带你飞,运行Android Studio工程 之前讲过Eclipse环境下的Android虚拟设备的创建和使用,现在既然升级了Android Studio开发工具,那么对应的Android虚拟设备也该一起升级了. 那么本期我们就来一起学习在Android Studio开发环境中如何创建和使用Android虚拟设备.   一.Android虚拟设备入口 上期我们使用了Android Studio创建了HeloWorld工程,要想运行该工程,首先需要一

Android Studio下执行单元测试

今天在Android Studio下学习怎么执行单元测试,现总结如下: 1. https://coderwall.com/p/ybds4w http://blog.futurice.com/android_unit_testing_in_ides_and_ci_environments 2. 出现问题如下: Exception in thread "main" java.lang.NoClassDefFoundError: junit/textui/ResultPrinter at j

Android studio编写简单的手电筒APP_Android

很不错的手电筒APP,分享给大家,希望大家喜欢. 1. Java代码     package com.example.goo.gfire; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.os.Bundle; import android.view.View; import android.widget.Bu

android studio简单界作问题

问题描述 android studio简单界作问题 初学studiotext 行那个文字格式貌似有问题,请问怎么去除那个红色标记 解决方案 http://tieba.baidu.com/p/4433824871http://ask.csdn.net/questions/244821?sort=id 解决方案二: 啥问题都没有,只是建议你用到的资源文件都定义在资源文件里,不要用这种硬编码,不用管他 解决方案三: 这个报错不影响使用但是建议不要直接把字符串写到这里要写到资源文件里 解决方案四: Ct