کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آزمایش برنامه های کاربردی android- اندروید- تست activity اندروید

تست activity برنامه

چرخه ی حیات activity ها و کلاس instrumentation

زمانی که برنامه نویس از instrumentation به منظور تست activity های برنامه کمک می گیرد, متدهای مربوط به چرخه ی حیات آن به صورت خودکار صدا زده نمی شوند بلکه تنها متد onCreate () در صورت فراخوانی تابع () startActivity صدا زده می شود . می توان دیگر متدها را به طور مستقیم به وسیله ی توابع کمک رسانی (helper method) getInstrumentation().callActivityOn* صدا زد .

استفاده از (unit test) تست بر حسب مولفه برای آزمایش کردن activity ها

جهت تست یک activity به صورت مجزا, می توانید از کلاس ActivityUnitTestCase بهره بگیرید .
کلاس فوق این توانایی را در اختیار شما قرار می دهد که طرح بندی یا شِمای کلی (layout) activity خود را چک کرده و همچنین از فعال سازی intents ها مطابق برنامه مطمئن شوید . intent به سیستم اندروید فرستاده نمی شود ولی شما می توانید با استفاده از تابع getStartedActivityIntent() به intent های بالقوه دسترسی پیدا کرده و داده ی آن را اعتبار سنجی کنید .
ActivityUnitTestCase اکتیویتی را در IsolatedContext راه اندازی می کند, به عبارت دیگر غالباً به صورت مجزا از سیستم اندروید.
ActivityUnitTestCase را می توان به منظور امتحان کردن شِماها و متدهای مجزا در activity بکارگرفت.
از آن جایی که تست نام برده در یک IsolatedContext اجرا می شود, تست باید activity را راه اندازی کند, بدین معنا که اکتیویتی خودکار توسط سیستم اندروید راه اندازی نمی شود .

Intent intent = new Intent(getInstrumentation().getTargetContext(),
        MainActivity.class);
startActivity(intent, null, null);
 
// after this call you can get the
// Activity with getActivity() 

بکارگیری integration test (تست کلی) جهت تست activity ها

تست های عملیاتی (functional test) را می توان با استفاده از کلاس ActivityInstrumentationTestCase2 ویژه ی activity مورد نظر نوشت . این تست از کلیه ی زیرساخت های سیستم اندروید بهره جسته و به برنامه نویس اجازه می دهد با اجزإ (کامپوننت) مختلف تعامل داشته باشد . ارتباط و تعامل با زیرساخت اندروید اساساً از طریق کلاس Instrumentation صورت می پذیرد . دسترسی به کلاس ذکر شده با فراخوانی متد getInstrumentation() امکان پذیر می باشد . این کلاس امکان ارسال کلیدواژه و رویدادهای مربوط به کلیک را برای شما فراهم می کند .
توجه : در صورت استفاده از این ) test caseماندافزازها یا تجهیزات لازم برای اجرای چندین تست را فراهم می آورد), در واقع زیرساخت واقعی اندروید مورد استفاده قرار داده می شود . فراخوانی تابع getApplication() درست همان نمونه از اپلیکیشن را سرتاسر تست ها بازمی گرداند . چنانچه این امر دلخواه شما نیست, می توانید خود به صورت دستی حالت برنامه ی مورد نظر را پیش از تست مجدداً راه اندازی کنید .
در صورت تمایل می توانید مقادیر را مستقیماً تنظیم یا سِت کنید . برای این منظور باید از متد runOnUiThread() اکتیویتی مربوطه بهره بگیرید . اگر کلیه ی دستورات داخل متد با نخ رابط کاربری (UI thread) تعامل دارند, در آن صورت همچنین می توانید سیستم حاشیه نویسی (annotation) @UiThreadTest بر روی متد بکار ببرید . توجه داشته باشید که در این مورد خاص نمی توان متدهایی را مورد استفاده قرار داد که در نخ اصلی رابط کاربری (UI main thread) اجرا نمی شوند .
تستی که مبتنی بر ActivityInstrumentationTestCase2 می باشد activity را در زمینه ی استاندارد اندروید (standard Android context) راه اندازی می کند, درست مشابه زمانی که کاربر برنامه را اجرا می کند .
اگر می خواهید رویدادهای مربوط به کلید را به وسیله ی تست ارسال کنید, در آن صورت باید ) touch modeقابلیت لمس) را در برنامه ی شبیه ساز غیرفعال کنید . این کار را می توان از طریق setActivityInitialTouchMode(false) داخل متد setup () تست انجام دهید .
برای فعال سازی action (عملیات) لازمه در منو, Instrumentation.invokeMenuActionSync(context, MENU_ID,0) را مورد استفاده قرار دهید .

آزمایش حالت اولیه

پیشنهاد می کنیم وضعیت اولیه (initial state) برنامه ی مورد نظر را پیش از اینکه activity اصلی راه اندازی یا آغاز شود آزمایش کنید تا بدین وسیله مطمئن شوید تمام شرایط مورد نیاز تست برآورده شده است .

