您的位置:首页 > 移动开发 > Android开发

单元测试——Android(入门篇)

2016-09-14 19:11 381 查看

一、Android中单元测试的基础使用

①、简单示例:(在android中测试加法)

public final class MathUtils {
private MathUtils(){
throw new IllegalArgumentException("该类无法实例化");
}

public static int addition(int a,int b){
return a+b;
}
}
测试类:

public class MathUtilsTest extends TestCase{

public void testMathUtils(){
assertEquals(0,MathUtils.addition(1,-1));
assertEquals(2,MathUtils.addition(1,1));
}
}


如果使用AndroidStudio会自动加载junit包

在build下能够看到:

testCompile 'junit:junit:4.12'


③、测试类如何拥有Context

作用:使用AndroidTestCase就能够为我们提供context了。

1、首先需要在build.gradle中加上,才能使用AndroidTestCase

android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
2、使用

public class ContextTest extends AndroidTestCase {
public void testContext(){
//自带了context,初始化为null,context需要设置
assertNotNull(mContext);
}

@Override
public void setUp() throws Exception {
super.setUp();
//创建Context,如果不使用该语句,Context默认为null
mContext = new MockContext();
}
}


二、Android四大组件测试

前言:本人查找的大部分文章都是使用Android自带的测试包android.test进行对四大组件的测试。但是本人使用android.test中的测试类,无法获取四大组件的对象,且找不到文档解决该问题。所以使用Robolectric框架进行单元测试,如果大家没有这种问题的话,可以尝试使用android自带的单元测试包(没找到太好的关于介绍原生单元测试的文章。。。)
例:
public class ActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

public ActivityTest() {
super(MainActivity.class);
}

@Override
public void setUp() throws Exception {
super.setUp();
assertNotNull(getInstrumentation());//返回null
assertNotNull(getActivity());//返回null
}

public void testActivity(){

}
}
1、Android提供的测试环境
①、测试文件的保存位置





首先会发现该项目中的src文件夹下多了两个文件夹androidTest与test。(稍后使用)
androidTest:主要用于进行UI测试的文件夹,存放进行UI测试的测试类。
test:主要用于进行四大组件的单元测试的文件夹,存放进行单元测试的测试类
(两个文件夹下存储的类不能重名,原因本质上是在一个文件夹下)

②、测试文件的环境
如果你的Android Studio版本是在2.0以下的话,那么还需要修改Build Variants(默认是在左下角)
例:



如果不存在则在View——>ToolWindow——>Build Variants中添加



然后打开Build Variants中的 Test Artifact,其中有两个选项:
Andorid Instrumentition Test:表示启用androidTest文件夹下的测试文件(同时 test文件夹下的测试文件将会不能使用,并变成灰色)
Unit Test:作用与上述相反。

但是如果是AS2.0以上的环境,支持同时启用androidTest和test文件夹下的测试文件。(也就是不需要使用Bulid Variants 切换测试环境了)

2、Robolectric环境配置
在项目的build.gradle中添加依赖(当前最新的是3.1.1)
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.1.1"
这里使用的是testCompile而不是平常的compile。testCompile表示是添加在test文件夹下的依赖,所以只能test文件夹下的类才能使用该依赖。所以main文件夹和androidTest文件夹是无法使用robolectric这个包的。

3、使用Robolectric测试

①、测试Activity
需求:用EditText输入文字,然后通过Button执行,显示在TextView上
制作MainActivity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<TextView
android:id="@+id/textView"
android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:hint="Enter your name here"
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"/>
<Button
android:id="@+id/btnSubmit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Say hello!"
android:layout_below="@+id/editText"
android:onClick="sayHello"/>   //这里Button注册了MainActivity的sayHello()点击监听
</RelativeLayout>
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

}

/**
* 处理Button的点击事件
*/
public void sayHello(View v){
TextView textView = (TextView) findViewById(R.id.textView);
EditText editText = (EditText) findViewById(R.id.editText);
textView.setText("Hello, " + editText.getText().toString() + "!");
}
}


进行测试:(自带的时候没有test这个文件夹的,可以使用单击右键->goTo->Test)
然后按照这种方式进行配置:





这里选择路径要多说依据,如果是AS 2.0一下使用Build Variant的伙伴,这里的路径直接点确定就好了,因为该路径已经根据你选择的Test Artifact确定好了是(创建在test文件夹,还是创建在androidTest文件夹)。
//格式,必须这样填
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)

public class MainActivityTest {
private MainActivity mActivity;
private TextView mTvContent;
private EditText mEtText;
private Button mBtnSubmit;
//表示在程序运行前执行
@Before
public void setUp() throws Exception {
//通过该方法获取Activity实例,内部执行了Activity的生命周期
mActivity = Robolectric.setupActivity(MainActivity.class);
//检查View控件是否出错。
checkWidgets();
}

private void checkWidgets(){
mTvContent = (TextView) mActivity.findViewById(R.id.textView);
Assert.assertNotNull(mTvContent);
mEtText = (EditText) mActivity.findViewById(R.id.editText);
Assert.assertNotNull(mEtText);
mBtnSubmit= (Button) mActivity.findViewById(R.id.btnSubmit);
Assert.assertNotNull(mBtnSubmit);
}
//表示在程序运行时执行
@Test
public void testSayHello() throws Exception {
//通过代码执行UI,设置EditText的数据
mEtText.setText("Peter");
//模拟点击
mBtnSubmit.performClick();
String str = "Hello, " + mEtText.getText().toString() + "!";
//需要通过Assert类来执行断言,而不是直接使用assertEquals
Assert.assertEquals(mTvContent.getText(),str);
}
}
最后,单击右键运行。

详细文档:
Android单元测试框架Robolectric3.0介绍(一):四大组件如何测试
Android单元测试框架Robolectric3.0介绍(二):日志如何输出、网络请求、数据库操作如何测试

三、Android的UI测试

1、配置Espresso的依赖
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
如果你的Android Studio版本不是API 22 的话,需要添加下面这句话,才能使用
androidTestCompile 'com.android.support:support-annotations:23.4.0'//annotations:为你当前版本号,本人为23.4.0

还需要在android.defaultConfig中加入:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

2、简单的使用espresso
//格式,固定格式
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityInstrumentationTest {

private static final String STRING_TO_BE_TYPED = "Peter";

@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
MainActivity.class);

@Test
public void sayHello(){
onView(withId(R.id.editText)).perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); //line 1
onView(withText("Say hello!")).perform(click()); //line 2
String expectedText = "Hello, " + STRING_TO_BE_TYPED + "!";
onView(withId(R.id.textView)).check(matches(withText(expectedText))); //line 3
}
}
详细资料:Espresso的详细使用

四、Espresso与Roboletric的区别

Espresso作为Google推出的Instrumentation UI测试框架,在API支持方面有着天然的优势,在推出后很大程度上替代了Robotium。而Robolectric由于只在Java虚拟机中运行,速度很快,虽然在API支持上无法和Espresso相比,但速度有很大优势,适合单元测试,尤其是TDD时使用。

五、优秀的单元测试文章

http://chriszou.com/2016/06/07/android-unit-testing-everything-you-need-to-know.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: