Android

dependencies {
    androidTestImplementation("dev.tracera:tracera-android:<version>")
    // Optional — richer screenshots (quality/scale) + hierarchy via UiDevice:
    // androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
    // Robolectric (host):
    // testImplementation("dev.tracera:tracera-android:<version>")
}

يتطلب JDK ≥ 17 وAndroid minSdk ≥ 26 وAndroidX Test (JUnit 4 / AndroidJUnitRunner). يُفضَّل @RunWith(TraceraAndroidJUnit4::class) (انظر محوّلات الاختبار الآلي). tracera-android على Maven Central.

متغيرات البيئة ووضع التشغيل: محوّلات الاختبار الآلي.

عيّن TRACERA_* عبر testInstrumentationRunnerArguments (أو am instrument -e).

android {
    defaultConfig {
        testInstrumentationRunner = "dev.tracera.TraceraAndroidJUnitRunner"
        testInstrumentationRunnerArguments += mapOf(
            "TRACERA_BASE_URL" to "https://app.example",
            "TRACERA_AUTOTEST_TOKEN" to System.getenv("TRACERA_AUTOTEST_TOKEN")!!,
            "TRACERA_PROJECT_ID" to "1",
        )
    }
}

ربط testCaseId و autotestName

استورد واجهات JUnit 4 / AndroidX Test القياسية، وTracera من dev.tracera.

عند الإعلان (مفضّل — يعمل الربط حتى لو تخطّى الجسم مبكراً):

import dev.tracera.TraceraAndroidJUnit4
import dev.tracera.Tracera
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(TraceraAndroidJUnit4::class)
class LoginTest {
    @Tracera.Id(42, name = "e2e/login")
    @Test
    fun login() {
        assert(true)
    }
}

داخل الاختبار:

import dev.tracera.TraceraAndroidJUnit4
import dev.tracera.Tracera
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(TraceraAndroidJUnit4::class)
class LoginTest {
    @Test
    fun login() {
        Tracera.testCase(42, "e2e/login")
        assert(true)
    }
}

التخطي

استخدم تخطي JUnit القياسي (Assume.assumeTrue، @Ignore، …). سبب التخطي يُضاف إلى النتيجة كـ comment.

الخطوات

استخدم Tracera.step("…") { … } أو Tracera.suspendStep("…") { … } للكوروتينات. للتداخل استخدم Tracera.step("…") { … }. خطوات @Before / @After تذهب إلى الإعداد / التنظيف؛ خطوات جسم الاختبار إلى الاختبار. @BeforeClass / @AfterClass لا تُبلَّغ.

على الجهاز استخدم Tracera.step("…") { … } — ART لا يدعم أدوات خطوات على مستوى الدالة. على Robolectric / JVM المضيف يعمل @Tracera.Step على الدوال كما في بقية مشغّلات JVM.

import dev.tracera.TraceraAndroidJUnit4
import dev.tracera.Tracera
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(TraceraAndroidJUnit4::class)
class CheckoutTest {
    @Before
    fun openShop() {
        Tracera.step("open shop") { }
    }

    @Tracera.Id(10, name = "e2e/checkout")
    @Test
    fun checkout() {
        Tracera.step("body outer") {
            Tracera.step("nested leaf") { }
        }
        Tracera.step("pay") { }
    }
}

التعليقات والأخطاء والمرفقات

التعليقات والأخطاء والمرفقات: محوّلات الاختبار الآلي.

Tracera.comment("result-level note")
Tracera.error("result-level error text")
Tracera.step("open login") {
    Tracera.comment("landed on login")
}

لقطات الشاشة وتشخيص الجهاز

لقطات الشاشة وlogcat وتسلسل النوافذ اختيارية (ليست تلقائية). الصق القواعد الثلاث على صنف الاختبار (أو صنف أساسي). اللقطات تعمل بلا تبعيات إضافية؛ أضف androidx.test.uiautomator:uiautomator فقط إذا أردت quality / scale في Tracera.screenshot (وتسلسل النوافذ عبر UiDevice).

ScreenshotRule.Mode: FAILURE (الافتراضي) أو SUCCESS أو END.

import dev.tracera.LogcatRule
import dev.tracera.ScreenshotRule
import dev.tracera.Tracera
import dev.tracera.TraceraAndroidJUnit4
import dev.tracera.WindowHierarchyRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(TraceraAndroidJUnit4::class)
class LoginDebugTest {
    @get:Rule
    val screenshots = ScreenshotRule(mode = ScreenshotRule.Mode.FAILURE, fileName = "failure.png")

    @get:Rule
    val logcat = LogcatRule()

    @get:Rule
    val hierarchy = WindowHierarchyRule()

    @Tracera.Id(42, name = "e2e/login")
    @Test
    fun login() {
        // Optional mid-test shot:
        // Tracera.screenshot("login.png", quality = 90, scale = 1.0f)
        assert(true)
    }
}

الاختبارات ذات المعاملات

استخدم @RunWith(Parameterized::class). ضع @Tracera.Id على طريقة الاختبار. يمكن لـ name استخدام {param_id} — اسم الاختبار في JUnit (مثل login[ok]). إن حُذف name فإن autotestName يأخذ قيمة اسم الاختبار في JUnit. حقول المُنشئ لا تُملأ في القالب: إن احتجتها في الاسم فاستدعِ Tracera.testCase داخل الاختبار.

import dev.tracera.Tracera
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized

@RunWith(Parameterized::class)
class LoginRows(private val login: String) {
    companion object {
        @JvmStatic
        @Parameterized.Parameters(name = "{0}")
        fun data() = listOf(arrayOf("ok"), arrayOf("sso"))
    }

    @Before
    fun openForm() {
        Tracera.step("open form") { }
    }

    @Tracera.Id(42, name = "login as {param_id}")
    @Test
    fun login() {
        assert(login.isNotEmpty())
    }
}