نوشتن و طراحی تست هایی ویژه ی آزمایش کردن حالت ها

برنامه نویس یا توسعه دهنده باید تست هایی طراحی کند که در نتیجه ی آن وضعیت (state) activity به حالت خود باقی بماند, حتی اگر توسط سیستم اندروید متوقف یا کاملاً خاتمه داده شود .
کلاس ActivityInstrumentationTestCase2 کلاس Instrumentation را بکار می برد که متعاقباً این قابلیت را بوجود می آورد که دستورات کنترلی چرخه ی حیات (life-cycle hooks) را مستقیماً فراخوانی کنید .

تمرین : تست بر حسب مولفه برای یک activity

ایجاد پروژه

پروژه ی جدید اندرویدی به نام com.vogella.android.test.simpleactivity ایجاد کنید, سپس activity آن را MainActivity نام گذاری کنید .
حال activity دیگری به نام SecondActivity به پروژه ی خود اضافه کنید . این activity باید از یک شِما با حداقل یک TextView استفاده کند . شناسه ی TextView باید "resultText" بوده و متن آن نیز باید روی "started" سِت شده باشد .
یک فیلد EditText به طرح بندی کلاس MainActivity خود اضافه کنید .
یک دکمه به layout ی که توسط MainActivity مورد استفاده قرار می گیرد, اضافه کنید . پس از زدن این دکمه, activity دوم باید اجرا شود . یک فیلد EditText اضافی با استفاده از کلید "text" به layout اضافه کنید . همچنین یک رشته ی http://www.tahlildadeh.com اضافی در داخل intent قرار دهید . برای این منظور کلید "URL" را بکار ببرید .
زیر نمونه کدهایی برای MainActivity فهرست شده است .

package com.vogella.android.test.simpleactivity;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
 
public class MainActivity extends Activity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
 
  public void onClick(View view) {
    Intent intent = new Intent(this, SecondActivity.class);
    intent.putExtra("URL", "http://www. tahlildadeh.com");
    startActivity(intent);
  }
} 

ساخت پروژه ی آزمایشی و کلاس

پروژه ی آزمایشی جدیدی به این نام بسازید : com.vogella.android.test.simpleactivity.test . com.vogella.android.test.simpleactivity را به عنوان پروژه ی که باید تست شود, انتخاب کنید .


تست activity اندروید
تست activity اندروید

کلاس آزمایشی MainActivityUnitTest را بر پایه ی کلاس ارشد (superclass) android.test.ActivityUnitTestCase ایجاد کنید . از این کلاس به منظور تست استفاده می شود .
Activity را در متد setup مقداردهی اولیه کنید. کلاس ایجاد شده باید شبیه به قالب زیر درآید .

package com.vogella.android.test.simpleactivity.test;
 
import android.content.Intent;
import android.test.TouchUtils;
import android.test.suitebuilder.annotation.SmallTest;
import android.widget.Button;
 
import com.vogella.android.test.simpleactivity.MainActivity;
 
public class MainActivityUnitTest extends
    android.test.ActivityUnitTestCase {
 
  private int buttonId;
  private MainActivity activity;
 
  public MainActivityUnitTest() {
    super(MainActivity.class);
  }
 
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    Intent intent = new Intent(getInstrumentation().getTargetContext(),
        MainActivity.class);
    startActivity(intent, null, null);
    activity = getActivity();
  }
 
} 

طراحی تست

یک unit test برای activity که موارد زیر را بررسی می کند بنویسید :

  • مطمئن شوید که شِمای کلی (layout) MainActivty دربردارنده ی دکمه ای است با شناسه ی R.id.button1
  • اطمینان کسب کنید متن نوشته شده روی دکمه ی مورد نظر "Start" می باشد
  • اطمینان حاصل کنید تابع getActivity.onClick() فراخوانده شده و متد getStartedActivityIntent() اینتنت (intent) مورد نظر را فعال می سازد

اعتبارسنجی

کد آزمایشی شما باید مشابه نمونه کد زیر باشد :

package com.vogella.android.test.simpleactivity.test;
 
import android.content.Intent;
import android.test.TouchUtils;
import android.test.suitebuilder.annotation.SmallTest;
import android.widget.Button;
 
import com.vogella.android.test.simpleactivity.MainActivity;
 
public class MainActivityUnitTest extends
    android.test.ActivityUnitTestCase {
 
  private int buttonId;
  private MainActivity activity;
 
  public MainActivityUnitTest() {
    super(MainActivity.class);
  }
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    Intent intent = new Intent(getInstrumentation().getTargetContext(),
        MainActivity.class);
    startActivity(intent, null, null);
    activity = getActivity();
  }
 
  public void testLayout() {
    buttonId = com.vogella.android.test.simpleactivity.R.id.button1;
    assertNotNull(activity.findViewById(buttonId));
    Button view = (Button) activity.findViewById(buttonId);
    assertEquals("Incorrect label of the button", "Start", view.getText());
  }
 
  public void testIntentTriggerViaOnClick() {
    buttonId = com.vogella.android.test.simpleactivity.R.id.button1;
    Button view = (Button) activity.findViewById(buttonId);
    assertNotNull("Button not allowed to be null", view);
 
    view.performClick();
    
    // TouchUtils cannot be used, only allowed in 
    // InstrumentationTestCase or ActivityInstrumentationTestCase2 
  
    // Check the intent which was started
    Intent triggeredIntent = getStartedActivityIntent();
    assertNotNull("Intent was null", triggeredIntent);
    String data = triggeredIntent.getExtras().getString("URL");
 
    assertEquals("Incorrect data passed via the intent",
        "http://www.vogella.com", data);
  }
 
} 

