在实际项目开发过程中,一般先实现核心功能,最后再做辅助性功能,这样可以尽快验证Idea的正确性,同时有助于让老板、投资人或客户看到可运行的产品,从而对产品充满信心,加大对项目的支持。

但是对于我们这个项目而言,我们首先需要得到一个Android应用MVC的架构体系,因此我们首先来实现一些典型功能,但是可以完整体现MVC架构的功能。在此我们选择任何应用程序在启动时都会显示的Splash页面,通常这个页面会显示一个应用图片,过30秒左右再显示程序的主界面,应用在这段时间完成数据加载等准备工作。

在这里我们要稍微背离一下测试驱动开发的标准方法,原因是我们在进行Android应用开发,由于Android系统限制有很多方面是很难做单元测试的,硬做单元测试,除了理论上的有效性外,没有任何实际意义。

在这里,我们采用验收测试驱动开发的理念,即我们开发足够功能来满足一个验收测试用例。这里我们选择的一个验收测试用例为:应用在开启时,先显示10秒应用图片,然后自动进入应用首页,也就是我们通常所看到的Splash屏幕功能。

我们首先定义SplashActivity类,代码如下所示:

package com.bjcic.wkj;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.WindowManager;public class SplashActivity extends Activity {// 生命周期方法---开始@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//全屏setContentView(R.layout.splash);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);appModel = (AppModel)getApplication();appController = appModel.getAppController();appController.postDelayed(new Runnable() {/*** 隔10秒钟启动主页面*/@Overridepublic void run() {appController.processEvent(new AppEvent(SplashActivity.this, AppEvent.EVE_SPLASH_END, null));}}, AppKeys.SPLASH_DURATION);// 启动异步任务准备应用数据}// 生命周期方法---结束private AppController appController = null;private AppModel appModel = null;
}

这个Activity所对应的布局文件为:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" android:background="@drawable/splash"></LinearLayout>

布局文件就是定义了一下Splash屏幕的背景图。

这里我们引入了AppController类,是应用的控制器类。Activity中用户的操作和系统的状态改变都会生成相应的事件,由AppController.processEvent来进行统一处理,同时异步任务、线程等产生的需要界面更新的操作,通过向AppController发送Message来实现(因为AppController继承了Handler类)。具体代码如下所示:

package com.bjcic.wkj;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;public class AppController extends Handler {public AppController(AppModel appModel) {super();this.appModel = appModel;}/*** Activity中会根据用户的操作或系统状态,产生对应的事件,发送给AppController进行统一处理。* @param event*/public void processEvent(AppEvent event) {switch (event.getEventId()) {case AppEvent.EVE_SPLASH_END: // 从Splash界面显示主界面showMainActivity((Activity)event.getContext(), event.getParams());break;default:break;}}/*** 异步任务、线程、后台服务等需要更新界面时,向AppController发送消息即可*/@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);}/*** 关闭Splash页面并打开应用主界面* @param activity* @param params*/private void showMainActivity(Activity activity, Bundle params) {Log.d("wkj", "activity=" + activity + "; c=" + MainActivity.class + "!");Intent intent = new Intent(activity, MainActivity.class);activity.startActivity(intent);activity.finish();}private AppModel appModel = null;
}

在上面的代码中,事件处理函数直接写在的应用总的Controller中,其实也可以写到具体的Controller中,为了代码的可维护性,最好还是将事件处理写到对应模块的Controller中比较好。

下面就是AppEvent的定义:

package com.bjcic.wkj;import android.content.Context;
import android.os.Bundle;public class AppEvent {public AppEvent(Context context, int eventId, Bundle params) {this.context = context;this.eventId = eventId;this.params = params;}public Context getContext() {return context;}public void setContext(Context context) {this.context = context;}public Bundle getParams() {return params;}public int getEventId() {return eventId;}public void setEventId(int eventId) {this.eventId = eventId;}public final static int EVE_NONE = 0;public final static int EVE_SPLASH_END = 1; // Splash界面显示时间到期private Context context = null;private int eventId = 0;private Bundle params = null;
}

在上面的事件定义中,事件中包含当前的Activity,事件ID和事件参数,这样AppController就可以直接对事件进行处理了。

最后,我们在Splash页面停留10秒,这里需要定义一个常量,我们将应用中需要用到的重要常量,统一定义到AppKeys中,如下所示:

package com.bjcic.wkj;public class AppKeys {public final static long SPLASH_DURATION = 10 * 1000;
}

好的,现在可以运行这个应用程序了,如果一切正常,应该可以看到一个Splash页面显示10秒钟后,进入到程序主界面中。至此我们的第一个验收测试用例就顺利通过了。

这时,我们再回到WkjTest这个工程中,以Android Junit形式运行MainActivityTest,这时应该显示所有测试用例全部通过。

注:大家也许注意到了,测试驱动开发是以一小步一小步的开发测试为基础的,在实际工作中,有一半愉上的程序员喜欢先把所有代码写好,然后在进行调试。当然也有一部分开发人员写一点调一点,这纯属于习惯性问题,不存在孰优孰劣的问题。但是采用测试驱动开发方法学,就要采用后面的工作方式。

因此,测试驱动开发不一定适合所有人,对于喜欢一次性先把代码写好,然后进行调试的人来说,让他们接受测试驱动开发的工作方式是很困难的,这一点希望大家能够重视起来。

Android测试驱动开发实践2相关推荐

  1. Android测试驱动开发实践

    在Android应用开发中,相信很少有人在坚持先由设计人员做完整的概要设计 .详细设计,然后交给程序员进行编码实现了.通常是在有一个大体框架的情况下,就开始进行具体编码开发了.在这种情形下,开发速度可 ...

  2. 测试驱动开发实践1————项目代码生成

    [内容指引] 领域驱动开发: 云端生成项目代码: 项目代码结构介绍. 一.领域驱动开发 1."云开发"开发者社交平台概述 "云开发"开发者社交平台是一个基于互联 ...

  3. TDD测试驱动开发入门实践

    最近和团队同学们分享了测试驱动开发实践,把分享的内容同步在博客上,主要分为三个方面,简单介绍软件测试的发展历程,为什么需要使用TDD,TDD的在编码中的实践. 一,软件测试的发展历程 调试为主:  怎 ...

  4. 对测试驱动开发的一些理解

    对测试驱动开发的一些理解 测试驱动开发解决什么问题? 系统测试和集成测试不容易覆盖一些代码细节,难以做到很高的代码覆盖率:测试驱动开发编写的测试一般是单元测试,而且由开发者编写,针对单个模块容易做到各 ...

  5. 「敏捷架构」核心实践:测试驱动开发(TDD)简介

    测试驱动开发(TDD) 是一种渐进的开发方法,它结合了测试优先的开发,即在编写足够的产品代码以完成测试和重构之前编写测试.TDD的主要目标是什么?一个观点是TDD的目标是规范而不是验证(Martin, ...

  6. 【架构 Flutter实践 Clean架构 TDD测试驱动开发---1.0】

    ----------- 2022-11-12 补充 ----------- 最近在开发中尝试用了clean架构,感觉就是 麻烦...太多模板代码,很容易过度开发. 我认为了解这些理念是很重要的,但应该 ...

  7. 测试驱动开发(TDD)的实践

    测试驱动开发(TDD)的实践 本文作者: Mr.J 本文链接: https://jiangtj.com/articles/almond/test-driven%20development/ 测试驱动开 ...

  8. 测试驱动开发与行为驱动开发中的测试先行方法

    Gil Zilberfeld将在 Agile Practitioners会议上举办小型研讨会,讨论测试先行(test first)方法,测试驱动开发(TDD)和行为驱动开发(BDD)的基础. \\ \ ...

  9. 测试驱动开发 测试前移_测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做...

    测试驱动开发 测试前移 by Navdeep Singh 通过Navdeep Singh 测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做 (Test-driven developmen ...

  10. 书评:测试驱动开发的艺术

    读罢<测试驱动开发的艺术>,忽然想起中国传统文化中的"道器之辩".<易经>曰:形而上者谓之道,形而下者谓之器.中国的传统文化常常是重道轻器,认为道本器末,即 ...

最新文章

  1. java小程序查看器_JAVA的一个查看图片的小程序
  2. 整体思考自动化测试发展和价值回报
  3. java_IO流之SequenceInputStream合并流的使用
  4. 手动实现SPring中的AOP(1)
  5. DG导入mysql依赖包_MySql导入导出数据库(含远程导入导出)
  6. JAVA字符串占位符替换
  7. 马鞍山红星中学2021年高考成绩查询,2021年马鞍山高考状元名单公布,马鞍山高考状元学校资料及最高分...
  8. TPAMI 2022综述 | 视觉Transformer系统性测评及未来方向探讨
  9. java游戏暂停_小白写了个java的小游戏 想加个暂停的功能 无从下手 求大佬们帮...
  10. Windows To Go,让Windows 8移动起来!
  11. 常用sql语句及案例(oracle)
  12. 微软MED-V虚拟化实战教程之二映像准备和测试
  13. 提高网页效率的14条准则
  14. openai_ros教程( ros gazebo 深度强化学习)
  15. 最新二次开发仿包图网素材图片源码
  16. linux 下 packet_mmap 前篇 (抓包实现)
  17. R语言主题风格—ggthemes和hrbrthemes包绘图风格总览参考手册
  18. 笔记本电脑网络图标丢失解决流程
  19. [讨论]去掉office正版提醒
  20. Python内置函数—vars的具体使用方法

热门文章

  1. RS485通讯上下拉电阻的选择
  2. java关键字匹配算法_简单关键词匹配算法
  3. 多媒体技术期末复习资料
  4. 中标2020中国联通数据设备集采项目,中兴通讯备受鼓舞
  5. Nginx反向代理、静态资源下载
  6. 同花顺python_同花顺有python接口_基于python的炒股软件
  7. 非香农类信息不等式_ICLR 2020 | 北大图灵班满分论文:基于计算约束下有用信息的信息论...
  8. 告别巴蒂和你的年少时代--当Batigol成为永恒
  9. win7 64BIT下使用VC2005的问题
  10. fastboot刷系统的步骤