- 浏览: 1159494 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
MyEyeOfJava:
产生问题的主要原因:1.方洪波与南枫公司的直接主管李琼在合作共 ...
人力资源管理案例-左右为难的经理 -
吾名长弓:
学习了,作为一个管理新手,从文章里学到了很多东西,感谢 ...
2018新年管理感言 -
MyEyeOfJava:
非常不错,看过很多文章,说到管理者必然不能抛弃技术,我的主张是 ...
IT行业技术部门人员架构设计 -
小灯笼:
JMeter测试从入门到精通网盘地址:https://pan. ...
LR与Jmeter相关资料 -
flying6071:
“(2)CERT.SF:这是对摘要的签名文件。对前一步生成的M ...
Android签名与认证详细分析之一(CERT.RSA剖析)
转自:http://yuanzhifei89.iteye.com/blog/1122104 作者:yuanzhifei
测试相关资源
让开发自动化: 用 Eclipse 插件提高代码质量http://www.ibm.com/developerworks/cn/java/j-ap01117/index.html
代码测试覆盖率介绍:http://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html
学习android单元测试时遇到的一些问题:
1.开始以为单元测试一定要从程序的launch Activity,一步一步的跳转到所要测试的Activity能对其进行测试。
但实际上,我们可以从任意一个activity开始,对任意一个activity进行测试。
2.在运行单元测试之前,一定要先将要测试的程序安装到模拟器或真机上。
junit相关
android中的测试框架是扩展的junit3,所以在学习android中的单元测试签,可以先熟悉下junit3的使用,junit3要学习的东西应该并不多,就几页纸的东西。入门可以参考这个:http://android.blog.51cto.com/268543/49994
android单元测试框架中涉及的注解
@Suppress 可以用在类或这方法上,这样该类或者该方法就不会被执行
@UiThreadTest 可以用在方法上,这样该方法就会在程序的ui线程上执行
@LargeTest, @MediumTest, @SmallTest 用在方法上,标记所属的测试类型,主要是用于单独执行其中的某一类测试时使用。具体参考InstrumentationTestRunner类的文档。
@Smoke 具体用法还不清楚
android单元测试框架中涉及的一些类的uml
接下来我们以demo project来讲解如何使用android中的单元测试
主要包括了三个activity:
MainActivity:仅包含一个button,点击后就可以进入LoginActivity
LoginActivity:可以输入username, password,然后点击submit的话可进入HomeActivity,如果点击reset的话,输入的内容就会被清空
HomeActivity:在TextView中显示LoginActivity输入的内容
首先我们创建要测试的项目demo(使用了2.1)
MainActivity代码
MainActivity的布局文件
LoginActivity代码
LoginActivity的布局文件
HomeActivity代码
HomeActivity的布局文件
程序非常简单,接下来我们为demo创建单元测试工程demo_unittest
选择之前创建的工程demo,然后eclipse会自动帮我们设定api level,包名等。(测试用例的包名一般就是在要测试类的包名后加上test)
创建完后eclipse会自动为我们创建好所需的目录,Manifest.xml文件
接下来就是为要测试的类编写测试用例。关于要用哪个测试用例类,在第一张UML图中也做了简要的说明。
ActivityInstrumentationTestCase2:主要是用于进行activity的功能测试,和activity的交互测试,如activity间的跳转,ui的交互等。
ActivityInstrumentationTestCase:这个类现在已deprecated了,所以不许考虑。
SingleLaunchActivityTestCase:该测试用例仅掉用setUp和tearDown一次,而不像其它测试用例类一样,没调用一次测试方法就会重新调用一次setUp和tearDown。所以主要测试activity是否能够正确处理多次调用。
ActivityUnitTestCase:主要用于测试Activity,因为它允许注入MockContext和MockApplicaton,所以可以测试Activity在不同资源和应用下的情况。
还有Application等的测试用例比较简单,看uml图。如果觉得不够详细,可以参考sdk文档的dev guide和api reference。
MainActivityTest测试用例
LoginActivityTest测试用例
HomeActivityTest测试用例
接下来是运行测试用例,首先我们需要把要测试的程序安装到模拟器或真机上
运行测试用例,查看运行结果
这里仅仅讲了使用eclipse来进行单元测试,当然也是可以在命令行中进行单元测试的,但既然有eclipse这种图形界面的工具,就不再折腾什么命令行了。
还有就是测试用例也可以直接创建在源程序中(即源代码和测试代码放在一个项目中),具体怎么做的话google一些吧,就是把测试时涉及的一些Manifest元素移到源码工程的Manifest中等
测试相关资源
让开发自动化: 用 Eclipse 插件提高代码质量http://www.ibm.com/developerworks/cn/java/j-ap01117/index.html
代码测试覆盖率介绍:http://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html
学习android单元测试时遇到的一些问题:
1.开始以为单元测试一定要从程序的launch Activity,一步一步的跳转到所要测试的Activity能对其进行测试。
但实际上,我们可以从任意一个activity开始,对任意一个activity进行测试。
2.在运行单元测试之前,一定要先将要测试的程序安装到模拟器或真机上。
junit相关
android中的测试框架是扩展的junit3,所以在学习android中的单元测试签,可以先熟悉下junit3的使用,junit3要学习的东西应该并不多,就几页纸的东西。入门可以参考这个:http://android.blog.51cto.com/268543/49994
android单元测试框架中涉及的注解
@Suppress 可以用在类或这方法上,这样该类或者该方法就不会被执行
@UiThreadTest 可以用在方法上,这样该方法就会在程序的ui线程上执行
@LargeTest, @MediumTest, @SmallTest 用在方法上,标记所属的测试类型,主要是用于单独执行其中的某一类测试时使用。具体参考InstrumentationTestRunner类的文档。
@Smoke 具体用法还不清楚
android单元测试框架中涉及的一些类的uml
接下来我们以demo project来讲解如何使用android中的单元测试
主要包括了三个activity:
MainActivity:仅包含一个button,点击后就可以进入LoginActivity
LoginActivity:可以输入username, password,然后点击submit的话可进入HomeActivity,如果点击reset的话,输入的内容就会被清空
HomeActivity:在TextView中显示LoginActivity输入的内容
首先我们创建要测试的项目demo(使用了2.1)
MainActivity代码
public class MainActivity extends Activity { private static final boolean DEBUG = true; private static final String TAG = "-- MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { if (DEBUG) { Log.i(TAG, "onCreate"); } super.onCreate(savedInstanceState); setContentView(R.layout.act_main); View toLoginView = findViewById(R.id.to_login); toLoginView.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if (DEBUG) { Log.i(TAG, "toLoginView clicked"); } Intent intent = new Intent(getApplicationContext(), LoginActivity.class); startActivity(intent); } }); } }
MainActivity的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/to_login" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="to login" /> </LinearLayout>
LoginActivity代码
public class LoginActivity extends Activity { private static final boolean DEBUG = true; private static final String TAG = "-- LoginActivity"; private EditText mUsernameView; private EditText mPasswordView; @Override protected void onCreate(Bundle savedInstanceState) { if (DEBUG) { Log.i(TAG, "onCreate"); } super.onCreate(savedInstanceState); setContentView(R.layout.act_login); mUsernameView = (EditText) findViewById(R.id.username); mPasswordView = (EditText) findViewById(R.id.password); View submitView = findViewById(R.id.submit); submitView.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if (DEBUG) { Log.i(TAG, "submitView clicked"); } Intent intent = new Intent(getApplicationContext(), HomeActivity.class); intent.putExtra(HomeActivity.EXTRA_USERNAME, mUsernameView.getText().toString()); intent.putExtra(HomeActivity.EXTRA_PASSWORD, mPasswordView.getText().toString()); startActivity(intent); } }); View resetView = findViewById(R.id.reset); resetView.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if (DEBUG) { Log.i(TAG, "resetView clicked"); } mUsernameView.setText(""); mPasswordView.setText(""); mUsernameView.requestFocus(); } }); } }
LoginActivity的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/label_username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="username:" /> <EditText android:id="@+id/username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="text" /> <TextView android:id="@+id/label_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="password:" /> <EditText android:id="@+id/password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textPassword" /> <Button android:id="@+id/submit" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="submit" /> <Button android:id="@+id/reset" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="reset" /> </LinearLayout>
HomeActivity代码
public class HomeActivity extends Activity { private static final boolean DEBUG = true; private static final String TAG = "-- HomeActivity"; public static final String EXTRA_USERNAME = "yuan.activity.username"; public static final String EXTRA_PASSWORD = "yuan.activity.password"; @Override protected void onCreate(Bundle savedInstanceState) { if (DEBUG) { Log.i(TAG, "onCreate"); } super.onCreate(savedInstanceState); Intent intent = getIntent(); StringBuilder sb = new StringBuilder(); sb.append("username:").append(intent.getStringExtra(EXTRA_USERNAME)).append("\n"); sb.append("password:").append(intent.getStringExtra(EXTRA_PASSWORD)); setContentView(R.layout.act_home); TextView loginContentView = (TextView) findViewById(R.id.login_content); loginContentView.setText(sb.toString()); } }
HomeActivity的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/login_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center" android:textColor="#EEE" android:textStyle="bold" android:textSize="25sp" /> </LinearLayout>
程序非常简单,接下来我们为demo创建单元测试工程demo_unittest
选择之前创建的工程demo,然后eclipse会自动帮我们设定api level,包名等。(测试用例的包名一般就是在要测试类的包名后加上test)
创建完后eclipse会自动为我们创建好所需的目录,Manifest.xml文件
接下来就是为要测试的类编写测试用例。关于要用哪个测试用例类,在第一张UML图中也做了简要的说明。
ActivityInstrumentationTestCase2:主要是用于进行activity的功能测试,和activity的交互测试,如activity间的跳转,ui的交互等。
ActivityInstrumentationTestCase:这个类现在已deprecated了,所以不许考虑。
SingleLaunchActivityTestCase:该测试用例仅掉用setUp和tearDown一次,而不像其它测试用例类一样,没调用一次测试方法就会重新调用一次setUp和tearDown。所以主要测试activity是否能够正确处理多次调用。
ActivityUnitTestCase:主要用于测试Activity,因为它允许注入MockContext和MockApplicaton,所以可以测试Activity在不同资源和应用下的情况。
还有Application等的测试用例比较简单,看uml图。如果觉得不够详细,可以参考sdk文档的dev guide和api reference。
MainActivityTest测试用例
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private static final String TAG = "=== MainActivityTest"; private Instrumentation mInstrument; private MainActivity mActivity; private View mToLoginView; public MainActivityTest() { super("yuan.activity", MainActivity.class); } @Override public void setUp() throws Exception { super.setUp(); mInstrument = getInstrumentation(); // 启动被测试的Activity mActivity = getActivity(); mToLoginView = mActivity.findViewById(yuan.activity.R.id.to_login); } public void testPreConditions() { // 在执行测试之前,确保程序的重要对象已被初始化 assertTrue(mToLoginView != null); } //mInstrument.runOnMainSync(new Runnable() { // public void run() { // mToLoginView.requestFocus(); // mToLoginView.performClick(); // } //}); @UiThreadTest public void testToLogin() { // @UiThreadTest注解使整个方法在UI线程上执行,等同于上面注解掉的代码 mToLoginView.requestFocus(); mToLoginView.performClick(); } @Suppress public void testNotCalled() { // 使用了@Suppress注解的方法不会被测试 Log.i(TAG, "method 'testNotCalled' is called"); } @Override public void tearDown() throws Exception { super.tearDown(); } }
LoginActivityTest测试用例
public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> { private static final String TAG = "=== LoginActivityTest"; private Instrumentation mInstrument; private LoginActivity mActivity; private EditText mUsernameView; private EditText mPasswordView; private View mSubmitView; private View mResetView; public LoginActivityTest() { super("yuan.activity", LoginActivity.class); } @Override public void setUp() throws Exception { super.setUp(); /* * 要向程序发送key事件的话,必须在getActivity之前调用该方法来关闭touch模式 * 否则key事件会被忽略 */ setActivityInitialTouchMode(false); mInstrument = getInstrumentation(); mActivity = getActivity(); Log.i(TAG, "current activity: " + mActivity.getClass().getName()); mUsernameView = (EditText) mActivity.findViewById(yuan.activity.R.id.username); mPasswordView = (EditText) mActivity.findViewById(yuan.activity.R.id.password); mSubmitView = mActivity.findViewById(yuan.activity.R.id.submit); mResetView = mActivity.findViewById(yuan.activity.R.id.reset); } public void testPreConditions() { assertTrue(mUsernameView != null); assertTrue(mPasswordView != null); assertTrue(mSubmitView != null); assertTrue(mResetView != null); } public void testInput() { input(); assertEquals("yuan", mUsernameView.getText().toString()); assertEquals("1123", mPasswordView.getText().toString()); } public void testSubmit() { input(); mInstrument.runOnMainSync(new Runnable() { public void run() { mSubmitView.requestFocus(); mSubmitView.performClick(); } }); } public void testReset() { input(); mInstrument.runOnMainSync(new Runnable() { public void run() { mResetView.requestFocus(); mResetView.performClick(); } }); assertEquals("", mUsernameView.getText().toString()); assertEquals("", mPasswordView.getText().toString()); } @Override public void tearDown() throws Exception { super.tearDown(); } private void input() { mActivity.runOnUiThread(new Runnable() { public void run() { mUsernameView.requestFocus(); } }); // 因为测试用例运行在单独的线程上,这里最好要 // 同步application,等待其执行完后再运行 mInstrument.waitForIdleSync(); sendKeys(KeyEvent.KEYCODE_Y, KeyEvent.KEYCODE_U, KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_N); // 效果同上面sendKeys之前的代码 mInstrument.runOnMainSync(new Runnable() { public void run() { mPasswordView.requestFocus(); } }); sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3); } }
HomeActivityTest测试用例
public class HomeActivityTest extends ActivityUnitTestCase<HomeActivity> { private static final String TAG = "=== HomeActivityTest"; private static final String LOGIN_CONTENT = "username:yuan\npassword:1123"; private HomeActivity mHomeActivity; private TextView mLoginContentView; public HomeActivityTest() { super(HomeActivity.class); } @Override public void setUp() throws Exception { super.setUp(); Intent intent = new Intent(); intent.putExtra(HomeActivity.EXTRA_USERNAME, "yuan"); intent.putExtra(HomeActivity.EXTRA_PASSWORD, "1123"); // HomeActivity有extra参数,所以我们需要以intent来启动它 mHomeActivity = launchActivityWithIntent("yuan.activity", HomeActivity.class, intent); mLoginContentView = (TextView) mHomeActivity.findViewById(yuan.activity.R.id.login_content); } public void testLoginContent() { assertEquals(LOGIN_CONTENT, mLoginContentView.getText().toString()); } @Override public void tearDown() throws Exception { super.tearDown(); } }
接下来是运行测试用例,首先我们需要把要测试的程序安装到模拟器或真机上
运行测试用例,查看运行结果
这里仅仅讲了使用eclipse来进行单元测试,当然也是可以在命令行中进行单元测试的,但既然有eclipse这种图形界面的工具,就不再折腾什么命令行了。
还有就是测试用例也可以直接创建在源程序中(即源代码和测试代码放在一个项目中),具体怎么做的话google一些吧,就是把测试时涉及的一些Manifest元素移到源码工程的Manifest中等
- demo.rar (49.2 KB)
- 下载次数: 35
- demotest.rar (49.3 KB)
- 下载次数: 27
发表评论
-
[ATC]Facebook开源弱网模拟工具
2016-03-26 14:24 2749需要注意如下:1.笔者使用了linux USB网卡,是让 ... -
【远程真机管理】openstf
2016-03-24 11:36 2934网站地址:https://github.com/ope ... -
AndroidStudio性能优化
2016-03-15 16:39 1154Android Studio慢、吃内存!启动时后会立即通过Gr ... -
Drozer使用手册
2016-01-18 15:22 2240Drozer ⼯具的安装与启动:源码地址(https:// ... -
TCPDUMP抓包
2015-12-17 20:56 815tcpdump 使用方法:唯有使用文章描述的参数移动手机的 ... -
HTML5安全
2015-10-30 19:43 1330移动安全问题汇总:htt ... -
Android插件DSL配置文档
2015-07-29 15:54 1055Android Plugin DSL Reference -
Gradle-Android打包文档
2015-07-29 15:29 1839http://tools.android.com/tech- ... -
Android性能优化典范(一)
2015-06-02 17:26 13222015年伊始,Google发布 ... -
Android性能系列-电量篇
2015-05-29 16:28 1353电量篇 1) Understanding Battery ... -
Android性能系列-内存篇
2015-05-29 16:27 835内存篇 1) Memory, GC, and Perfor ... -
Android性能系列-运算篇
2015-05-29 16:26 586运算篇 1) Intro to Compute ... -
Android性能系列-渲染篇
2015-05-29 16:25 841Google近期在Udacity上发布了Android性能优 ... -
如何通过wifi在android手机上安装调试应用
2015-05-29 14:42 7081. 首先还是要打开手机 ... -
[Android]解决android65K方法引用限制
2015-01-14 11:39 1635解决方案如下: 1.Google官方的andr ... -
[Android]获取整体APP CPU信息
2015-01-07 14:34 4807通过proc获取CPU信息。adb shell cat / ... -
genymotion-安卓模拟器-IMEI修改方法
2015-01-05 15:44 4422看淘宝动辄就几十元卖这么个破玩意儿,实在是懒得说什么了,人总 ... -
[android]创建固定大小文件
2014-12-29 19:27 2216dd if=/dev/zero of=yourfile ... -
[总结]无线测试
2014-12-18 16:33 1155本文主要介绍测试在项目的各个阶段应该要做的事情、使用的工具和 ... -
[适配性]移动Webapp自适应方案
2014-12-18 16:15 1878此次方案的优化点 页面元素会随宽度的变化而自适应的放大 ...
相关推荐
在这个"android单元测试实例二"中,我们将探讨如何对一个简单的加法函数进行单元测试,以及如何在同一个项目中组织测试代码。 首先,我们要理解单元测试的基本概念。单元测试是对软件中的最小可测试单元进行检查和...
通过这个实例,你可以深入理解Android单元测试的工作原理,学会如何编写和执行测试用例,以及如何利用工具和框架优化测试流程。记住,良好的测试实践不仅能提升代码质量,还能降低维护成本,提高开发效率。
这篇内容将深入探讨Android JUnit单元测试的基本实例,帮助开发者理解如何有效地利用它来验证应用程序的功能。 首先,我们需要了解Android JUnit的基本结构。一个简单的Android JUnit测试类通常会继承自`androidx....
本Demo旨在提供一个基础的Android单元测试实践,通过实例化和运行测试用例,确保应用程序的各个组件(如Activity、Service、BroadcastReceiver等)在独立环境中正确执行。 单元测试通常使用JUnit框架进行,这是Java...
一、Android单元测试基础 单元测试是针对软件中的最小可测试单元进行验证,对于Android应用来说,这通常是指单个的Java或Kotlin类、方法或函数。通过单元测试,开发者可以在不依赖实际设备或模拟器的情况下,独立地...
Android JUnit 单元测试 在 Android 应用开发中,单元测试是一个非常重要的步骤。单元测试可以帮助开发者快速地检测应用中的错误和问题,从而提高应用的质量和 stability。Android JUnit 是一个基于 JUnit 框架的...
总结起来,Android单元测试通过`JUnit`框架和Android测试扩展,可以有效地验证代码逻辑,确保功能正确性,并促进代码的健壮性。通过创建和运行测试用例,开发者可以快速发现和修复问题,提高整体应用的质量。
本篇学习笔记主要探讨了如何在Android应用中进行单元测试,通过实例分析了其实现原理和具体步骤。下面将详细阐述这些内容。 首先,要启用单元测试,我们需要在`AndroidManifest.xml`文件中进行相应的配置。在`...
一、Android单元测试概述 1. 单元测试定义:单元测试是对软件中的最小可测试单元进行检查和验证,对于Android应用来说,这通常是一个方法或者一个类。 2. 目的:单元测试能够确保代码的独立性,帮助开发者快速定位...
Android单元测试: 首先,从是什么开始 代码和测试代码都在what子package下面 Android单元测试(三):JUnit单元测试框架的使用 代码和测试代码在junit子package下面 Android单元测试在蘑菇街支付金融部门的实践 代码和...
总结,Android单元测试通过JUnit框架配合Android测试支持库,为开发者提供了一种有效验证代码功能的方式。通过合理的测试设计和执行,可以极大地提高代码质量和项目的可靠性。在实际开发中,我们应该养成良好的测试...
12. **测试**:单元测试、集成测试,以及 Espresso 测试框架的应用。 13. **Android组件化与模块化**:理解如何将应用拆分为可重用的模块,便于维护和扩展。 14. **Gradle构建系统**:熟悉Gradle的构建脚本,理解...
14. **测试和调试**:涵盖单元测试、UI测试和 Espresso 测试框架的使用,以及Android Studio的调试工具。 15. **发布应用**:讲解如何打包APK,签名验证,以及将应用上传到Google Play Store的过程。 本教程的目的...
开发者需要使用Android Studio的内置工具进行单元测试、集成测试,确保应用在不同设备和Android版本上的兼容性。 总结来说,《Android人品测试器》的开发涵盖了Android应用的基本架构、UI设计、事件处理、数据计算...
13. **单元测试和UI测试**:如何编写和运行JUnit或Espresso测试,确保代码质量。 14. **Android模拟器与真机调试**:如何在Android Studio中配置和使用模拟器,以及连接真实设备进行调试。 15. **发布应用**:了解...