چگونه میتوان برای اپلیکیشن اندروید unit test نوشت؟ - بخش دوم
در مطلب قبلی به نحوه نوشتن تست های واحد با استفاده از JUnit و Mockito پرداخته شد، در ادامه سایر شیوه های نوشتن تست واحد را بررسی میکنیم، با ما همراه باشید.
نوشتن تست با استفاده از Roboelectric
Robolectric یک فریم ورک تست واحد برای اندروید میباشد. با استفاده از آن میتوانید تست واحد اندروید را بر روی JVM اجرا کنید. در صورت شکست خوردن تست، فرآیند بیلد انجام نمیشود.
برای افزودن Roboelectric به وابستگی های تست خود باید وابستگی های خود را به صورت زیر آپدیت کنید
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.0.1'
// Add Junit and mockito as testing dependencies
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
//For Roboelectric
testCompile "org.robolectric:robolectric:3.0"
}
وقتی وابستگی موردنظر را اضافه کردیم، میتوانیم تست زیر برای MainActivity بیفزاییم
package com.testsinandroid;
import org.junit.Test;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import org.robolectric.RobolectricGradleTestRunner;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
MainActivity activity;
EditText firstNumber;
EditText secondNumber;
TextView addResult;
Button btnAdd;
@Before
public void setUp() {
activity = Robolectric.setupActivity(MainActivity.class);
firstNumber = (EditText)activity.findViewById(R.id.txtNumber1);
secondNumber = (EditText)activity.findViewById(R.id.txtNumber2);
addResult = (TextView)activity.findViewById(R.id.txtResult);
btnAdd = (Button) activity.findViewById(R.id.btnAdd);
}
@Test
public void testMainActivityAddition() {
//setup
firstNumber.setText("12.2");
secondNumber.setText("13.3");
//test
btnAdd.performClick();
//verify
assertEquals(25.5, Double.parseDouble(addResult.getText().toString()), 0.0);
}
}
در تست بالا یک MainActivity Test ساخته ایم، این تست با استفاده از RoboelectricGradleTestRunner اجرا میشود.
سپس از Roboelectric Api با نام Roboelectric.setupActivity که اکتیویتی را اینیشیت میکند استفاده میکنیم که متدهایی مانند OnCreate و onStart را نیز فراخوانی میکند. سپس عناصر ویوی مختلف در اکتیویتی را گرفته و مقادیر را ست میکنیم. پس از ست شدن مقادیر، یک کلیک بر روی دکمه اجرا میکنیم. در آخر با کمک assertEqulas تایید میکنیم که TextView نتیجه شده دارای مقدار مناسب است.
همانطور که در مثال بالا مشخص است، Roboelectric نوشتن تست واحد برای کد اندروید را تسهیل میبخشد
نوشتن تست Instrumentation اندروید
اندروید شما را قادر به نوشتن تست های واحد Instrumentation میکند و این نوع تست ها بر روی گوشی واقعی اندروید به اجرا درمی آیند. از آنجا که تست بر روی گوشی اندروید انجام میشود، دیگر نیازی به شبیه سازی کلاس های اندروید نیست.
تست اجزای مختلف اندروید مانند اکتیوتی ها با استفاده از تست Instrumentation به سادگی صورت میپذیرد. اما مشکل اینجاست که به یک گوشی واقعی برای اجرای تست نیاز دارید و نمیتوان این تست را بر روی سیستم مجازی انجام داد.
جهت افزودن Instrumentation باید وابستگی های Gradle را به صورت زیر آپدیت کنید
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.0.1'
// Add Junit and mockito as testing dependencies
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
//For Roboelectric
testCompile "org.robolectric:robolectric:3.0"
//For Instrumentation tests
androidTestCompile 'com.android.support:support-annotations:25.0.1'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
}
برای نوشتن تست Instrumentation برای MainActivity، یک فایل به نام MainActivityInstrumentationTest.java بسازید.
این فایل باید در فولدر src/androidTest/java/com/testsinandroid قرار گرفته و محتوای زیر را داشته باشد
package com.testsinandroid;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.test.ViewAsserts;
import android.view.View;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import static org.junit.Assert.*;
import android.test.UiThreadTest;
public class MainActivityIntrumentationTest extends ActivityInstrumentationTestCase2<MainActivity> {
MainActivity activity;
EditText firstNumber;
EditText secondNumber;
TextView addResult;
Button btnAdd;
public MainActivityIntrumentationTest() {
super(MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(true);
activity = getActivity();
firstNumber = (EditText)activity.findViewById(R.id.txtNumber1);
secondNumber = (EditText)activity.findViewById(R.id.txtNumber2);
addResult = (TextView)activity.findViewById(R.id.txtResult);
btnAdd = (Button) activity.findViewById(R.id.btnAdd);
}
@UiThreadTest
public void testMainActivityAddition() {
//setup
firstNumber.setText("12.2");
secondNumber.setText("13.3");
//test
btnAdd.performClick();
//verify
assertEquals(25.5, Double.parseDouble(addResult.getText().toString()), 0.0);
}
}
در کد بالا، کلاس تست ویژگی های خود را از ActivityInstrumentationTestCase2 به ارث برده است.
توسط ActivityInstrumentationTestCase2 میتوانیم برای اکتیویتی تست واحد بنویسیم. باید اکتیویتی (در این شرایط MainActivity) را در سازنده این کلاس تست کنیم. پس از آن باید متد setUp را که آبجکت اکتیویتی و سایر اجزای UI از اکتیویتی را در آن میگیریم، اورراید کنیم.
سپس یک تست مینویسیم که مشابه تستی است که در بخش قبل نوشته بودیم. این تست دارای UiThreadTest@ است و از آنجایی که برخی عملگرهای UI در تست وجود دارد، بر روی ترد UI اجرا میشود.
میتوان تست instrumentation را با استفاده از کامند و بعد از وصل کردن گوشی اجرا کرد
./gradlew connectedCheck
جمع بندی
در این مقاله با روش های مختلف نوشتن تست های واحد برای کد اندروید آشنا شدیم. میتوان بسته به نیازمندی های پروژه هریک از این تست ها را بر روی پروژه های اجرا کرد. تست های واحد خودکار مزایای بلندمدت بیشماری دارند و باید آن را به عنوان بخشی از فرآیند توسعه محسوب کرد.
فریم ورک هایی معرفی شده به شما در نوشتن تست های واحد برای اپلیکیشن اندروید کمک میکنند. بسیاری از عملیات پیچیده توسط این فریم ورک ها صورت میپذیرد و شما میتوانید بر روی فرآیند تست متمرکز شوید.