本文主要内容

  • 1、单元测验介绍
  • 2、java单元测验
  • 3、android单元测验
  • 4、常用办法介绍

1、单元测验介绍

单元测验,是指对软件中的最小可测验单元进行检查和验证。

在Java中,最小单元可所以类也可所以办法,比如刚刚开发完成一个下载的办法,此时能够用单元测验其是否ok。如果不必单元测验,用手写代码调用的方法,则工作量会较大。

运用Android studio进行单元测验,一共有两种类型,一种便是普通的java单元测验,另一种便是android单元测验,android单元测验包括对ui测验,activity的相关办法进行测验等等,需求context参数

Android单元测试

进行单元测验需求引入对应的依靠。

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选项,生成对应的单元测验文件。

Android单元测试

Android单元测试

Android单元测试

最终一步中能够选择为当前类中的哪些办法增加单元测验,也能够勾选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<MainActivity> rule = new ActivityTestRule<MainActivity>(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<MainActivity> rule = new ActivityTestRule<MainActivity>(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() 打开指定超链