日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android单元测试 activity跳转 以及 input 输入后 测试

發(fā)布時間:2024/8/24 编程问答 41 如意码农
生活随笔 收集整理的這篇文章主要介紹了 android单元测试 activity跳转 以及 input 输入后 测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Android junit實現(xiàn)多個Activity跳轉(zhuǎn)測試

分類: Android Junit測試2011-11-14 16:49 1601人閱讀 評論(2) 收藏 舉報
androidjunitlayout測試單元測試exception

測試相關(guān)資源 
讓開發(fā)自動化: 用 Eclipse 插件提高代碼質(zhì)量http://www.ibm.com/developerworks/cn/java/j-ap01117/index.html

代碼測試覆蓋率介紹:http://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html

學習android單元測試時遇到的一些問題: 
1.開始以為單元測試一定要從程序的launch Activity,一步一步的跳轉(zhuǎn)到所要測試的Activity能對其進行測試。 
但實際上,我們可以從任意一個activity開始,對任意一個activity進行測試。

2.在運行單元測試之前,一定要先將要測試的程序安裝到模擬器或真機上。

junit相關(guān) 
android中的測試框架是擴展的junit3,所以在學習android中的單元測試簽,可以先熟悉下junit3的使用,junit3要學習的東西應該并不多,就幾頁紙的東西。入門可以參考這個:http://android.blog.51cto.com/268543/49994

android單元測試框架中涉及的注解 
@Suppress 可以用在類或這方法上,這樣該類或者該方法就不會被執(zhí)行 
@UiThreadTest 可以用在方法上,這樣該方法就會在程序的ui線程上執(zhí)行 
@LargeTest, @MediumTest, @SmallTest 用在方法上,標記所屬的測試類型,主要是用于單獨執(zhí)行其中的某一類測試時使用。具體參考InstrumentationTestRunner類的文檔。
@Smoke 具體用法還不清楚

android單元測試框架中涉及的一些類的uml

接下來我們以demo project來講解如何使用android中的單元測試 
主要包括了三個activity: 
MainActivity:僅包含一個button,點擊后就可以進入LoginActivity

LoginActivity:可以輸入username, password,然后點擊submit的話可進入HomeActivity,如果點擊reset的話,輸入的內(nèi)容就會被清空

HomeActivity:在TextView中顯示LoginActivity輸入的內(nèi)容

首先我們創(chuàng)建要測試的項目demo(使用了2.1)

MainActivity代碼

Java代碼

public class MainActivity extends Activity {

private static final boolean DEBUG = true;

private static final String TAG = "-- MainActivity";

@Override

protected void onCreate(Bundle savedInstanceState) {

if (DEBUG) {

Log.i(TAG, "onCreate");

}

super.onCreate(savedInstanceState);

setContentView(R.layout.act_main);

View toLoginView = findViewById(R.id.to_login);

toLoginView.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

if (DEBUG) {

Log.i(TAG, "toLoginView clicked");

}

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);

startActivity(intent);

}

});

}

}

MainActivity的布局文件

Xml代碼

  1. <LinearLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. >
  6. <Button
  7. android:id="@+id/to_login"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:layout_gravity="bottom"
  11. android:text="to login" />
  12. </LinearLayout>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<Button

android:id="@+id/to_login"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_gravity="bottom"

android:text="to login" />

</LinearLayout>

LoginActivity代碼

Java代碼

  1. public class LoginActivity extends Activity {
  2. private static final boolean DEBUG = true;
  3. private static final String TAG = "-- LoginActivity";
  4. private EditText mUsernameView;
  5. private EditText mPasswordView;
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. if (DEBUG) {
  9. Log.i(TAG, "onCreate");
  10. }
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.act_login);
  13. mUsernameView = (EditText) findViewById(R.id.username);
  14. mPasswordView = (EditText) findViewById(R.id.password);
  15. View submitView = findViewById(R.id.submit);
  16. submitView.setOnClickListener(new View.OnClickListener() {
  17. public void onClick(View view) {
  18. if (DEBUG) {
  19. Log.i(TAG, "submitView clicked");
  20. }
  21. Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
  22. intent.putExtra(HomeActivity.EXTRA_USERNAME, mUsernameView.getText().toString());
  23. intent.putExtra(HomeActivity.EXTRA_PASSWORD, mPasswordView.getText().toString());
  24. startActivity(intent);
  25. }
  26. });
  27. View resetView = findViewById(R.id.reset);
  28. resetView.setOnClickListener(new View.OnClickListener() {
  29. public void onClick(View view) {
  30. if (DEBUG) {
  31. Log.i(TAG, "resetView clicked");
  32. }
  33. mUsernameView.setText("");
  34. mPasswordView.setText("");
  35. mUsernameView.requestFocus();
  36. }
  37. });
  38. }
  39. }

