اختبار في Kotlin: أطر العمل والأدوات لكتابة كود موثوق
Kotlin هي لغة حديثة تُستخدم بنشاط لتطوير تطبيقات Android والحلول الخادمية (Ktor، Spring Boot) والمشاريع متعددة المنصات. تعتمد جودة الكود بشكل مباشر على التغطية بالاختبارات. في هذه المقالة، سنستعرض الأدوات الرئيسية للاختبار في Kotlin: أطر العمل لكتابة الاختبارات، مكتبات المحاكاة (mocking) والأدوات المساعدة لفحص coroutines.
1. JUnit 5 — أساس الاختبار
JUnit 5 هو إطار العمل القياسي للاختبارات الوحدوية في Java/Kotlin. يوفر التعليقات التوضيحية @Test و @BeforeEach و @AfterEach وآلية التوسعات (Extensions). في Kotlin، تبدو الاختبارات موجزة:
import org.junit.jupiter.api.Testimport org.junit.jupiter.api.Assertions.*
class CalculatorTest { private val calculator = Calculator()
@Test fun `addition should work correctly`() { assertEquals(4, calculator.add(2, 2)) }
@Test fun `division by zero throws exception`() { assertThrows<ArithmeticException> { calculator.divide(10, 0) } }}ميزات استخدام JUnit 5 مع Kotlin:
- يمكن كتابة أسماء الاختبارات بين علامتي اقتباس خلفيتين (backticks) — مما يحسن قابلية القراءة.
- يعمل مع أي coroutines من خلال
@Testوتوسعةkotlinx-coroutines-test. - يدعم الاختبارات المعلمية (
@ParameterizedTest).
2. Kotest — إطار عمل قوي مخصص لـ Kotlin
Kotest (المعروف سابقًا باسم KotlinTest) هو إطار عمل متكامل تم تطويره خصيصًا لـ Kotlin. يقدم عدة أنماط لكتابة الاختبارات: String Spec و Fun Spec و Describe Spec وغيرها. مثال باستخدام التطوير الموجه بالسلوك (BDD):
import io.kotest.core.spec.style.StringSpecimport io.kotest.matchers.shouldBe
class UserServiceTest : StringSpec({ "user should be created with correct name" { val user = UserService().createUser("Alice") user.name shouldBe "Alice" user.isActive shouldBe true }})مزايا Kotest:
- مطابقات (matchers) مدمجة للمجموعات والسلاسل النصية والأرقام.
- دعم coroutines وموفري البيانات (
@TestFactory) والمهلات الزمنية. - تكوين مرن للاختبارات من خلال
projectConfig. - التكامل مع Gradle و Maven.
3. MockK — المحاكاة (mocking) لـ Kotlin
MockK هي مكتبة لإنشاء كائنات محاكاة (mock objects) تراعي خصائص Kotlin: دوال suspend ودوال التوسعة (extension functions) والفئات المختومة (sealed classes) والكائنات المفردة (object singletons). مثال على الاستخدام:
import io.mockk.*import org.junit.jupiter.api.Test
class UserServiceTest { @Test fun `should call repository when saving user`() { val repo = mockk<UserRepository>() every { repo.save(any()) } returns Unit
val service = UserService(repo) service.saveUser("Bob")
verify { repo.save(any()) } }}الإمكانيات الرئيسية لـ MockK:
mockk()— إنشاء محاكاة،spyk()— محاكاة جزئية لكائن حقيقي.coEveryوcoVerifyللعمل مع coroutines.- التحقق من ترتيب الاستدعاءات (
verifyOrder)، التقاط الوسائط (slot). - دعم التعليقات التوضيحية
@MockKو@RelaxedMockK.
4. اختبار coroutines: kotlinx-coroutines-test
عند اختبار الكود غير المتزامن القائم على coroutines، من المهم التحكم في الوقت. توفر المكتبة kotlinx-coroutines-test الدالتين runTest و TestCoroutineDispatcher:
import ko أيضاً في المكتبة
إرسال البريد الإلكتروني بلغة C++: المكتبات وأمثلة الكود
قوائم المهام لـ Rust: نظرة عامة على المكتبات والأدوات الشائعة
تكوين تطبيقات C# (.NET): Microsoft.Extensions.Configuration
إرسال البريد الإلكتروني باستخدام JavaScript (Node.js): Nodemailer، SendGrid، Mailgun