由头:项目要做新版本,我打算把我知道的新知识都用起来,所以,单元测试不能少。
用的是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.youkuaiyun.com/xuguoli_beyondboy/article/details/50475728 Android Espresso单元测试
http://blog.youkuaiyun.com/javaandroid730/article/details/53327276 Android中如何简单的做单元测试 讲解常用断言方法
http://www.jianshu.com/p/9d988a2f8ff7 单元测试框架Robolectric3.0 关于Android各个组件的单元测试方法,有待学习。