<只看这个就够了。。。>Android自动化测试及性能优化
软件自动化测试对于程序员来说能够确保软件开发的质量和效率。在Android编程中,Android集成了Junit单元测试框架,因此我们可以通过Junit来进行单元测试以及自动化测试。
1、引入Junit测试框架
在Manifest.xml配置文件中,我们需要引入Junit测试框架,因此需要在配置文件中添加如下代码:
在<application>标签中添加Junit测试库:
- <uses-library android:name="android.test.runner" />
在<manifest>标签中添加以下代码:
- <instrumentation
- android:name="android.test.InstrumentationTestRunner"
- android:label="Tests for My App"
- android:targetPackage="com.jony.androidtestdemo" />
其中android:name="android.test.InstrumentationTestRunner"表示引入Android测试类
android:label="Tests for My App"该属性的具体内容根据实际情况自行定义
android:targetPackage="com.jony.androidtestdemo"该属性定义了需要测试的包名
至此,进行单元测试需要配置的工作就全部完成了。接下来简单写几个测试用的Activity——模拟实现用户登录过程
2、业务代码编写
MainActivity.java主要作用是实现Activity界面的跳转,通过点击界面上的Button按钮,跳转到用户登录界面;
LoginActivity.java主要作用是接收用户输入的用户名和密码;
HomeActivity.java用户登录成功界面。
以上三个界面的逻辑非常简单,本文重点在于讲解Android自动化测试以及性能优化,因此复杂的业务逻辑在此就不做过多介绍。
3、单元测试
在进行单元测试前,大家可能最关注的是:怎样获得Activity的实例?
的确,这个问题是我们必须要关心的。既然我们能想到的问题,想必Android的大牛们已经给我们提供了怎么获得Activity实例的方法了。
在Android单元测试中,我们只要继承ActivityInstrumentationTestCase2 类,在其构造函数中传入需要测试的Activity,就能通过getActivity()方法获得我们需要测试的Activity的实例,具体代码如下所示:
MainActivity.java的测试代码如下所示:
- package com.jony.androidtestdemo.test;
- import android.app.Instrumentation;
- import android.test.ActivityInstrumentationTestCase2;
- import android.test.UiThreadTest;
- import android.test.suitebuilder.annotation.Suppress;
- import android.util.Log;
- import android.view.View;
- import com.jony.androidtestdemo.MainActivity;
- import com.jony.androidtestdemo.R;
- public class MainActivityTest extends
- ActivityInstrumentationTestCase2<MainActivity> {
- private static final String TAG = "MainActivityTest";
- private Instrumentation mInstrument;
- private MainActivity mActivity;
- private View mToLoginView;
- public MainActivityTest() {
- super(MainActivity.class);
- }
- @Override
- public void setUp() throws Exception {
- super.setUp();
- mInstrument = getInstrumentation();
- // 启动被测试的Activity
- mActivity = getActivity();
- mToLoginView = mActivity.findViewById(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();
- }
- }
LoginActivity.java测试代码如下所示:
- package com.jony.androidtestdemo.test;
- import android.app.Instrumentation;
- import android.test.ActivityInstrumentationTestCase2;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.View;
- import android.widget.EditText;
- import com.jony.androidtestdemo.LoginActivity;
- import com.jony.androidtestdemo.R;
- 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(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(R.id.username);
- mPasswordView = (EditText) mActivity.findViewById(R.id.password);
- mSubmitView = mActivity.findViewById(R.id.submit);
- mResetView = mActivity.findViewById(R.id.reset);
- }
- public void testPreConditions() {
- assertTrue(mUsernameView != null);
- assertTrue(mPasswordView != null);
- assertTrue(mSubmitView != null);
- assertTrue(mResetView != null);
- }
- public void testInput() {
- input();
- assertEquals("1231", mUsernameView.getText().toString());
- assertEquals("11", 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_1, KeyEvent.KEYCODE_2,
- KeyEvent.KEYCODE_3);
- // 效果同上面sendKeys之前的代码
- mInstrument.runOnMainSync(new Runnable() {
- public void run() {
- mPasswordView.requestFocus();
- }
- });
- sendKeys(KeyEvent.KEYCODE_1);
- }
- }
HomeActivity.java测试代码如下所示:
- package com.jony.androidtestdemo.test;
- import android.content.Intent;
- import android.test.ActivityUnitTestCase;
- import android.widget.TextView;
- import com.jony.androidtestdemo.HomeActivity;
- import com.jony.androidtestdemo.R;
- public class HomeActivityTest extends ActivityUnitTestCase<HomeActivity> {
- private static final String TAG = "HomeActivityTest";
- private static final String LOGIN_CONTENT = "username:1231\npassword:11";
- 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, "1231");
- intent.putExtra(HomeActivity.EXTRA_PASSWORD, "11");
- // HomeActivity有extra参数,所以我们需要以intent来启动它
- mHomeActivity = launchActivityWithIntent("com.jony.androidtestdemo",
- HomeActivity.class, intent);
- mLoginContentView = (TextView) mHomeActivity
- .findViewById(R.id.login_content);
- }
- public void testLoginContent() {
- assertEquals(LOGIN_CONTENT, mLoginContentView.getText().toString());
- }
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
- }
到此,简单的测试代码就完成了,接下来就是验证代码能否正常运行。
首先,需要将Android应用程序安装到手机或者模拟器上面才能运行测试代码,打开Eclipse的Outline窗口,选中需要测试的方法,单击右键选择Run As-->Android Junit Test
如果出现下图的绿色状态栏则说明运行成功。
Android性能测试
在Android的SDK的tools 目录中,Android为我们提供了一个性能测试工具traceview,通过traceview功能我们能够确切了解每个方法执行的时间,调用次数以及递归调用测试等信息。通过分析各方法的调用时间可以了解系统的瓶颈,提升系统性能。
使用方法:
在需要进行性能分析的Activity中加入以下代码(一般在Activity的onCreate()方法中添加):
- Debug.startMethodTracing("jonytest");//jonytest.trace
在onDestroy()方法中添加:
- Debug.stopMethodTracing();// 停止数据采集
运行程序,当程序运行到该Activity是,系统会自动记录该Activity的所调用的所有方法的信息,并生成jonytest.trace文件保存在SDcard中。将该文件导出到电脑C盘,运行以下命令:traceview jonytest.trace 系统将会弹出如图所示窗口(可以在Find窗口查找具体方法(目前只支持小写)):
至此,Android单元测试和系统优化已经给大家介绍完了,知识融会贯通,希望对大家有所帮助。
<只看这个就够了。。。>Android自动化测试及性能优化的更多相关文章
- 转——Android应用开发性能优化完全分析
[工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...
- Android 应用开发性能优化完全分析
1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...
- 【转】Android应用开发性能优化完全分析
http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关 ...
- Android应用开发性能优化完全分析
1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...
- 转:Android应用开发性能优化完全分析
转自:http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜 ...
- ym——Android之ListView性能优化
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android之ListView性能优化 假设有看过我写过的15k面试题的朋友们一定知 ...
- Android之ListView性能优化——一行代码绑定数据——万能适配器
如下图,加入现在有一个这样的需求图,你会怎么做?作为一个初学者,之前我都是直接用SimpleAdapter结合一个Item的布局来实现的,感觉这样实现起来很方便(基本上一行代码就可以实现),而且也没有 ...
- 那些Android中的性能优化
性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起. 首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应 ...
- Android应用程序性能优化Tips
对于我们设计的应用需要做到以下特征:build an app that's smooth, responsive(反应敏捷), and uses as little battery as possib ...
随机推荐
- java类同时引用父类和接口的成员变量,需要指明是父类的还是接口的
code: package com.qhong; public class Main extends B implements A{ public static void main(String[] ...
- G_M_网络流A_网络吞吐量
调了两天的代码,到最后绝望地把I64d改成lld就过了,我真的是醉了. 网络吞吐量 题面:给出一张(n个点,m条边)带权(点权边权均有)无向图,点权为每个点每秒可以接受发送的最大值,边权为花费,保证数 ...
- Python学习札记(四十三) IO 3
参考:操作文件和目录 NOTE: 1.Python内置的os模块可以直接调用操作系统提供的接口函数: 2.os.name 打印操作系统的名称:如果是posix,说明系统是Linux.Unix或Mac ...
- BZOJ 2333 【SCOI2011】 棘手的操作
题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹……但是树高严格\(\log\)的可并堆我不会啊……还是离线大法好…… 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...
- $n,$!等的含义
$$ Shell本身的PID(ProcessID)$! Shell最后运行的后台命令的PID$? 上一个运行的命令是否成功的标志,成功为0,失败不为0$* 所有参数列表.如"$*" ...
- python判断key是否存在
d = {: , : , : , : , : , : } def is_key_present(x): if x in d: print('Key is present in the dictiona ...
- jsp页面中jstl标签详解[转]
JSLT标签库,是日常开发经常使用的,也是众多标签中性能最好的.把常用的内容,放在这里备份一份,随用随查.尽量做到不用查,就可以随手就可以写出来.这算是Java程序员的基本功吧,一定要扎实. JSTL ...
- 加密算法中涉及C/C++总结
学习网站:http://www.runoob.com/cplusplus/cpp-functions.html char在VC(c++)中占1字节(byte),8位(bit). int在VC(c++) ...
- 条件查询、SQL、JPQL、HQL比较
一.什么是JPQL 在 Java EE 中,JPQL( Java 持久性查询语言)是专门为Java 应用程序访问和导航实体实例设计的.JPQL是EJB2使用的查询语言EJB QL的扩展,它继承了EJB ...
- oracle过滤某个字段重复记录,只获取一条记录
一,首先想到: 1,关键字distinct 2,group by 3,MAX,MIN这样的函数被称为聚集函数,和GROUP搭配起来用 但均无法实现,执行结果如下 举例: 表名:OffsiteOutre ...