Health Connect की टेस्टिंग लाइब्रेरी का इस्तेमाल करके यूनिट टेस्ट बनाना

Health Connect की टेस्टिंग लाइब्रेरी (androidx.health.connect:connect-testing) ऑटोमेटेड टेस्ट को बनाना आसान बनाता है. पुष्टि करने के लिए, इस लाइब्रेरी का इस्तेमाल किया जा सकता है आपके ऐप्लिकेशन के काम करने के तरीके को समझ सकता है. साथ ही, इस बात की पुष्टि कर सकता है कि वह ऐसे असामान्य मामले हैं जिनकी मैन्युअल तौर पर जांच करना मुश्किल होता है.

लाइब्रेरी का इस्तेमाल करके, लोकल यूनिट टेस्ट बनाए जा सकते हैं. आम तौर पर, ये टेस्ट आपके ऐप्लिकेशन में मौजूद उन क्लास के व्यवहार की जानकारी जो Health Connect के साथ इंटरैक्ट करती हैं क्लाइंट के लिए भी ऐसा ही किया जा सकता है.

लाइब्रेरी का इस्तेमाल शुरू करने के लिए, इसे टेस्ट डिपेंडेंसी के तौर पर जोड़ें:

 testImplementation("androidx.health.connect:connect-testing:1.0.0-alpha01")

लाइब्रेरी का एंट्री पॉइंट FakeHealthConnectClient क्लास है, जिसे का इस्तेमाल HealthConnectClient को बदलने के लिए किया जाता है. FakeHealthConnectClient में ये सुविधाएँ शामिल हैं:

  • यह मेमोरी में सेव रिकॉर्ड को दिखाता है, ताकि आपके पास उन्हें शामिल करने, हटाने, मिटाने और उन्हें पढ़ें
  • बदलाव के लिए टोकन जनरेट करना और बदलाव को ट्रैक करना
  • रिकॉर्ड और बदलावों के लिए, पेज पर नंबर डालना
  • एग्रीगेशन रिस्पॉन्स, स्टब के साथ काम करते हैं
  • किसी भी फ़ंक्शन को अपवाद देने की अनुमति देता है
  • अनुमतियों की जांच को एम्युलेट करने के लिए इस्तेमाल किया जा सकने वाला FakePermissionController

टेस्ट में डिपेंडेंसी बदलने के बारे में ज़्यादा जानने के लिए, पढ़ें Android में डिपेंडेंसी इंजेक्शन. नकली चीज़ों के बारे में ज़्यादा जानने के लिए, पढ़ें Android में टेस्ट डबल्स का इस्तेमाल करना.

उदाहरण के लिए, अगर क्लाइंट से इंटरैक्ट करने वाली क्लास को कॉल किया जाता है HealthConnectManager है और यह HealthConnectClient को डिपेंडेंसी के तौर पर लेता है, यह ऐसा दिखेगा:

class HealthConnectManager(
    private val healthConnectClient: HealthConnectClient,
    ...
) { }

टेस्ट में, इसकी जगह किसी नकली क्लास को टेस्ट में पास किया जा सकता है:

import androidx.health.connect.client.testing.ExperimentalTestingApi
import androidx.health.connect.client.testing.FakeHealthConnectClient
import kotlinx.coroutines.test.runTest

@OptIn(ExperimentalTestingApi::class)
class HealthConnectManagerTest {

    @Test
    fun readRecords_filterByActivity() = runTest {
        // Create a Fake with 2 running records.
        val fake = FakeHealthConnectClient()
        fake.insertRecords(listOf(fakeRunRecord1, fakeBikeRecord1))

        // Create a manager that depends on the fake.
        val manager = HealthConnectManager(fake)

        // Read running records only.
        val runningRecords = manager.fetchReport(activity = Running)

        // Verify that the records were filtered correctly.
        assertTrue(runningRecords.size == 1)
    }
}

इस परीक्षण से पुष्टि होगी कि काल्पनिक fetchReport फ़ंक्शन में HealthConnectManager, गतिविधि के हिसाब से रिकॉर्ड को सही तरीके से फ़िल्टर करता है.

