赞
踩
本文主要内容
1、单元测试介绍
2、java单元测试
3、android单元测试
4、常用方法介绍
1、单元测试介绍
单元测试,是指对软件中的最小可测试单元进行检查和验证。
在Java中,最小单元可以是类也可以是方法,比如刚刚开发完成一个下载的方法,此时可以用单元测试其是否ok。如果不用单元测试,用手写代码调用的方式,则工作量会较大。
使用Android studio进行单元测试,一共有两种类型,一种就是普通的java单元测试,另一种就是android单元测试,android单元测试包括对ui测试,activity的相关方法进行测试等等,需要context参数
image.png
进行单元测试需要引入对应的依赖。
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
前面3个依赖包,在创建工程的时候会默认加进来,最后一个貌似不会默认添加,需要手动添加。最后一个依赖包与activity相关的单元测试有关。
2、java单元测试
以一个最简单的例子,计算器为例:
public class Util {
public static int add(int a, int b){
return a + b;
}
public int addInt(int a, int b){
return a + b;
}
}
Util类中有一个静态方法,一个非静态方法,都是简单的相加逻辑。接下来,可以右键选中方法,然后点击goto选项,生成对应的单元测试文件。
最后一步中可以选择为当前类中的哪些方法添加单元测试,也可以勾选before和after两个选项,顾名思义,before和after方法分别在单元测试前后调用,我们可以在这两个方法中做一些事情,例如初始化、回收等等。
public class UtilTest {
Util util;
@Before
public void setUp() throws Exception {
util = new Util();
System.out.println("sutup");
}
@After
public void tearDown() throws Exception {
System.out.println("tearDown");
}
@Test
public void add() {
assertEquals(2,Util.add(1, 1));
}
@Test
public void addInt() {
assertEquals(2, util.addInt(1,1));
}
}
Util类中,写了一个静态方法和非静态方法,其实就是为了演示 setUp 方法的作用,如果在单元测试中需要初始化一些类,则可以在 setUp 中初始化,在测试方法中使用已经初始化过的实例即可。
Java单元测试运行依赖于 JVM,执行单元测试方法非常简单,右键单元测试文件执行即可,也可以选择某个方法,只执行这一个方法。
3、android单元测试
Android单元测试,它依赖于Android的执行环境,也就是需要在android机器上运行。与java单元测试相比,它有一点点的不同。
前一章中讲过java单元测试,提到了 before 和 after 这两个选项,有点类似于切面编程,可以在其中做一些初始化的动作。但android中最常用的是activity,如何在activity中也添加一些周期回调函数呢?
@Rule
public ActivityTestRule rule = new ActivityTestRule(MainActivity.class){
@Override
protected Intent getActivityIntent() {
Intent intent = new Intent();
intent.putExtra("data","world");
return intent;
}
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
Log.i("okunu","before");
}
};
通过如上方式添加activity相关的单元测试周期回调函数。
getActivityIntent ,顾名思义,对启动activity的intent进行测试封装,上例中就添加了相关的参数。值得注意的是,为何 intent 中没有添加 action 呢?我猜想就是 ActivityTestRule 对象已经与MainActivity相关联了,它就是要去启动MainActivity的,加不加action都无所谓了。这里也隐含了另一层意思,要对某个activity相关的任何方法进行单元测试,都要添加与之相关联的ActivityTestRule 对象。
beforeActivityLaunched ,就是在activity启动之前执行的函数
本例中,有一个EditText,TextView和一个Button,点击Button,将EditText中的文字显示到TextView,同时也会接收Intent中的相关参数,显示在TextView中
public class MainActivity extends AppCompatActivity {
String mData;
TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mData = getIntent().getStringExtra("data");
text = (TextView)findViewById(R.id.text);
text.setText(mData != null ? mData : "");
}
public void sayHello(View view){
EditText edit = (EditText)findViewById(R.id.edit);
String str = "hello " + mData + " " + edit.getText().toString() + " !";
text.setText(str);
}
}
它的单元测试类依然可以和第2节一样生成,我们看看详细代码:
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
@Rule
public ActivityTestRule rule = new ActivityTestRule(MainActivity.class){
@Override
protected Intent getActivityIntent() {
Intent intent = new Intent();
intent.putExtra("data","world");
return intent;
}
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
Log.i("okunu","before");
}
};
Context appContext;
@Before
public void setUp() throws Exception {
Log.i("okunu","setUp");
appContext = InstrumentationRegistry.getTargetContext();
}
@After
public void tearDown() throws Exception {
Log.i("okunu","tearDown");
}
@Test
public void sayHello() {
onView(withId(R.id.edit)).perform(typeText("jim"), closeSoftKeyboard()); //line 1
onView(withText("hello")).perform(click()); //line 2
String expectedText = "hello " + "world " + "jim" + " !";
onView(withId(R.id.text)).check(matches(withText(expectedText))); //line 3
}
}
注意,context是可以获取的。另外最重要的就是理解这几个生命周期回调函数的作用。可以在setUp函数中获取context,如果与activity启动相关的要改动,则在ActivityTestRule类中修改即可。
4、常用方法介绍
在android单元测试中需要获取到某个view,如何获取呢?
withText:通过文本来获取对象,如:ViewInteraction save = onView(withText(“保存”)) ;
withId:通过id来获取对象,如:ViewInteraction save = onView(withId(R.id.save)) ;
通过文本获取,如上例,如果某个view上的文本是“保存”,则返回此view。通过id获取就比较容易理解了,建议使用id方式。
那么对view操作的接口又有哪些呢?
使用方式是onView(…).perform() 。也可以执行多个操作在一个perform中如:perform(click(),clearText()) 。所有的操作都有一个前提 ———— 就是要执行的view必须在当前界面上显示出来(有且可见)。
方法名
含义
click()
点击view
clearText()
清除文本内容
swipeLeft()
从右往左滑
swipeRight()
从左往右滑
swipeDown()
从上往下滑
swipeUp()
从下往上滑
click()
点击view
closeSoftKeyboard()
关闭软键盘
pressBack()
按下物理返回键
doubleClick()
双击
longClick()
长按
scrollTo()
滚动
replaceText()
替换文本
openLinkWithText()
打开指定超链
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。