public class LoginActivity extends Activity {

private static final boolean DEBUG = true;

private static final String TAG = "-- LoginActivity";

private EditText mUsernameView;

private EditText mPasswordView;

@Override

protected void onCreate(Bundle savedInstanceState) {

if (DEBUG) {

Log.i(TAG, "onCreate");

}

super.onCreate(savedInstanceState);

setContentView(R.layout.act_login);

mUsernameView = (EditText) findViewById(R.id.username);

mPasswordView = (EditText) findViewById(R.id.password);

View submitView = findViewById(R.id.submit);

submitView.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

if (DEBUG) {

Log.i(TAG, "submitView clicked");

}

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);

intent.putExtra(HomeActivity.EXTRA_USERNAME, mUsernameView.getText().toString());

intent.putExtra(HomeActivity.EXTRA_PASSWORD, mPasswordView.getText().toString());

startActivity(intent);

}

});

View resetView = findViewById(R.id.reset);

resetView.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

if (DEBUG) {

Log.i(TAG, "resetView clicked");

}

mUsernameView.setText("");

mPasswordView.setText("");

mUsernameView.requestFocus();

}

});

}

}

LoginActivity的布局文件

Xml代碼

  1. <LinearLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <TextView
  8. android:id="@+id/label_username"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:text="username:" />
  12. <EditText
  13. android:id="@+id/username"
  14. android:layout_width="fill_parent"
  15. android:layout_height="wrap_content"
  16. android:inputType="text" />
  17. <TextView
  18. android:id="@+id/label_password"
  19. android:layout_width="fill_parent"
  20. android:layout_height="wrap_content"
  21. android:text="password:" />
  22. <EditText
  23. android:id="@+id/password"
  24. android:layout_width="fill_parent"
  25. android:layout_height="wrap_content"
  26. android:inputType="textPassword" />
  27. <Button
  28. android:id="@+id/submit"
  29. android:layout_width="fill_parent"
  30. android:layout_height="wrap_content"
  31. android:text="submit" />
  32. <Button
  33. android:id="@+id/reset"
  34. android:layout_width="fill_parent"
  35. android:layout_height="wrap_content"
  36. android:text="reset" />
  37. </LinearLayout>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

>

<TextView

android:id="@+id/label_username"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="username:" />

<EditText

android:id="@+id/username"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:inputType="text" />

<TextView

android:id="@+id/label_password"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="password:" />

<EditText

android:id="@+id/password"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:inputType="textPassword" />

<Button

android:id="@+id/submit"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="submit" />

<Button

android:id="@+id/reset"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="reset" />

</LinearLayout>

HomeActivity代碼

Java代碼

public class HomeActivity extends Activity {

private static final boolean DEBUG = true;

private static final String TAG = "-- HomeActivity";

public static final String EXTRA_USERNAME = "yuan.activity.username";

public static final String EXTRA_PASSWORD = "yuan.activity.password";

@Override

protected void onCreate(Bundle savedInstanceState) {

if (DEBUG) {

Log.i(TAG, "onCreate");

}

super.onCreate(savedInstanceState);

Intent intent = getIntent();

StringBuilder sb = new StringBuilder();

sb.append("username:").append(intent.getStringExtra(EXTRA_USERNAME)).append("\n");

sb.append("password:").append(intent.getStringExtra(EXTRA_PASSWORD));

setContentView(R.layout.act_home);

TextView loginContentView = (TextView) findViewById(R.id.login_content);

loginContentView.setText(sb.toString());

}

}

HomeActivity的布局文件

Xml代碼

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<TextView

android:id="@+id/login_content"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:gravity="center"

android:textColor="#EEE"

android:textStyle="bold"

android:textSize="25sp" />

</LinearLayout>

程序非常簡單,接下來我們?yōu)閐emo創(chuàng)建單元測試工程demo_unittest

