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

Health Connect Testing kitaplığı (androidx.health.connect:connect-testing), otomatik testlerin oluşturulmasını kolaylaştırır. 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 genellikle uygulamanızdaki Health Connect istemciyle etkileşimde bulunan sınıfların davranışını doğrulayan yerel birim testleri oluşturabilirsiniz.

Kitaplığı kullanmaya başlamak için 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 jetonu oluşturma 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

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

Örneğin, istemciyle etkileşim kuran sınıfın adı HealthConnectManager ise ve sınıfın bağımlılığı HealthConnectClient ise sınıf aşağıdaki gibi 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. FakeHealthConnectClient mülkünün overrides özelliği aracılığıyla yapı taslaklarını görüntüleyebilirsiniz.

Ö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 kullanılabilir.

Test edilen kullanıcınız, izinleri kontrol etmek için HealthConnectClient arayüzünün PermissionController—through permissionController mülkünü kullanabilir. Bu işlem genellikle müşteriye yapılan her aramadan önce yapılır.

Bu işlevi test etmek için FakePermissionController öğesini kullanarak hangi izinlerin kullanılabileceğini ayarlayabilirsiniz:

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

Sayfalandırma, çok yaygın bir hata kaynağıdır. Bu nedenle FakeHealthConnectClient, kayıtlar ve değişiklikler için sayfalandırma uygulamanızın doğru şekilde çalıştığını doğrulamanıza yardımcı olacak mekanizmalar sağlar.

Test edilen özneniz (örnekteki HealthConnectManager), ReadRecordsRequest içinde sayfa boyutunu belirtebilir:

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, sayfalandırmayı kolayca test etmenizi sağlar. Örneğin, readRecords'ün 3 farklı sayfa döndürmesi için 5 kayıt ekleyebilirsiniz:

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

Verileri test et

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.

Stub'lar

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 birden fazla yanıtın sıraya eklenmesini destekler. Daha fazla bilgi için Stub ve MutableStub sayfalarına göz atın.

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.
  • Sayfalandı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.