يُجري الاختبار المحلي مباشرةً على محطة العمل الخاصة بك، بدلاً من جهاز Android أو جهاز محاكاة. وعلى هذا النحو، فإنها تستخدم جهاز Java الافتراضي المحلي (JVM)، لإجراء الاختبارات على جهاز Android تتيح لك الاختبارات المحلية تقييم منطق تطبيقك بسرعة أكبر. ومع ذلك، فإن عدم القدرة على التفاعل مع يفرض إطار عمل Android قيودًا على أنواع الاختبارات التي يمكنك إجراؤها.
يتحقّق اختبار الوحدة من سلوك قسم صغير من الرمز، وهو الوحدة ضمن الاختبار. يقوم بذلك عن طريق تنفيذ هذه التعليمة البرمجية والتحقق من النتيجة.
عادةً ما تكون اختبارات الوحدات بسيطة ولكن قد يتسبب إعدادها في حدوث مشاكل عندما يتم تشغيل قيد الاختبار مع وضع إمكانية الاختبار في الاعتبار:
- يجب أن يكون الرمز الذي تريد التحقّق منه متاحًا من خلال إجراء اختبار. بالنسبة على سبيل المثال، لا يمكنك اختبار طريقة خاصة مباشرةً. بدلاً من ذلك، يمكنك اختبار الفصل باستخدام واجهات برمجة التطبيقات العامة الخاصة به.
- من أجل إجراء اختبارات الوحدة في العزل، تعتمد تبعيات الوحدة تحت الاختبارات إلى استبدال العناصر التي تتحكم بها، مثل العناصر المزيفة أو الاختبارات المزدوجة الأخرى. تكون هذه مشكلة خاصة إذا كانت التعليمات البرمجية تعتمد على إطار عمل Android.
للتعرّف على الاستراتيجيات الشائعة لاختبار الوحدات في Android، اقرأ الخطوات التالية الاختبار.
موقع الاختبارات المحلية
يتم تلقائيًا وضع ملفات المصدر لاختبارات الوحدات المحلية في
module-name/src/test/
يتوفّر هذا الدليل حاليًا عند إنشاء دليل
مشروعك باستخدام "استوديو Android".
إضافة تبعيات الاختبار
تحتاج أيضًا إلى تكوين تبعيات الاختبار لمشروعك لاستخدام لواجهات برمجة التطبيقات القياسية التي يوفرها إطار عمل اختبار JUnit.
لإجراء ذلك، افتح ملف build.gradle
في وحدة تطبيقك وحدِّد ما يلي.
والمكتبات كتبعيات. استخدِم الدالة testImplementation
للإشارة إلى
التي تنطبق على مجموعة مصادر الاختبار المحلي، وليس على التطبيق:
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
إنشاء صف لاختبار وحدة محلية
أنت تكتب صف اختبار الوحدة المحلية كفصل اختبار من JUnit 4.
ولإجراء ذلك، أنشئ فئة تحتوي على طريقة اختبار واحدة أو أكثر، وعادةً في
module-name/src/test/
تبدأ طريقة اختبار بالتعليق التوضيحي @Test
يحتوي على التعليمات البرمجية التي يجب التدرب عليها والتحقق من جانب واحد من المكون
التي تريد اختبارها.
يوضح المثال التالي كيفية تنفيذ فئة اختبار وحدة محلية. تشير رسالة الأشكال البيانية
تحاول طريقة الاختبار emailValidator_correctEmailSimple_returnsTrue()
التحقق
isValidEmail()
، وهي طريقة داخل التطبيق. ستعرض دالة الاختبار
true إذا كان isValidEmail()
يعرض أيضًا true.
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
Java
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
يجب إنشاء اختبارات سهلة للقراءة تعمل على تقييم ما إذا كانت المكونات في ملف تعريف الارتباط
النتائج المتوقعة. ننصحك باستخدام مكتبة تأكيدات مثل
بتنسيق junit.Assert، أو Hamcrest، أو
الحقيقة: المقتطف أعلاه هو مثال على كيفية استخدام
junit.Assert
مكتبة Android للمحاكاة
عند تنفيذ اختبارات الوحدة المحلية، يتضمن المكوّن الإضافي لنظام Gradle المتوافق مع Android تحتوي على جميع واجهات برمجة التطبيقات لإطار عمل Android، مباشرةً الإصدار المستخدم في مشروعك. تحتوي المكتبة على جميع الأساليب مختلفة من واجهات برمجة التطبيقات هذه، ولكن تمت إزالة التعليمات البرمجية داخل الطرق. إن توفّرت من الطرق التي يتم الوصول إليها، يطرح الاختبار استثناءً.
يسمح ذلك بإنشاء الاختبارات المحلية عند الإشارة إلى الصفوف في نظام Android
إطار عمل مثل Context
. والأهم من ذلك، أنها تسمح لك باستخدام نموذج
إطار عمل مع فئات Android.
محاكاة لتبعيات Android
المشكلة النموذجية هي العثور على أن الفئة تستخدم مورد سلسلة. يمكنك
الحصول على موارد السلسلة من خلال استدعاء طريقة getString()
في Context
الصف. ومع ذلك، لا يمكن أن يستخدم الاختبار المحلي Context
أو أي من طرقه استنادًا إلى
ينتمون إلى إطار عمل Android. في الحالة المثالية، سيكون الاتصال بـ getString()
الخروج من الفصل، لكن هذا ليس عمليًا دائمًا. الحل هو
إنشاء نموذج تجريبي أو رمز موجز لـ Context
والذي يُرجع دائمًا القيمة نفسها عند
تم استدعاء طريقة getString()
.
من خلال مكتبة Mockable Android وأطر العمل، مثل Mockito أو MockK، التي يمكنك برمجة النماذج التجريبية لفئات Android في اختبارات الوحدة.
لإضافة كائن وهمي إلى اختبار الوحدة المحلية باستخدام نموذج Mockito، يُرجى اتّباع الخطوات التالية: نموذج البرمجة:
- ضمِّن تبعية مكتبة Mockito في ملف
build.gradle
، باسم الموضحة في إعداد بيئة الاختبار. - في بداية تعريف صف اختبار الوحدة، أضف
تعليق توضيحي واحد (
@RunWith(MockitoJUnitRunner.class)
) يوضح هذا التعليق التوضيحي عداء اختبار Mockito للتحقق من صحة استخدامك لإطار العمل تبسط تهيئة كائنات وهمية. - لإنشاء كائن وهمي لاعتمادية Android، أضِف التعليق التوضيحي
@Mock
. قبل بيان الحقل. - لإيقاف سلوك التبعية، يمكنك تحديد شرط
القيمة المعروضة عند استيفاء الشرط باستخدام
when()
وthenReturn()
الطرق.
يوضح المثال التالي كيف يمكنك إنشاء اختبار وحدة يستخدم نموذجًا تجريبيًا
كائن Context
في Kotlin تم إنشاؤه باستخدام Mockito-Kotlin.
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
لمزيد من المعلومات حول استخدام إطار عمل Mockito، يُرجى الاطّلاع على Mockito API.
المرجع والفئة SharedPreferencesHelperTest
في
رمز نموذجي يمكنك أيضًا تجربة الدرس التطبيقي حول الترميز الخاص باختبار Android.
خطأ: "الطريقة ... لم يتم تقليدها"
وتطرح مكتبة Mockable Android استثناءً إذا حاولت الوصول إلى أي من
مع الرسالة Error: "Method ... not mocked
.
إذا كانت الاستثناءات البارزة تمثل مشاكل في اختباراتك، يمكنك تغيير
بحيث تُرجع الطرق بدلاً من ذلك إما صفرًا أو صفرًا، اعتمادًا على
نوع الإرجاع. لإجراء ذلك، أضِف الإعدادات التالية في قسم مشروعك.
ملف build.gradle
من المستوى الأعلى في Groovy:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}