iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android单元测试框架Robolectric3.0介绍(一)
  • 467
分享到

Android单元测试框架Robolectric3.0介绍(一)

android单元测试测试Android 2022-06-06 12:06:29 467人浏览 泡泡鱼
摘要

  一、关于Robolectric3.0   文章中的所有代码在此:https://GitHub.com/geniusmart/LoveUT,由于Robolectric3

  一、关于Robolectric3.0   文章中的所有代码在此:https://GitHub.com/geniusmart/LoveUT,由于Robolectric3.0和3.1版本(包括后续3.x版本)差异不小,该工程中包含这两个版本对应的测试用例 Demo 。   作为一个软件开发攻城狮,无论你多不屑多排斥单元测试,它都是一种非常好的开发方式,且不谈TDD,为自己写的代码负责,测试自己写的代码,在自己力所能及的范围内提高产品的质量,本是理所当然的事情。   那么如何测试自己写的代码?点点界面,测测功能固然是一种方式,但是如果能留下一段一劳永逸的测试代码,让代码测试代码,岂不两全其美?所以,写好单元测试,爱惜自己的代码,爱惜颜值高的QA妹纸,爱惜有价值的产品(没价值的、政治性的、屁股决定脑袋的产品滚粗),人人有责!   对于Android app来说,写起单元测试来瞻前顾后,一方面单元测试需要运行在模拟器上或者真机上,麻烦而且缓慢,另一方面,一些依赖Android SDK的对象(如Activity,TextView等)的测试非常头疼,Robolectric可以解决此类问题,它的设计思路便是通过实现一套JVM能运行的Android代码,从而做到脱离Android环境进行测试。本文对Robolectric3.0做了简单介绍,并列举了如何对Android的组件和常见功能进行测试的示例。   二、环境搭建   Gradle配置   在build.gradle中配置如下依赖关系:   testCompile "org.robolectric:robolectric:3.0"   通过注解配置TestRunner   @RunWith(RobolectricGradleTestRunner.class)   @Config(constants = BuildConfig.class)   public class SampleActivityTest {   }   Android Studio的配置   在Build Variants面板中,将Test Artifact切换成Unit Tests模式(注:新版本的as已经不需要做这项配置),如下图:

  配置Test Artifact   working directory 设置为$MODULE_DIR$   如果在测试过程遇见如下问题,解决的方式是设置working directory的值:   java.io.FileNotFoundException: buildintermediatesundlesdebugAndroidManifest.xml (系统找不到指定的路径。)   设置方法如下图所示:

  Edit Configurations

