2016-10-17 20:43:23 ss8860524 阅读数 1594
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19199 人正在学习 去看看 任苹蜻

              我们在进行项目开发时,为了提高项目开发效率,方便项目测试中的局部代码功能测试会用到单元测试。这样就不用重新运行一遍整个项目。长期以此我们会就节省大量的时间去做其他的事。

           首先来介绍一下如何进行单元测试:

                 A . 创建一个Android项目,我这里为TestDemo;

                 B . 配置AndroidManifest

                 C . 创建测试Class与测试Activity

                 D . 创建Android Junit Test 与 Android Application    

            

                这是我的项目结构,并且创建了MainActivity,TestActivity ,TestClass

    

                  1.在AndroidManifest配置单元测试

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testdemo"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
        </activity>
        <activity android:name="com.example.testdemo.TestActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 添加代码1 -->
        <uses-library android:name="android.test.runner" />
    </application>

    <!-- 添加代码2 -->
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:label="aaa"
        android:targetPackage="com.example.testdemo" />

</manifest>
             
                代码1:<uses-library Android:name="android.test.runner"/>代表把单元测试框架中的一些依赖库引入进来

                代码2 :<instrumentation android:name="android.test.InstrumentationTestRunner"android:targetPackage="com.example.testdemo" android:label="testd"/>代表配置单元测试框架的启动装置,启动装置有好几个类,可以选择,一般情况下我们使用上面这个。

                这里需要注意targetPackage中的包名要与项目包名一致;我这里都是com.example.testdemo


                  2.开始编写测试代码

                      MainActivity . class   :                