選擇之前創(chuàng)建的工程demo,然后eclipse會自動幫我們設定api level,包名等。(測試用例的包名一般就是在要測試類的包名后加上test)

創(chuàng)建完后eclipse會自動為我們創(chuàng)建好所需的目錄,Manifest.xml文件

接下來就是為要測試的類編寫測試用例。關(guān)于要用哪個測試用例類,在第一張UML圖中也做了簡要的說明。 
ActivityInstrumentationTestCase2:主要是用于進行activity的功能測試,和activity的交互測試,如activity間的跳轉(zhuǎn),ui的交互等。

ActivityInstrumentationTestCase:這個類現(xiàn)在已deprecated了,所以不許考慮。

SingleLaunchActivityTestCase:該測試用例僅掉用setUp和tearDown一次,而不像其它測試用例類一樣,每調(diào)用一次測試方法就會重新調(diào)用一次setUp和tearDown。所以主要測試activity是否能夠正確處理多次調(diào)用。

ActivityUnitTestCase:主要用于測試Activity,因為它允許注入MockContext和MockApplicaton,所以可以測試Activity在不同資源和應用下的情況。

還有Application等的測試用例比較簡單,看uml圖。如果覺得不夠詳細,可以參考sdk文檔的dev guide和api reference。

MainActivityTest測試用例

Java代碼

  1. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  2. private static final String TAG = "=== MainActivityTest";
  3. private Instrumentation mInstrument;
  4. private MainActivity mActivity;
  5. private View mToLoginView;
  6. public MainActivityTest() {
  7. super("yuan.activity", MainActivity.class);
  8. }
  9. @Override
  10. public void setUp() throws Exception {
  11. super.setUp();
  12. mInstrument = getInstrumentation();
  13. // 啟動被測試的Activity
  14. mActivity = getActivity();
  15. mToLoginView = mActivity.findViewById(yuan.activity.R.id.to_login);
  16. }
  17. public void testPreConditions() {
  18. // 在執(zhí)行測試之前,確保程序的重要對象已被初始化
  19. assertTrue(mToLoginView != null);
  20. }
  21. //mInstrument.runOnMainSync(new Runnable() {
  22. //  public void run() {
  23. //      mToLoginView.requestFocus();
  24. //      mToLoginView.performClick();
  25. //  }
  26. //});
  27. @UiThreadTest
  28. public void testToLogin() {
  29. // @UiThreadTest注解使整個方法在UI線程上執(zhí)行,等同于上面注解掉的代碼
  30. mToLoginView.requestFocus();
  31. mToLoginView.performClick();
  32. }
  33. @Suppress
  34. public void testNotCalled() {
  35. // 使用了@Suppress注解的方法不會被測試
  36. Log.i(TAG, "method 'testNotCalled' is called");
  37. }
  38. @Override
  39. public void tearDown() throws Exception {
  40. super.tearDown();
  41. }
  42. }

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

private static final String TAG = "=== MainActivityTest";

private Instrumentation mInstrument;

private MainActivity mActivity;

private View mToLoginView;

public MainActivityTest() {

super("yuan.activity", MainActivity.class);

}

@Override

public void setUp() throws Exception {

super.setUp();

mInstrument = getInstrumentation();

// 啟動被測試的Activity

mActivity = getActivity();

mToLoginView = mActivity.findViewById(yuan.activity.R.id.to_login);

}

public void testPreConditions() {

// 在執(zhí)行測試之前,確保程序的重要對象已被初始化

assertTrue(mToLoginView != null);

}

//mInstrument.runOnMainSync(new Runnable() {

//  public void run() {

//   mToLoginView.requestFocus();

//   mToLoginView.performClick();

//  }

//});

@UiThreadTest

public void testToLogin() {

// @UiThreadTest注解使整個方法在UI線程上執(zhí)行,等同于上面注解掉的代碼

mToLoginView.requestFocus();

mToLoginView.performClick();

}

@Suppress

public void testNotCalled() {

// 使用了@Suppress注解的方法不會被測試

Log.i(TAG, "method 'testNotCalled' is called");

}

@Override

public void tearDown() throws Exception {

super.tearDown();

}

}

LoginActivityTest測試用例