अपवादों की पुष्टि की जा रही है

HealthConnectClient पर किए जाने वाले करीब-करीब हर कॉल में अपवाद हो सकते हैं. उदाहरण के लिए, insertRecords के दस्तावेज़ में इन अपवादों का उल्लेख किया गया है:

  • आईपीसी ट्रांसपोर्टेशन में हुई किसी भी गड़बड़ी के लिए @throws android.os.RemoteException.
  • बिना अनुमति वाले ऐक्सेस वाले अनुरोधों के लिए @throws SecurityException.
  • डिस्क I/O से जुड़ी किसी भी समस्या के लिए @throws java.io.IOException.

ये अपवाद इस तरह के मामलों को कवर करते हैं: खराब कनेक्शन या कोई जगह खाली न होना डिवाइस. आपके ऐप्लिकेशन को रनटाइम की इन समस्याओं पर सही तरीके से प्रतिक्रिया देनी चाहिए, ताकि वे ऐसा कर सकें किसी भी समय हो सकती है.

import androidx.health.connect.client.testing.stubs.stub

@Test
fun addRecords_throwsRemoteException_errorIsExposed() {
    // Create Fake that throws a RemoteException
    // when insertRecords is called.
    val fake = FakeHealthConnectClient()
    fake.overrides.insertRecords = stub { throw RemoteException() }

    // Create a manager that depends on the fake.
    val manager = HealthConnectManager(fake)

    // Insert a record.
    manager.addRecords(fakeRunRecord1)

    // Verify that the manager is exposing an error.
    assertTrue(manager.errors.size == 1)
}

एक साथ दिखाना

एग्रीगेशन कॉल में गलत तरीकों को लागू नहीं किया जाता है. इसके बजाय, एग्रीगेशन कॉल स्टब का इस्तेमाल करते हैं, जिन्हें आप एक खास तरीके से काम करने के लिए प्रोग्राम कर सकते हैं. एडमिन पेज पर, FakeHealthConnectClient की overrides प्रॉपर्टी से स्टब करता है.

उदाहरण के लिए, कोई खास नतीजा पाने के लिए एग्रीगेट फ़ंक्शन को प्रोग्राम किया जा सकता है:

import androidx.health.connect.client.testing.AggregationResult
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.ExerciseSessionRecord
import java.time.Duration

@Test
fun aggregate() {
    // Create a fake result.
    val result =
        AggregationResult(metrics =
            buildMap {
                put(HeartRateRecord.BPM_AVG, 74.0)
                put(
                    ExerciseSessionRecord.EXERCISE_DURATION_TOTAL,
                    Duration.ofMinutes(30)
                )
            }
        )

    // Create a fake that always returns the fake
    // result when aggregate() is called.
    val fake = FakeHealthConnectClient()
    fake.overrides.aggregate = stub(result)

इसके बाद, इस बात की पुष्टि की जा सकती है कि आपकी क्लास HealthConnectManager टेस्ट चल रही है केस, नतीजे को सही तरीके से प्रोसेस किया गया:

// Create a manager that depends on the fake.
val manager = HealthConnectManager(fake)
// Call the function that in turn calls aggregate on the client.
val report = manager.getHeartRateReport()

// Verify that the manager is exposing an error.
assertThat(report.bpmAverage).isEqualTo(74.0)

अनुमतियां

टेस्टिंग लाइब्रेरी में एक FakePermissionController होता है, जिसे पास किया जा सकता है FakeHealthConnectClient पर निर्भरता के तौर पर.

टेस्ट में शामिल आपका विषय, PermissionController—through जांच करने के लिए, HealthConnectClient इंटरफ़ेस की permissionController प्रॉपर्टी देखें. आम तौर पर, क्लाइंट को किए जाने वाले हर कॉल से पहले ऐसा किया जाता है.

इस सुविधा की जांच करने के लिए, आपके पास यह सेट करने का विकल्प होता है कि कौनसी अनुमतियां उपलब्ध हों FakePermissionController:

import androidx.health.connect.client.testing.FakePermissionController

@Test
fun newRecords_noPermissions_errorIsExposed() {
    // Create a permission controller with no permissions.
    val permissionController = FakePermissionController(grantAll = false)

    // Create a fake client with the permission controller.
    val fake = FakeHealthConnectClient(permissionController = permissionController)

    // Create a manager that depends on the fake.
    val manager = HealthConnectManager(fake)

    // Call addRecords so that the permission check is made.
    manager.addRecords(fakeRunRecord1)

    // Verify that the manager is exposing an error.
    assertThat(manager.errors).hasSize(1)
}

पेज पर नंबर डालना

पेज पर नंबर डालना, गड़बड़ियों की एक आम वजह है. इसलिए, FakeHealthConnectClient से आपको यह पुष्टि करने में मदद मिलती है कि आपकी साइट पर पेजिंग लागू की गई है या नहीं रिकॉर्ड और बदलाव सही तरीके से काम करते हैं.

हमारे उदाहरण में आपका विषय, HealthConnectManager, जांच के तहत आने वाली चीज़ों के बारे में बता सकता है ReadRecordsRequest में पेज का साइज़:

fun fetchRecordsReport(pageSize: Int = 1000) }
    val pagedRequest =
        ReadRecordsRequest(
            timeRangeFilter = ...,
            recordType = ...,
            pageToken = page1.pageToken,
            pageSize = pageSize,
        )
    val page = client.readRecords(pagedRequest)
    ...

