@RequiresApi(value = 36)
public final class AppFunctionTestRule implements TestRule


A JUnit TestRule for setting up an environment to exercise AppFunction APIs in unit or Robolectric tests.

Prefer real system-level testing where possible. This rule is intended only for local tests that simulate cross-app interactions via AppFunctions.

Setup

  1. Apply the appfunctions-compiler annotation processor to the test configuration:

     dependencies {
    // ...
    kspTest("androidx.appfunctions:appfunctions-compiler:xx.xx.xx")
    }
  2. Define the service entry point class with @AppFunctionServiceEntryPoint. This is either an existing service in the app under test or a test service created specifically for agent integration testing. See androidx.appfunctions.AppFunctionServiceEntryPoint for set-up instructions.
    Note: If a service's enabled state changes dynamically via android.content.pm.PackageManager.setComponentEnabledSetting, call reloadAppFunctions to reload its functions.

Example:

package com.example.appfunctions

class
ExampleFunctionsTest {
@get:Rule val appFunctionTestRule = AppFunctionTestRule(context)
private val appFunctionManager = appFunctionTestRule.getAppFunctionManager()

@Test
fun addFunction_returnsCorrectSum() = runBlocking {
val appFunctionName = AppFunctionName(
packageName = "com.example.appfunctions",
functionIdentifier = "com.example.pkg.TestAppFunctionService#addFunction"
)
val appFunctions = appFunctionManager.searchAppFunctions(
AppFunctionSearchSpec(functionNames = setOf(appFunctionName))
)
val addFunctionMetadata = appFunctions.single()

val response = appFunctionManager.executeAppFunction(
ExecuteAppFunctionRequest(
targetPackageName = context.packageName,
functionIdentifier = addFunctionMetadata.id,
functionParameters = AppFunctionData.Builder(
addFunctionMetadata.parameters,
addFunctionMetadata.components
)
.setLong("a", 2)
.setLong("b", 3)
.build()
)
)

// Assert on returned response.
}
}

Summary

Public constructors

Public methods

@NonNull Statement
apply(Statement base, Description description)
final @NonNull AppFunctionManager

Returns an AppFunctionManager instance for interacting with AppFunctions registered via the test rule.

final void

Triggers AppFunction indexing.

Public constructors

AppFunctionTestRule

Added in 1.0.0-beta01
public AppFunctionTestRule(@NonNull Context context)

Public methods

apply

Added in 1.0.0-beta01
public @NonNull Statement apply(Statement base, Description description)

getAppFunctionManager

Added in 1.0.0-beta01
public final @NonNull AppFunctionManager getAppFunctionManager()

Returns an AppFunctionManager instance for interacting with AppFunctions registered via the test rule.

reloadAppFunctions

Added in 1.0.0-beta01
@ExperimentalAppFunctionsApi
public final void reloadAppFunctions()

Triggers AppFunction indexing.

Call this function after updating service component state with android.content.pm.PackageManager.setComponentEnabledSetting to re-index available functions.

Once returned, the AppFunctions indexation is guaranteed to be finished. If any static metadata has changed, active observers of AppFunctionManager.observeAppFunctions will be notified of changes. AppFunctionManager.searchAppFunctions will return the updated metadata, if queried, and AppFunctionManager.executeAppFunction will use the updated metadata.

Example: Enabling a Disabled Service Component

// Target the generated service specified by serviceName in @AppFunctionServiceEntryPoint.
val componentName = ComponentName(
context,
"com.example.appfunctions.TestAppFunctionService"
)
context.packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
// Re-index to discover updated service functions.
appFunctionTestRule.reloadAppFunctions()