Java代碼

  1. public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {
  2. private static final String TAG = "=== LoginActivityTest";
  3. private Instrumentation mInstrument;
  4. private LoginActivity mActivity;
  5. private EditText mUsernameView;
  6. private EditText mPasswordView;
  7. private View mSubmitView;
  8. private View mResetView;
  9. public LoginActivityTest() {
  10. super("yuan.activity", LoginActivity.class);
  11. }
  12. @Override
  13. public void setUp() throws Exception {
  14. super.setUp();
  15. /*
  16. *  要向程序發(fā)送key事件的話,必須在getActivity之前調(diào)用該方法來關(guān)閉touch模式
  17. * 否則key事件會被忽略
  18. */
  19. setActivityInitialTouchMode(false);
  20. mInstrument = getInstrumentation();
  21. mActivity = getActivity();
  22. Log.i(TAG, "current activity: " + mActivity.getClass().getName());
  23. mUsernameView = (EditText) mActivity.findViewById(yuan.activity.R.id.username);
  24. mPasswordView = (EditText) mActivity.findViewById(yuan.activity.R.id.password);
  25. mSubmitView = mActivity.findViewById(yuan.activity.R.id.submit);
  26. mResetView = mActivity.findViewById(yuan.activity.R.id.reset);
  27. }
  28. public void testPreConditions() {
  29. assertTrue(mUsernameView != null);
  30. assertTrue(mPasswordView != null);
  31. assertTrue(mSubmitView != null);
  32. assertTrue(mResetView != null);
  33. }
  34. public void testInput() {
  35. input();
  36. assertEquals("yuan", mUsernameView.getText().toString());
  37. assertEquals("1123", mPasswordView.getText().toString());
  38. }
  39. public void testSubmit() {
  40. input();
  41. mInstrument.runOnMainSync(new Runnable() {
  42. public void run() {
  43. mSubmitView.requestFocus();
  44. mSubmitView.performClick();
  45. }
  46. });
  47. }
  48. public void testReset() {
  49. input();
  50. mInstrument.runOnMainSync(new Runnable() {
  51. public void run() {
  52. mResetView.requestFocus();
  53. mResetView.performClick();
  54. }
  55. });
  56. assertEquals("", mUsernameView.getText().toString());
  57. assertEquals("", mPasswordView.getText().toString());
  58. }
  59. @Override
  60. public void tearDown() throws Exception {
  61. super.tearDown();
  62. }
  63. private void input() {
  64. mActivity.runOnUiThread(new Runnable() {
  65. public void run() {
  66. mUsernameView.requestFocus();
  67. }
  68. });
  69. // 因為測試用例運行在單獨的線程上,這里最好要
  70. // 同步application,等待其執(zhí)行完后再運行
  71. mInstrument.waitForIdleSync();
  72. sendKeys(KeyEvent.KEYCODE_Y, KeyEvent.KEYCODE_U,
  73. KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_N);
  74. // 效果同上面sendKeys之前的代碼
  75. mInstrument.runOnMainSync(new Runnable() {
  76. public void run() {
  77. mPasswordView.requestFocus();
  78. }
  79. });
  80. sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_1,
  81. KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3);
  82. }
  83. }

public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {

private static final String TAG = "=== LoginActivityTest";

private Instrumentation mInstrument;

private LoginActivity mActivity;

private EditText mUsernameView;

private EditText mPasswordView;

private View mSubmitView;

private View mResetView;

public LoginActivityTest() {

super("yuan.activity", LoginActivity.class);

}

@Override

public void setUp() throws Exception {

super.setUp();

/*

*  要向程序發(fā)送key事件的話,必須在getActivity之前調(diào)用該方法來關(guān)閉touch模式

* 否則key事件會被忽略

*/

setActivityInitialTouchMode(false);

mInstrument = getInstrumentation();

mActivity = getActivity();

Log.i(TAG, "current activity: " + mActivity.getClass().getName());

mUsernameView = (EditText) mActivity.findViewById(yuan.activity.R.id.username);

mPasswordView = (EditText) mActivity.findViewById(yuan.activity.R.id.password);

mSubmitView = mActivity.findViewById(yuan.activity.R.id.submit);

mResetView = mActivity.findViewById(yuan.activity.R.id.reset);

}

public void testPreConditions() {

assertTrue(mUsernameView != null);

assertTrue(mPasswordView != null);

assertTrue(mSubmitView != null);

assertTrue(mResetView != null);

}

public void testInput() {

input();

assertEquals("yuan", mUsernameView.getText().toString());

assertEquals("1123", mPasswordView.getText().toString());

}

public void testSubmit() {

input();

mInstrument.runOnMainSync(new Runnable() {

public void run() {

mSubmitView.requestFocus();

mSubmitView.performClick();

}

});

}

public void testReset() {

input();

mInstrument.runOnMainSync(new Runnable() {

public void run() {

mResetView.requestFocus();

mResetView.performClick();

}

});

assertEquals("", mUsernameView.getText().toString());

assertEquals("", mPasswordView.getText().toString());

}

@Override

public void tearDown() throws Exception {

super.tearDown();

}

private void input() {

mActivity.runOnUiThread(new Runnable() {

public void run() {

mUsernameView.requestFocus();

}

});

// 因為測試用例運行在單獨的線程上,這里最好要

// 同步application,等待其執(zhí)行完后再運行

mInstrument.waitForIdleSync();

sendKeys(KeyEvent.KEYCODE_Y, KeyEvent.KEYCODE_U,

KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_N);

// 效果同上面sendKeys之前的代碼

mInstrument.runOnMainSync(new Runnable() {

public void run() {

mPasswordView.requestFocus();

}

});

sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_1,

KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3);

}

}

