Health Connect Test kitaplığını kullanarak birim testleri oluşturma

Health Connect Test kitaplığı (androidx.health.connect:connect-testing) otomatik testlerin oluşturulmasını basitleştirir. Doğrulamak için bu kitaplığı kullanabilirsiniz ve doğru yanıtlar verdiğinden emin olmak için manuel olarak test edilmesi zor durumlardır.

Kitaplığı kullanarak yerel birim testleri oluşturabilirsiniz. Yerel birim testleri, genellikle doğrulama için uygulamanızda Health Connect ile etkileşimde bulunan sınıfların davranışı gerekir.

Kitaplığı kullanmaya başlamak için bir test bağımlılığı olarak ekleyin:

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

Kitaplığa giriş noktası, FakeHealthConnectClient sınıfıdır. testlerde HealthConnectClient değerini değiştirmek için kullanılır. FakeHealthConnectClient aşağıdaki özelliklere sahiptir:

  • Kayıtların bellek içi temsilidir. Böylece ekleyebilir, kaldırabilir, silebilir ve onları okuyun
  • Değişiklik jetonlarının oluşturulması ve değişiklik izleme
  • Kayıtlar ve değişiklikler için sayfalara ayırma
  • Toplama yanıtları saplamalarla desteklenir
  • Tüm işlevlerin istisnalar bildirmesine izin verir
  • İzin kontrollerini emüle etmek için kullanılabilecek bir FakePermissionController

Testlerdeki bağımlılıkları değiştirme hakkında daha fazla bilgi edinmek için şu makaleyi okuyun: Android'de Bağımlılık Yerleştirme. Sahteler hakkında daha fazla bilgi için şu adresi okuyun: Android'de iki kez test özelliğini kullanma

Örneğin, müşteriyle etkileşimde bulunan sınıfın adı HealthConnectManager ve bağımlılık olarak HealthConnectClient alır. şöyle görünür:

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

Testlerde, bunun yerine test ettiğiniz sınıfınıza sahtesini iletebilirsiniz:

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)
    }
}

Bu test, kurgusal fetchReport işlevinin HealthConnectManager, kayıtları etkinliğe göre düzgün şekilde filtreler.

İstisnaları doğrulama

HealthConnectClient için yapılan neredeyse her çağrı istisnaya neden olabilir. Örneğin, insertRecords dokümanlarında şu istisnalar belirtilmiştir:

  • IPC aktarım hataları için @throws android.os.RemoteException.
  • İzinsiz erişime sahip istekler için @throws SecurityException.
  • Disk G/Ç sorunları için @throws java.io.IOException.

Bu istisnalar, kötü bir bağlantı veya ekranda hiç boşluk kalmaması gibi durumları olanak tanır. Uygulamanız bu çalışma zamanı sorunlarına doğru şekilde tepki vermelidir; çünkü ne olduğunu konuştuk.

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)
}

Toplama

Toplama çağrılarında sahte uygulama bulunmaz. Bunun yerine belirli şekilde davranacak şekilde programlayabileceğiniz taslaklar kullanmak. Buradan: FakeHealthConnectClient öğesinin overrides özelliğindeki saplamalar.

Örneğin, toplama işlevini belirli bir sonucu döndürecek şekilde programlayabilirsiniz:

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)

Ardından, şu sayfada test edilen sınıfınızın (HealthConnectManager) sonuç doğru şekilde işlendi:

// 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)

İzinler

Test kitaplığı, iletilebilecek bir FakePermissionController içerir FakeHealthConnectClient bağımlılığı olarak gösterir.

Test edilen denek, PermissionController—through ve HealthConnectClient arayüzünün permissionController özelliği (kontrol etmek için) tıklayın. Bu işlem genellikle müşteriye yapılan her aramadan önce yapılır.

Bu işlevi test etmek için hangi izinlerin kullanılabildiğini ayarlamak için 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)
}

Sayfaları numaralandırma

Sayfalara ayırma, hataya neden olan yaygın bir kaynaktır. Bu nedenle FakeHealthConnectClient sayfa oluşturma uygulamanızın doğru şekilde davrandığından emin olun.

Örneğimizde HealthConnectManager olan test özneniz, ReadRecordsRequest içindeki sayfa boyutu:

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

Sayfa boyutunu 2 gibi küçük bir değere ayarlamak, sayfa boyutunu sayfalara ayırmanızı sağlar. Örneğin, readRecords değerinin 3 döndürmesi için 5 kayıt ekleyebilirsiniz farklı sayfalar:

@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)
}

Test verileri

Kitaplıkta henüz sahte veri oluşturmaya yönelik API'ler bulunmamaktadır, ancak Android Code Search'teki kitaplık tarafından kullanılan veriler ve oluşturucular için de geçerlidir.

Saplamalar

FakeHealthConnectClient öğesinin overrides özelliği, programı (veya kurallarını çıkarıp) çağırın. Toplama çağrıları, rastgele veriler de döndürebilir ve sıraya almayı destekler. birden fazla yanıt olabilir. Daha fazla bilgi için bkz. Stub ve MutableStub.

Uç durumların özeti

  • İstemci istisnalar bildirdiğinde uygulamanızın beklendiği gibi davrandığını doğrulayın. İstisnaları görmek için her bir fonksiyonun dokümanlarına bakın kontrol etmelisiniz.
  • Müşteriyle yaptığınız her aramanın öncesinde uygun izin kontrolü yapın.
  • Sayfalara ayırma uygulamanızı doğrulayın.
  • Birden fazla sayfa getirdiğinizde ancak bunlardan birinin süresi dolduğunda ne olduğunu doğrulayın jeton.