Fusion is a extensible lightweight Android instrumented
test framework that combines Espresso, UI Automator and ComposeUiTest into one easy-to-use API with the clear syntax, at the same time keeping the native Android frameworks APIs unchanged.
Add Fusion dependency to your build file:
repositories {
mavenCentral()
}
// build.gradle
androidTestImplementation "me.proton.test:fusion:0.9.97"
// build.gradle.kts
androidTestImplementation("me.proton.test:fusion:0.9.97")
To start using Fusion API simply import required builder
import me.proton.test.fusion.Fusion.view
import me.proton.test.fusion.Fusion.listView
import me.proton.test.fusion.Fusion.recyclerView
class EspressoTests {
@Test
fun onViewTest() {
view
.withId(R.id.text)
.withRootMatcher(isDialogPopup())
.typeText("Secure Email")
}
@Test
fun onListViewTest() {
listView
.onListItem()
.atPosition(0)
.click()
}
@Test
fun onRecyclerViewTest() {
recyclerView
.withId(R.id.inbox)
.onItemAtPosition(0)
.click()
view
.withText(R.string.test)
.checkIsDisplayed()
}
}
Full Fusion Espresso documentation.
import me.proton.test.fusion.Fusion.node
import me.proton.test.fusion.Fusion.allNodes
class ComposeUITests : FusionComposeTest {
@Test
fun singleNodeTest() {
node
.withTag("testTag")
.click()
node
.withText("text")
.assertExists()
.await {
assertIsDisplayed()
}
}
@Test
fun nodeCollectionTest() {
allNodes
.withTag("testTag")
.assertEach(
node.containsText("test")
)
allNodes
.withText("Item")
.onFirst()
.click()
.await {
assertDoesNotExist()
}
}
}
Full Fusion Compose documentation.
import me.proton.test.fusion.Fusion.device
import me.proton.test.fusion.Fusion.uiObject
import me.proton.test.fusion.Fusion.byObject
class InstrumentationTests {
@Test
fun deviceTest() {
device
.pressHome()
.pressRecentApps()
}
@Test
fun uiObjectTest() {
uiObject
.withPkg("me.package.example")
.withText("Example")
.click()
}
@Test
fun byObjectTest() {
byObject
.withContentDesc("Search")
.click()
byObjects
.containsText("test")
.atPosition(0)
.click()
}
}
More about Fusion capabilities for UIDevice device - documentation.
More about Fusion for UIAutomator - documentation.
This is the entry point to Fusion API:
- Espresso:
intent
- use it to test intents. Coversintending()
andintended()
APIs.listView
- should be used to interact withListView
elements. Covers EspressoonData()
API.recyclerView
- should be used to interact withRecyclerView
items or views inside theViewHolder
item.rootView
- use it to interact with root views.view
- the shortcut to interact withView
elements. Covers EspressoonView()
API.
- UIAutomator:
uiObject
- an alias forUiObject
UI Automator API.byObject
- an alias forUiObject2
UI Automator API.byObjects
- an alias forUiObject2
UI Automator API where you interact with multipleUiObject2
objects.
- ComposeUiTest:
node
- an alias forSemanticsNodeInteraction
ComposeUiTest API.allNodes
- an alias forSemanticsNodeInteractionCollection
ComposeUiTest API where you interact with multipleSemanticsNodeInteraction
elements.
- Device:
device
- collection of functions to control the test device using the UiDevice API.
FusionConfig.kt file contains configuration parameters to control multiple Fusion parameters.
useUnmergedTree
- controls whether the Compose UI Test framework should use an unmerged tree for UI tests. An unmerged tree could refer to a more detailed or raw view hierarchy, which might be useful for certain types of tests where the default merged or simplified view hierarchy isn't sufficient. Default isfalse
.testRule
- allows dynamically changing the test rule in a thread-safe manner during test execution.shouldPrintHierarchyOnFailure
- instructs the testing framework to print or log the UI hierarchy in the event of a test failure. This can be invaluable for debugging, providing immediate insight into the UI state at the time of failure.
-
Search flags -
shouldSearchByObjectEachAction
andshouldSearchUiObjectEachAction
flags, both initialized to false, are used to control how UI elements (objects) are located, specifically in the context of using UI selectors or identifiers to interact with elements.Both flags offer a way to balance between test robustness and execution speed. By default, with both flags set to false, the system assumes elements do not need to be re-located for each action, optimizing for speed.
-
Boost function -
boost(idleTimeout: Long = 0L, selectorTimeout: Long = 0L, actionTimeout: Long = 50L)
is a utility designed specifically for enhancing the performance of UI tests automated with UI Automator in Android test automation projects. It aims to significantly reduce the execution time of UI tests by adjusting key timeouts in the UI Automator's Configurator.
Fusion offers a set of default timeouts for various operations within the test execution process. These include:
waitTimeout
: Maximum time to wait for conditions to be met before proceeding.assertTimeout
: Time to wait before asserting a condition to ensure stability.watchInterval
: Frequency at which conditions or changes are checked.
These timeouts are encapsulated within AtomicReference objects to ensure thread-safe updates and retrievals, allowing dynamic adjustments during runtime.
Defines hooks for key moments in the test lifecycle, which can be customized per test needs. These hooks include:
before
: Executed before each test case.after
: Executed after each test case.onFailure
: Invoked when a test case fails.onSuccess
: Invoked when a test case succeeds.
These hooks provide a flexible mechanism to integrate setup, teardown, and custom behavior based on test outcomes.