تمرین : طراحی تست های عملیاتی برای activity ها

پروژه ی آزمایشی به نام com.vogella.android.intent.simple.test بسازید . اکنون کلاس آزمایشی به نام MainActivityFunctionalTest بر پایه ی کلاس ActivityInstrumentationTestCase2 ایجاد کنید .
این کلاس را جهت طراحی integration test برای هر دو activity مورد استفاده قرار می دهیم .

package com.vogella.android.test.simpleactivity.test;
 
import android.app.Activity;
import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.ViewAsserts;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
import com.vogella.android.test.simpleactivity.R;
 
import com.vogella.android.test.simpleactivity.MainActivity;
import com.vogella.android.test.simpleactivity.SecondActivity;
 
public class MainActivityFunctionalTest extends
    ActivityInstrumentationTestCase2 {
 
  private MainActivity activity;
 
  public MainActivityFunctionalTest() {
    super(MainActivity.class);
  }
 
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    setActivityInitialTouchMode(false);
    activity = getActivity();
  }
 
}
package com.vogella.android.test.simpleactivity.test;
 
import android.app.Activity;
import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.ViewAsserts;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
import com.vogella.android.test.simpleactivity.R;
 
import com.vogella.android.test.simpleactivity.MainActivity;
import com.vogella.android.test.simpleactivity.SecondActivity;
 
public class MainActivityFunctionalTest extends
    ActivityInstrumentationTestCase2 {
 
  private MainActivity activity;
 
  public MainActivityFunctionalTest() {
    super(MainActivity.class);
  }
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    setActivityInitialTouchMode(false);
    activity = getActivity();
  }
 
  public void testStartSecondActivity() throws Exception {
   
   
   
    // add monitor to check for the second activity
    ActivityMonitor monitor =
        getInstrumentation().
          addMonitor(SecondActivity.class.getName(), null, false);
 
    // find button and click it
    Button view = (Button) activity.findViewById(R.id.button1);
   
    // TouchUtils handles the sync with the main thread internally
    TouchUtils.clickView(this, view);
 
    // to click on a click, e.g., in a listview
    // listView.getChildAt(0);
 
    // wait 2 seconds for the start of the activity
    SecondActivity startedActivity = (SecondActivity) monitor
        .waitForActivityWithTimeout(2000);
    assertNotNull(startedActivity);
 
    // search for the textView
    TextView textView = (TextView) startedActivity.findViewById(R.id.resultText);
   
    // check that the TextView is on the screen
    ViewAsserts.assertOnScreen(startedActivity.getWindow().getDecorView(),
        textView);
    // validate the text on the TextView
    assertEquals("Text incorrect", "Started", textView.getText().toString());
   
    // press back and click again
    this.sendKeys(KeyEvent.KEYCODE_BACK);
   
    TouchUtils.clickView(this, view);
  }
} 

برای تست تعریف مستقیم view, کلاس آزمایشی زیر را ویژه ی کلاس SecondActivity ایجاد کنید .

package com.vogella.android.test.simpleactivity.test;
 
import android.app.Activity;
import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.UiThreadTest;
import android.test.ViewAsserts;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
import com.vogella.android.test.simpleactivity.R;
 
import com.vogella.android.test.simpleactivity.MainActivity;
import com.vogella.android.test.simpleactivity.SecondActivity;
 
public class SecondActivityFunctionalTest extends
    ActivityInstrumentationTestCase2 {
 
  private static final String NEW_TEXT = "new text";
 
  public SecondActivityFunctionalTest() {
    super(SecondActivity.class);
  }
 
  public void testSetText() throws Exception {
 
    SecondActivity activity = getActivity();
 
    // search for the textView
    final TextView textView = (TextView) activity
        .findViewById(R.id.resultText);
 
    // set text
    getActivity().runOnUiThread(new Runnable() {
 
      @Override
      public void run() {
        textView.setText(NEW_TEXT);
      }
    });
    
    getInstrumentation().waitForIdleSync();
    assertEquals("Text incorrect", NEW_TEXT, textView.getText().toString());
 
  }
 
  @UiThreadTest
  public void testSetTextWithAnnotation() throws Exception {
 
    SecondActivity activity = getActivity();
 
    // search for the textView
    final TextView textView = (TextView) activity
        .findViewById(R.id.resultText);
 
    textView.setText(NEW_TEXT);
    assertEquals("Text incorrect", NEW_TEXT, textView.getText().toString());
 
  }
 
} 
1394/08/11 3751 2652
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...