-
Notifications
You must be signed in to change notification settings - Fork 0
Testing
This page covers testing your app's integration with the Convert Android SDK — making experiment decisions deterministic in tests, capturing SDK logs, and keeping tracking quiet. For testing the SDK itself, see its repository.
The biggest source of test flakiness is the asynchronous config fetch. Avoid it entirely by building the SDK in direct-data mode with a known config fixture, so decisions are available synchronously and never depend on the network:
import com.convert.sdk.android.ConvertSDK
import com.convert.sdk.core.model.generated.ConfigResponseData
val config: ConfigResponseData = loadTestConfig() // deserialize a fixture JSON
val sdk = ConvertSDK.builder(context)
.data(config)
.build()
sdk.onReady {
val ctx = sdk.createContext("test-visitor")
val variation = ctx.runExperience("homepage-redesign")
// assert on variation?.key
}With data(...) set, the SDK seeds its config without an HTTP call. Use a stable explicit visitor id (e.g. "test-visitor") so bucketing is reproducible run to run — the same id always maps to the same variation for a given experience.
Disable outbound tracking so tests do not emit network events:
val sdk = ConvertSDK.builder(context)
.data(config)
.trackingEnabled(false)
.build()Bucketing, rule evaluation, and sticky persistence still work with tracking disabled — only the network side is silenced. See Tracking Control. For a single call, use the per-call override: ctx.runExperience("key", enableTracking = false).
The SDK uses Android APIs (SharedPreferences, ConnectivityManager, WorkManager), so integration tests that build a real ConvertSDK run under Robolectric rather than as plain JVM unit tests.
@RunWith(RobolectricTestRunner::class)
class MyConvertIntegrationTest {
@Test
fun bucketsVisitorDeterministically() {
val sdk = ConvertSDK.builder(ApplicationProvider.getApplicationContext())
.data(loadTestConfig())
.trackingEnabled(false)
.build()
// ...assert on decisions
}
}The SDK logs through android.util.Log under the tag ConvertSDK. In Robolectric tests you can assert on emitted log lines via org.robolectric.shadows.ShadowLog.getLogs(). Set the log level high while debugging a test:
ConvertSDK.builder(context)
.data(config)
.logLevel(LogLevel.DEBUG)
.build()-
One SDK per test — build a fresh
ConvertSDKper test (or per class) so visitor and queue state do not leak between tests. - Use explicit visitor ids — never rely on the auto-UUID in tests; an explicit id makes bucketing assertions stable.
- Prefer fixtures over live keys — direct-data mode with a checked-in config fixture keeps tests hermetic and fast.
-
Initialization — direct-data mode and
onReady - Tracking Control — disabling tracking
-
Troubleshooting — diagnosing
nulldecisions
Copyrights © 2026 All Rights Reserved by Convert Insights, Inc.
Getting Started
Android SDK
- Quickstart
- Installation
- Initialization
- Configuration
- Return Types & Models
- Code Examples
- Offline Behavior
- Tracking Control
- Google Play Data Safety
- Java Interop
Core Concepts
- Experiences & Variations
- Feature Flags
- Bucketing Algorithm
- Rule Evaluation
- Segments
- Data Management
- Event System
- API Communication
How-To Guides
- Running Experiences
- Running Features
- Tracking Conversions
- Visitor Context
- Persistent DataStore
- Troubleshooting
Contributing