<pre name="code" class="java">public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		try {
			open();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void open() throws Exception {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		startActivityForResult(intent, 1);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == Activity.RESULT_OK) {
			String sdStatus = Environment.getExternalStorageState();
			if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
				Log.i("TestFile",
						"SD card is not avaiable/writeable right now.");
				return;
			}
			String name = new android.text.format.DateFormat().format(
					"yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA))
					+ ".jpg";
			Toast.makeText(this, name, Toast.LENGTH_LONG).show();
			Bundle bundle = data.getExtras();
			Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式

			FileOutputStream b = null;
			File file = new File("/sdcard/myImage/");
			file.mkdirs();// 创建文件夹
			String fileName = "/sdcard/myImage/" + name;

			try {
				b = new FileOutputStream(fileName);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} finally {
				try {
					b.flush();
					b.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}

}


                       这里我调用了摄像头的测试功能,是想展示单元测试如何在Activity进行并且是否可以测试硬件功能。

                      TestActivity .class :

public class TestActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		try {
			open();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void open() throws Exception {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		startActivityForResult(intent, 1);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == Activity.RESULT_OK) {
			String sdStatus = Environment.getExternalStorageState();
			if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
				Log.i("TestFile",
						"SD card is not avaiable/writeable right now.");
				return;
			}
			String name = new android.text.format.DateFormat().format(
					"yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA))
					+ ".jpg";
			Toast.makeText(this, name, Toast.LENGTH_LONG).show();
			Bundle bundle = data.getExtras();
			Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式

			FileOutputStream b = null;	
			File file = new File("/sdcard/myImage/");
			file.mkdirs();// 创建文件夹
			String fileName = "/sdcard/myImage/" + name;

			try {
				b = new FileOutputStream(fileName);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} finally {
				try {
					b.flush();
					b.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}

}

                        其实TestActivity与MainActivity中的代码是一样的,这是只是想展示如何切换Activity间的测试,这个问题我纠结了半天,所以我不希望这个问题困惑到大家。


                         TestClass.class :

public class TestClass extends AndroidTestCase {

	private List list;

	//这个方法是正常执行的
	public void test_1() throws Exception {
		list = new ArrayList();
		list.add("他们都说蔡睿智很帅,但他总觉得自己很丑");
		list.add("他们都说蔡睿智是男神,但他总觉得自己是男生");
		list.get(0);
	}
	
	//这个方法会抛出数组下标越界异常
	public void test_2() throws Exception {
		list = new ArrayList();
		list.add("蔡睿智不是男神");
		list.add("蔡睿智是男生");
		list.add("蔡睿智貌似是gay");
		list.get(4);
	}

	//这个数组会抛出空指针异常
	public void test_3() throws Exception{
		List list = null;
		list.add("蔡睿智是弯的");
	}

}

           下来我们进行测试操作:首先进行Activity的单元测试,选中MainActivity,会在Outline中出现这个类的目录结构,


                   然后右击红色框选的MainActivity,选中Run As选项来添加测试类。

                          这里需要注意的是  Launch 这个选项即是我们要测的那个activity,这个是根据在AndroidManifest中的这段代码来选择的测试Activity的

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

                   然后点击Run来测试我们指定的Activity。


                  接下来介绍Class的测试步骤:同样的选中的TestClass,在Outline中右击TestClass,选择Run AS

                   我这里直接选择的单个的class测试的,注意Instrumentation runner这个选项,如果没有的话,就去检查一下AndroidManifest中的Instrumentation是否写在了Application里面。然后运行

                   TestClass的测试结果如下:


                  
                      Test_1的方法抛出了数组下标越界的异常。







                      Test_2的方法抛出了空指针的异常。


                      写到这里关于Android的单元测试都写完了,欢迎大家提出自己的意见相互交流,共勉。





                       

2017-09-07 16:03:35 lplj717 阅读数 938
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19199 人正在学习 去看看 任苹蜻

基础配置:Module:app中增加相关配置

defaultConfig中增加配置testInstrumentationRunner配置:

在Android目录下配置:


在Dependencies目录下配置:


单个类单元测试

单个类的单元测试比较简单,在类中右击选择Go To--->Test

public class JUnitBean {
    public int sum(int a, int b) {
        return a + b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }
}



如果以前有写过测试类会有相关选择,如果是第一次编写可以选择Create New Test,直接创建


根据自己需要进行单元测试方法选择以及测试类的类名和包名等,点击Ok


单个类的单元测试放在test目录中,如果没有这个包可以自己创建,不影响


新建测试类之后再测试类中声明JUitBean对象,并在setUp方法中进行相关初始化,然后再测试方法中使用类调用相关方法进行测试

public class JUnitBeanTest {
    private JUnitBean bean;

    @Before
    public void setUp() throws Exception {
        //初始化对象
        bean = new JUnitBean();
    }

    @Test
    public void sum() throws Exception {
        //测试sum方法
        assertEquals(6,bean.sum(3,4));
    }

    @Test
    public void multiply() throws Exception {
        //测试multiply方法
        assertEquals(6,bean.multiply(3,2));
    }

}

测试结果,sum结果异常,multiply正常通过


简单的bean对象测试已经通过

Activity及网络请求单元测试

接下来看看Activity相关测试,建立测试类和单个类建立测试类步骤一样(需要特别注意的是测试类貌似不支持private修饰的方法,
publicprotected都可以),只是在测试类放的目录是在androidTest目录下


建立好测试类之后实现方式有两种:

第一种是使用@RunWith(AndroidJUnit4.class)

@RunWith(AndroidJUnit4.class)
public class LoginActivityTest {
    //当前Activity初始化
    @Rule
    public ActivityTestRule mActivityRule = new ActivityTestRule(LoginActivity.class);

    public LoginActivity loginActivity;
    private EditText etName;
    private EditText etPassword;
    private final Integer LOCK = 1;

    @MainThread
    @Test
    public void testLogin() {
        loginActivity = (LoginActivity) mActivityRule.getActivity();
        loginActivity.mgr.clear();
        //初始化控件
        etName = (EditText) loginActivity.findViewById(R.id.login_phone_number);
        etPassword = (EditText) loginActivity.findViewById(R.id.login_password);
        //模拟人为向输入框中输入
        onView(withId(R.id.login_phone_number)).perform(typeText("账号"), ViewActions.closeSoftKeyboard());
        onView(withId(R.id.login_password)).perform(typeText("密码"), ViewActions.closeSoftKeyboard());
        //进行网络请求
        Map<String, Object> map = new HashMap<>();
        map.put("phoneNo", etName.getText().toString());
        map.put("password", MD5Util.md5(new StringBuilder().append(Constant.ACCESS_KEY).append(etPassword.getText().toString()).toString()).toUpperCase());
        ApiCaller.call(loginActivity, new ApiCaller.MyStringCallback(loginActivity, true) {
            @Override
            public void onError(Call call, Exception e, int id) {
                super.onError(call, e, id);
            }

            @Override
            public void onResponse(String response, int id) {
                super.onResponse(response, id);
                if ("0000".equals(head.getResponseCode())) {
                    //网络请求完成后唤醒
                    synchronized (LOCK) {
                        LOCK.notify();
                    }
		//进行相关业务处理
           	 }

        });

        //网络请求是异步完成,所以在此等待
        try {
            synchronized (LOCK) {
                LOCK.wait();
            }
        } catch (InterruptedException e) {
            Assert.assertNotNull(e);
        }
    }
}



第二种是继承ActivityInstrumentationTestCase2

public class LoginActivi2Test extends ActivityInstrumentationTestCase2<LoginActivity> {

    private LoginActivity mActivity;
    private EditText etName;
    private EditText etPassword;

    public LoginActivi2Test() {
        super(LoginActivity.class);
    }

    private final Integer LOCK = 1;

    //初始化
    @Before
    public void setUp() throws Exception {
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        mActivity = this.getActivity();
        //初始化控件
        etName = (EditText) mActivity.findViewById(R.id.login_phone_number);
        etPassword = (EditText) mActivity.findViewById(R.id.login_password);

    }

    @Test
    public void testLogin2(){
        mActivity.mgr.clear();
        //仿键盘输入
        onView(withId(R.id.login_phone_number)).perform(typeText("账号"), ViewActions.closeSoftKeyboard());
        onView(withId(R.id.login_password)).perform(typeText("密码"), ViewActions.closeSoftKeyboard());
        //参数设置进行网络请求
        Map<String, Object> map = new HashMap<>();
        map.put("phoneNo", etName.getText().toString());
        map.put("password", etPassword.getText().toString());
        ApiCaller.call(mActivity, new ApiCaller.MyStringCallback(mActivity, true){
            @Override
            public void onError(Call call, Exception e, int id) {
                super.onError(call, e, id);
            }

            @Override
            public void onResponse(String response, int id) {
                super.onResponse(response, id);
                if ("0000".equals(head.getResponseCode())) {
                    //网络请求完成后唤醒
                    synchronized (LOCK) {
                        LOCK.notify();
                    }
                    //进行相关业务处理
                 }
        });
        //网络请求是异步完成,所以在此等待
        try {
            synchronized (LOCK) {
                LOCK.wait();
            }
        } catch (InterruptedException e) {
            Assert.assertNotNull(e);
        }
    }

}


经过测试两个方法都是可以进行单元测试并且可以通过测试,请多多指教

2011-03-14 13:46:17 iteye_21201 阅读数 34
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19199 人正在学习 去看看 任苹蜻
KEY:Android JUnit Android单元测试 单元测试

Menifest.xml中加入:
<application>中加入:

<uses-library android:name="android.test.runner" />

<application>外面加入:

<uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />

<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.***.***【您的项目包名】"

android:label="JUnit Test"/>

编写单元测试代码:必须继承自AndroidTestCase类


import android.test.AndroidTestCase;

import junit.framework.Assert;



public class JUnitTest extends AndroidTestCase {

private static final String Tag="JUnitTest";



public void testOne() throws Throwable

{

int i=1 + 1;

Assert.assertEquals(2,i);

}



public void testOther() throws Throwable {

Assert.assertTrue(1 + 1 == 12);

}

}
Eclipse下选择运行>>Android JUnit Test ,就OK了
2016-09-30 17:14:02 yepeng2014 阅读数 390
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19199 人正在学习 去看看 任苹蜻

android studio 单元测试

android studio新建项目会自动创建一个单元测试目录,如下图:
这里写图片描述
里面代码如下:

package com.example.xx.myapplication;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.example.xx.myapplication", appContext.getPackageName());
    }
}

右键点击运行测试
这里写图片描述

结果:
这里写图片描述

2018-04-14 14:38:58 u013144863 阅读数 106
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19199 人正在学习 去看看 任苹蜻

本篇介绍Android相关的单元测试, 本篇为系列教程的开篇, 对Android单元测试做一个系统介绍.

本系列教程将介绍在Android应用中如何编写本地单元测试和instrumentation测试(设备测试).并通过Android Studio和Gradle来执行这些测试.

Android单元测试分类

Android应用运行在各种各样的设备中.另外,Android框架和其他相关的开源框架都在高速发展.要保证应用正常运行,有必要去写Android应用测试.这将会有助于优化和改善我们的Android应用.

Android的单元测试分为下列两种:

  • 本地单元测试 - 即测试用例运行在JVM中
  • Instrumented 单元测试 - 即测试用例需要Android 系统支持,运行在真机或模拟器中

Android测试分类

相对于在Android设备上部署和运行测试所需的时间,本地的单元测试速度要快很多.如果你需要真正的Android系统环境,应首选本地单元测试,并且仅在Android平台上运行.

如果使用本地单元测试并对Android API有依赖,应该通过模拟框架(mocking framework)来替代它们,例如Mockito.

测试分布法则

我们应该把测试的关注点放在代码的业务逻辑上,下面几条是非常好的测试分布法则:

  • 70-80 % 单元测试来确保基础代码的稳定性
  • 20-30 % 功能测试来确保应用程序的功能正常工作
  • 如果应用程序与其他应用程序组件集成起来,则需要进行一些跨功能测试

测试分布规则

应该至少在一个设备上测试应用,并尽可能的减少配置.另外也应该在具有最高可用配置(例如像素密度,屏幕分辨率)的设备上进行测试,以确保其在这些设备上正常工作.

Android测试工具支持

Google的Android测试支持库(ATSL)项目为Android测试提供了工具. 例如 AndroidJUnitRunner.

如果你运行本地单元测试,那么工具会创建一个特殊版本的android.jar (也被称为Android 模拟Jar包). 这个被修改后的 JAR 文件用来提供给单元测试,以便所有Android库中的字段,方法和类都可用. 在默认情况下,对Android可模拟JAR的任何调用都会导致异常,但是你可以将Android配置为返回默认值.当然最好的方式是使用一些Mock库,具体详情可以见Android Developer官方文档.

该库提供了JUnit兼容的测试运行器(AndroidJunitRunner)、Espresso测试框架和UI Automator 测试框架. Espresso测试框架可用于测试应用程序的用户界面,UI Automator 允许编写跨应用程序的功能测试.

AndroidJunitRunner 通过InstrumentationRegistery 提供了对 instrumentation API 的访问.

  • InstrumentationRegistry.getInstrumentation(), 返回当前运行的Instrumentation
  • InstrumentationRegistry.getContext(), 返回Instrumentation包下的Context
  • InstrumentationRegistry.getTargetContext(), 返回目前应用的Context
  • InstrumentationRegistry.getArguments(), 返回传递给此Instrumentation的参数Bundle的副本.当你想访问传递给你测试工具的命令行参数时非常有用

它还可以通过ActivityLifecycleMonitorRegistry访问生命周期.

Android工程测试结构

以下是你的应用和测试代码的默认目录结构:

  • app/src/main/java - 主要应用程序构建的源代码
  • app/src/test/java - 用于任何可以运行在JVM单元测试
  • app/src/androidTest/java - 用于应该运行在Android设备上的测试

遵循上述结构,Android的构建系统就会在相应的目标(JVM或者Android设备)运行测试.

解决”error duplicate files in path”的错误

如果你收到下面的错误:”error duplicate files in path. Path in archive: LICENSE.txt”,你可以将以下内容添加到app/build.gradle文件中:

android {
    packagingOptions {
    exclude 'LICENSE.txt'
    }
}

敲行代码再睡觉

Android单元测试

阅读数 683

Android单元测试:

博文 来自: bq1073100909

android之单元测试

阅读数 315

没有更多推荐了,返回首页