HomeActivityTest測試用例

Java代碼

  1. public class HomeActivityTest extends ActivityUnitTestCase<HomeActivity> {
  2. private static final String TAG = "=== HomeActivityTest";
  3. private static final String LOGIN_CONTENT = "username:yuan\npassword:1123";
  4. private HomeActivity mHomeActivity;
  5. private TextView mLoginContentView;
  6. public HomeActivityTest() {
  7. super(HomeActivity.class);
  8. }
  9. @Override
  10. public void setUp() throws Exception {
  11. super.setUp();
  12. Intent intent = new Intent();
  13. intent.putExtra(HomeActivity.EXTRA_USERNAME, "yuan");
  14. intent.putExtra(HomeActivity.EXTRA_PASSWORD, "1123");
  15. // HomeActivity有extra參數(shù),所以我們需要以intent來啟動它
  16. mHomeActivity = launchActivityWithIntent("yuan.activity", HomeActivity.class, intent);
  17. mLoginContentView = (TextView) mHomeActivity.findViewById(yuan.activity.R.id.login_content);
  18. }
  19. public void testLoginContent() {
  20. assertEquals(LOGIN_CONTENT, mLoginContentView.getText().toString());
  21. }
  22. @Override
  23. public void tearDown() throws Exception {
  24. super.tearDown();
  25. }
  26. }

public class HomeActivityTest extends ActivityUnitTestCase<HomeActivity> {

private static final String TAG = "=== HomeActivityTest";

private static final String LOGIN_CONTENT = "username:yuan\npassword:1123";

private HomeActivity mHomeActivity;

private TextView mLoginContentView;

public HomeActivityTest() {

super(HomeActivity.class);

}

@Override

public void setUp() throws Exception {

super.setUp();

Intent intent = new Intent();

intent.putExtra(HomeActivity.EXTRA_USERNAME, "yuan");

intent.putExtra(HomeActivity.EXTRA_PASSWORD, "1123");

// HomeActivity有extra參數(shù),所以我們需要以intent來啟動它

mHomeActivity = launchActivityWithIntent("yuan.activity", HomeActivity.class, intent);

mLoginContentView = (TextView) mHomeActivity.findViewById(yuan.activity.R.id.login_content);

}

public void testLoginContent() {

assertEquals(LOGIN_CONTENT, mLoginContentView.getText().toString());

}

@Override

public void tearDown() throws Exception {

super.tearDown();

}

}

接下來是運行測試用例,首先我們需要把要測試的程序安裝到模擬器或真機上

運行測試用例,查看運行結(jié)果

這里僅僅講了使用eclipse來進行單元測試,當然也是可以在命令行中進行單元測試的,但既然有eclipse這種圖形界面的工具,就不再折騰什么命令行了。 
還有就是測試用例也可以直接創(chuàng)建在源程序中(即源代碼和測試代碼放在一個項目中),具體怎么做的話google一些吧,就是把測試時涉及的一些Manifest元素移到源碼工程的Manifest中等

總結(jié)

以上是生活随笔為你收集整理的android单元测试 activity跳转 以及 input 输入后 测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。