Working directory的配置

  更多环境配置可以参考官方网站。   三、Activity的测试   1、创建Activity实例   @Test   public void testActivity() {   SampleActivity sampleActivity = Robolectric.setupActivity(SampleActivity.class);   assertNotNull(sampleActivity);   assertEquals(sampleActivity.getTitle(), "SimpleActivity");   }   2、生命周期   @Test   public void testLifecycle() {   ActivityController<SampleActivity> activityController = Robolectric.buildActivity(SampleActivity.class).create().start();   Activity activity = activityController.get();   TextView textview = (TextView) activity.findViewById(R.id.tv_lifecycle_value);   assertEquals("onCreate",textview.getText().toString());   activityController.resume();   assertEquals("onResume", textview.getText().toString());   activityController.destroy();   assertEquals("onDestroy", textview.getText().toString());   }   3、跳转   @Test   public void testStartActivity() {   //按钮点击后跳转到下一个Activity   forwardBtn.perfORMClick();   Intent expectedIntent = new Intent(sampleActivity, LoginActivity.class);   Intent actualIntent = ShadowApplication.getInstance().getNextStartedActivity();   assertEquals(expectedIntent, actualIntent);   }   注:Robolectric 3.1 之后,不建议用  Intent.equals() 的方式来比对两个 Intent ,因此以上代码将无法正常执行。目前建议用类似代码来断言:   assertEquals(expectedIntent.getComponent(), actualIntent.getComponent());   当然,Intent 有很多属性,如果需要分别断言的话比较麻烦,因此可以用一些第三方库,比如 assertj-android 的工具类 IntentAssert。   4、UI组件状态   @Test   public void testViewState(){   CheckBox checkBox = (CheckBox) sampleActivity.findViewById(R.id.checkbox);   Button inverseBtn = (Button) sampleActivity.findViewById(R.id.btn_inverse);   assertTrue(inverseBtn.isEnabled());   checkBox.setChecked(true);   //点击按钮,CheckBox反选   inverseBtn.performClick();   assertTrue(!checkBox.isChecked());   inverseBtn.performClick();   assertTrue(checkBox.isChecked());   }   5、Dialog   @Test   public void testDialog(){   //点击按钮,出现对话框   dialogBtn.performClick();   AlertDialog latestAlertDialog = ShadowAlertDialog.getLatestAlertDialog();   assertNotNull(latestAlertDialog);   }   6、Toast   @Test   public void testToast(){   //点击按钮,出现吐司   toastBtn.performClick();   assertEquals(ShadowToast.getTextOfLatestToast(),"we love UT");   }   7、Fragment的测试   如果使用support的Fragment,需添加以下依赖   testCompile "org.robolectric:shadows-support-v4:3.0"   shadow-support包提供了将Fragment主动添加到Activity中的方法:SupportFragmentTestUtil.startFragment(),简易的测试代码如下   @Test   public void testFragment(){   SampleFragment sampleFragment = new SampleFragment();   //此api可以主动添加Fragment到Activity中,因此会触发Fragment的onCreateView()   SupportFragmentTestUtil.startFragment(sampleFragment);   assertNotNull(sampleFragment.getView());   }   8、访问资源文件   @Test   public void testResources() {   Application application = RuntimeEnvironment.application;   String appName = application.getString(R.string.app_name);   String activityTitle = application.getString(R.string.title_activity_simple);   assertEquals("LoveUT", appName);   assertEquals("SimpleActivity",activityTitle);   }四、BroadcastReceiver的测试   首先看下广播接收者的代码   public class MyReceiver extends BroadcastReceiver {   @Override   public void onReceive(Context context, Intent intent) {   SharedPreferences.Editor editor = context.getSharedPreferences(   "account", Context.MODE_PRIVATE).edit();   String name = intent.getStringExtra("EXTRA_USERNAME");   editor.putString("USERNAME", name);   editor.apply();   }   }   广播的测试点可以包含两个方面,一是应用程序是否注册了该广播,二是广播接受者的处理逻辑是否正确,关于逻辑是否正确,可以直接人为的触发onReceive()方法,验证执行后所影响到的数据。   @Test   public void testBoradcast(){   ShadowApplication shadowApplication = ShadowApplication.getInstance();   String action = "com.geniusmart.loveut.login";   Intent intent = new Intent(action);   intent.putExtra("EXTRA_USERNAME", "geniusmart");   //测试是否注册广播接收者   assertTrue(shadowApplication.hasReceiverForIntent(intent));   //以下测试广播接受者的处理逻辑是否正确   MyReceiver myReceiver = new MyReceiver();   myReceiver.onReceive(RuntimeEnvironment.application,intent);   SharedPreferences preferences = shadowApplication.getSharedPreferences("account", Context.MODE_PRIVATE);   assertEquals( "geniusmart",preferences.getString("USERNAME", ""));   }   五、Service的测试   Service的测试类似于BroadcastReceiver,以IntentService为例,可以直接触发onHandleIntent()方法,用来验证Service启动后的逻辑是否正确。   public class SampleIntentService extends IntentService {   public SampleIntentService() {   super("SampleIntentService");   }   @Override   protected void onHandleIntent(Intent intent) {   SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences(   "example", Context.MODE_PRIVATE).edit();   editor.putString("SAMPLE_DATA", "sample data");   editor.apply();   }   }   以上代码的单元测试用例:   @Test   public void addsDataToSharedPreference() {   Application application = RuntimeEnvironment.application;   RoboSharedPreferences preferences = (RoboSharedPreferences) application   .getSharedPreferences("example", Context.MODE_PRIVATE);   SampleIntentService reGIStrationService = new SampleIntentService();   registrationService.onHandleIntent(new Intent());   assertEquals(preferences.getString("SAMPLE_DATA", ""), "sample data");   }   六、Shadow的使用   Shadow是Robolectric的立足之本,如其名,作为影子,一定是变幻莫测,时有时无,且依存于本尊。因此,框架针对Android SDK中的对象,提供了很多影子对象(如Activity和ShadowActivity、TextView和ShadowTextView等),这些影子对象,丰富了本尊的行为,能更方便的对Android相关的对象进行测试。   1.使用框架提供的Shadow对象   @Test   public void testDefaultShadow(){   MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);   //通过Shadows.shadowOf()可以获取很多Android对象的Shadow对象   ShadowActivity shadowActivity = Shadows.shadowOf(mainActivity);   ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);   Bitmap bitmap = BitmapFactory.decodeFile("Path");   ShadowBitmap shadowBitmap = Shadows.shadowOf(bitmap);   //Shadow对象提供方便我们用于模拟业务场景进行测试的api   assertNull(shadowActivity.getNextStartedActivity());   assertNull(shadowApplication.getNextStartedActivity());   assertNotNull(shadowBitmap);   }   2.如何自定义Shadow对象   首先,创建原始对象Person   public class Person {   private String name;   public Person(String name) {   this.name = name;   }   public String getName() {   return name;   }   }   其次,创建Person的Shadow对象   @Implements(Person.class)   public class ShadowPerson {   @Implementation   public String getName() {   return "geniusmart";   }   }   接下来,需自定义TestRunner,添加Person对象为要进行Shadow的对象(注:Robolectric 3.1 起可以省略此步骤)。   public class CustomShadowTestRunner extends RobolectricGradleTestRunner {   public CustomShadowTestRunner(Class<?> klass) throws InitializationError {   super(klass);   }   @Override   public InstrumentationConfiguration createClassLoaderConfig() {   InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();      builder.addInstrumentedPackage(Person.class.getPackage().getName());   builder.addInstrumentedClass(Person.class.getName());   return builder.build();   }   }   后,在测试用例中,ShadowPerson对象将自动代替原始对象,调用Shadow对象的数据和行为   @RunWith(CustomShadowTestRunner.class)   @Config(constants = BuildConfig.class,shadows = {ShadowPerson.class})   public class ShadowTest {      @Test   public void testCustomShadow(){   Person person = new Person("genius");   //getName()实际上调用的是ShadowPerson的方法   assertEquals("geniusmart", person.getName());   //获取Person对象对应的Shadow对象   ShadowPerson shadowPerson = (ShadowPerson) ShadowExtractor.extract(person);   assertEquals("geniusmart", shadowPerson.getName());   }   }   七、关于代码   文章中的所有代码在此:Https://github.com/geniusmart/LoveUT   另外,除了文中所示的代码之外,该工程还包含了Robolectric官方的测试例子,一个简单的登录功能的测试,可以作为入门使用,界面如下图。


--结束END--

本文标题: Android单元测试框架Robolectric3.0介绍(一)

本文链接: https://www.lsjlt.com/news/28744.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python单元测试框架pytest介绍
    pytest是python语言中一款强大的单元测试框架,用来管理和组织测试用例,可应用在单元测试、自动化测试工作中。 unittest也是python语言中一款单元测试框架,但是功能...
    99+
    2024-04-02
  • SpringBoot单元测试框架Mockito介绍及使用
    目录1. 什么是mock测试2. Mockito简介3. 在SpringBoot单元测试中使用Mockito4. Mockito的限制5. 总结Mockito 是一种 Java mo...
    99+
    2023-01-04
    SpringBoot单元测试框架Mockito SpringBoot Mockito SpringBoot单元测试
  • 自动化测试Pytest单元测试框架的基本介绍
    目录一、Pytest概念二、Pytest特点三、Pytest安装安装pytest命令:查看pytest版本:安装生成测试结果的HTML报告pytest-html四、Pycharm配置...
    99+
    2024-04-02
  • Java单元测试介绍
    文章目录 单元测试单元测试基本介绍单元测试快速入门单元测试常用注解 单元测试 单元测试基本介绍 单元测试: 单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是...
    99+
    2023-08-31
    单元测试 java junit
  • Python测试框架pytest介绍
    目录一、Pytest简介二、Pytest安装三、Pytest测试执行四、测试类主函数五、断言方法六、常用命令详解七、接口调用一、Pytest简介 Pytest is a mature...
    99+
    2024-04-02
  • imba框架的简单介绍和性能测试
    这篇文章主要讲解了“imba框架的简单介绍和性能测试”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“imba框架的简单介绍和性能测试”吧!imba 简单介绍i...
    99+
    2024-04-02
  • C++ 测试框架GoogleTest入门介绍
    目录引言简单介绍初体验 引言 开发者虽然主要负责工程里的开发任务,但是每个开发完毕的功能都是需要开发者自测通过的,所以经常会听到开发者提起单元测试的话题。那么今天我就带大伙一起来看...
    99+
    2023-05-14
    C++ 测试框架GoogleTest C++ 测试框架入门
  • UnitTest单元测试框架详解
    一、什么是Unittest框架 unittest是python自带的一个单元测试框架,不仅适用于单元测试,还可用于Web、Appium、接口自动化测试用例的开发与执行;此框架可以组织执行测试用例,并且...
    99+
    2023-09-03
    python 单元测试
  • PHP中的单元测试框架
    随着软件开发领域的迅速发展,软件测试的重要性也越来越被大家所重视。单元测试是软件测试中的一个重要环节,它能够在程序开发的早期就发现潜在的问题,从而提高软件的质量和稳定性。而在PHP语言领域中,有许多非常优秀的单元测试框架,本文将介绍其中的一...
    99+
    2023-05-23
    框架 PHP 单元测试
  • JunitMockito实现单元测试方法介绍
    目录一、前言二、JUnit 框架三、Mockito 框架3.1 使用 Mockito 创建 mock 对象3.2 使用 mock 对象实践单元测试3.3 使用 PowerMock m...
    99+
    2024-04-02
  • MySQL Test Run 测试框架详细介绍
    目录一、介绍二、安装三、测试示例四、创建测试用例五、mtr其他常用参数介绍–force–record–big-test–suite=[...
    99+
    2024-04-02
  • java单元测试框架有哪些
    java中的单元测试框架有:1.JUnit,java程序测试框架;2.Spock,用于测试和规范java应用程序的框架;3.TestNG,自动化测试框架;java中的单元测试框架有以下几种JUnitJUnit是一个java程序的测试框架,可...
    99+
    2024-04-02
  • python单元测试框架有哪些
    python中的单元测试框架有unittest、nose和pytest三种unittestunittest是Python标准库中自带的单元测试框架,其具有支持自动化测试、测试用例的初始化和关闭、测试用例的聚合等功能。nosenose是一个P...
    99+
    2024-04-02
  • .NETCore单元测试的两种方法介绍
    应用程序测试的类型很多,包括集成测试,Web 测试,负载测试等。在最底层的是单元测试,此测试可以测试单个软件组件或方法。单元测试一般只测试开发人员的代码,不应该测试基础结构普、问题,...
    99+
    2024-04-02
  • php的单元测试框架有哪些
    php中常见的单元测试框架有PHPUnit、SimpleTest、Peridot PHPUnit PHPUnit是一款使用php开发的单元测试框架,由Sebastian Bergmann创建,PHPUnit提供了一系列共同、有用的功能来实现...
    99+
    2024-04-02
  • gtest单元测试框架如何使用
    使用gtest单元测试框架,需要按照以下步骤: 下载并安装gtest框架:可以从https://github.com/googl...
    99+
    2023-10-21
    gtest
  • Python中单元测试框架 Nose的安
    1 安装setuptoolsdownload地址:http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f6...
    99+
    2023-01-31
    框架 单元测试 Python
  • C#中常见的测试框架和单元测试问题
    C#中常见的测试框架和单元测试问题,需要具体代码示例引言:在软件开发过程中,测试是一个至关重要的环节。通过测试,我们可以确保代码的质量和稳定性,提高应用程序的可靠性和可维护性。C#是一种广泛应用于软件开发的编程语言,因此需要了解C#中常见的...
    99+
    2023-10-22
    测试框架: NUnit 测试框架: MSTest 单元测试问题:断言错误
  • 快速上手Java单元测试框架JUnit5
    为什么学JUnit5 Java技术栈的单元测试框架有两个:JUnit和TestNG,有种说法是TestNG比JUnit更强大,学TestNG就够了,但是当我打开GitHub看到sta...
    99+
    2024-04-02
  • Yii框架的测试武器库:单元测试、功能测试和集成测试
    范围:单元测试关注代码的特定部分,而不考虑外部依赖关系。它们验证代码的行为是否符合预期,并覆盖所有代码路径。 优点: 快速执行 容易维护 可以自动化并集成到持续集成管道中 缺点: 无法测试代码的依赖关系集成 覆盖面可能不全面,可能遗...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作