由頭:項目要做新版本,我打算把我知道的新知識都用起來,所以,單元測試不能少。
用的是Espresso框架。
在src中有兩個包,分別是:test與androidTest
① test:是測試不涉及Activity,UI組件的純Java方法。
直接在電腦上直接測試。
androidTest:涉及UI,Android組件的都在該路徑下測試。
需要連接真機,或者模擬器進行測試。
② 在AS2.2中已經有現成的。在build.grade文件中:有兩部分,
testCompile 'junit:junit:4.12' ----->對應test路徑下的測試
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) ----->對應androidTest路徑下的測試
③ 使用:選中要測試的類方法:Mac上快捷鍵:command + shift + T,選擇:create new test,下一步
選擇是在test路徑下,還是androidTest路徑下創建單元測試,然後OK就可以了。
④ 實踐:
test下,簡單測試:
上源代碼,很簡單一個求和,一個求乘積
public class Caculation {
public double sum(double numA,double numB){
return numA + numB;
}
public double multiply(double numA,double numB){
return numA * numB;
}
}
按照③步驟,調用方法用到了對象,所以創建一個對象。用到了註解的方式,所以爲了方便單元測試,功能爲了更好的模塊下,方便解耦,我們還要學習dagger2 匕首2的使用姿勢.本章的題外話。
/**
* Created by liuhaoqing on 17/3/16.
*/
public class CaculationTest {
private Caculation mCaculation;
@Before //調用測試方法之前執行
public void setUP() throws Exception{
mCaculation = new Caculation();
}
@Test
public void testSum() throws Exception{
assertEquals(2,mCaculation.sum(1,1),0);//斷言 :assertEquals
}
@Test
public void testMultiply()throws Exception{
assertEquals(2,mCaculation.multiply(2,1),0);
}
}
=====================華麗分割線=============================
androidTest下,簡單測試
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="mobile.bank.ecitic.com.testdemo.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello world!"/>
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"
android:hint="Enter your name here"/>
<Button
android:id="@+id/sayHello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/editText"
android:text="Say hello!"/>
</RelativeLayout>
效果圖:
Java代碼:
package mobile.bank.ecitic.com.testdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private EditText editText;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
}
private void initUI(){
textView = (TextView) findViewById(R.id.textView);
editText = (EditText) findViewById(R.id.editText);
button = (Button) findViewById(R.id.sayHello);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("Hello:"+editText.getText().toString() + "!");
}
});
}
}
涉及UI的單元測試代碼: 有一點需要注意,在使用onView等方法時候,AS沒有提示。我找了半天以爲引入的包不對,我反覆比對,沒錯。最後我是點擊報錯提示,引入進來的。
此處有點小坑。學習摸索前進,不能避免的。具體註釋使用,見代碼註釋。
package mobile.bank.ecitic.com.testdemo;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.junit.Assert.*;
/**
* Created by liuhaoqing on 17/3/16.
*/
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
private static final String STRING_TO_BE_TYPED = "LHQ";
@Rule
public ActivityTestRule<MainActivity> mainActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class);
@Test
public void sayHello() throws Exception{
//提供onView()來注入組件,通過withId 找到組件,寫入STRING_TO_BE_TYPED所指向字符串,並關閉軟鍵盤
onView(withId(R.id.editText)).perform(typeText(STRING_TO_BE_TYPED),closeSoftKeyboard());
//點擊id爲sayHello的button
onView(withId(R.id.sayHello)).perform(click());
onView(withId(R.id.textView)).check(matches(withText("Hello:"+STRING_TO_BE_TYPED + "!")));
}
}
運行測試文件,run的時候,會自動執行代碼,執行完,紅色條表示有錯誤。綠色條表示成功。
參考文章:
感謝:http://www.jianshu.com/p/90095c989311 AndroidStudio測試(二)UI測試
http://www.jianshu.com/p/587994b4727c (三)爲什麼要用單元測試 總結
http://blog.csdn.net/xuguoli_beyondboy/article/details/50475728 Android Espresso單元測試
http://blog.csdn.net/javaandroid730/article/details/53327276 Android中如何簡單的做單元測試 講解常用斷言方法
http://www.jianshu.com/p/9d988a2f8ff7 單元測試框架Robolectric3.0 關於Android各個組件的單元測試方法,有待學習。