पेज के साइज़ को 2 जैसे छोटे मान पर सेट करके, आप आसानी से अपने पेज की जांच कर सकते हैं खोज नतीजों को पेजों में बांटना. उदाहरण के लिए, पांच रिकॉर्ड शामिल किए जा सकते हैं, ताकि readRecords, 3 नतीजे दिखाए अलग-अलग पेज:

@Test
fun readRecords_multiplePages() = runTest {

    // Create a Fake with 2 running records.
    val fake = FakeHealthConnectClient()
    fake.insertRecords(generateRunningRecords(5))

    // Create a manager that depends on the fake.
    val manager = HealthConnectManager(fake)

    // Read records with a page size of 2.
    val report = manager.generateReport(pageSize = 2)

    // Verify that all the pages were processed correctly.
    assertTrue(report.records.size == 5)
}

टेस्ट डेटा

फ़िलहाल, लाइब्रेरी में नकली डेटा जनरेट करने के लिए एपीआई शामिल नहीं हैं. हालांकि, आपके पास Android Code Search में मौजूद लाइब्रेरी के लिए, डेटा और जनरेटर का इस्तेमाल किया जाता है.

स्टब

FakeHealthConnectClient की overrides प्रॉपर्टी आपको प्रोग्राम करने की सुविधा देती है (या stub out भी नहीं करना चाहिए, ताकि कॉल किए जाने पर वे अपवाद दिखें. एग्रीगेशन कॉल से आर्बिट्रेरी डेटा मिल सकता है. साथ ही, इनकी मदद से सूची बनाई जा सकती है कई जवाब हैं. ज़्यादा जानकारी के लिए, Stub और MutableStub देखें.

किनारे के केस की खास जानकारी

  • पुष्टि करें कि क्लाइंट की ओर से अपवाद मिलने पर, आपका ऐप्लिकेशन उम्मीद के मुताबिक काम करता हो. हर फ़ंक्शन के दस्तावेज़ देखें और पता लगाएं कि आपको किन अपवादों की जानकारी देनी है को जाँचना चाहिए.
  • इस बात की पुष्टि करें कि क्लाइंट को की जाने वाली हर कॉल में, अनुमतियों की जांच करें.
  • पुष्टि करें कि आपने पेजों को लागू किया है.
  • पुष्टि करें कि जब कई पेज फ़ेच किए जाते हैं, लेकिन एक पेज की समयसीमा खत्म हो जाती है, तो क्या होता है टोकन.