Locator Strategies in Flutter Integration Tests

Akanksha
CommandDash
Published in
4 min readJan 26, 2024

--

Locator strategy, in the context of software development and test automation, refers to the method or approach used to identify and locate elements within a user interface (UI). Elements can include buttons, text fields, images, and other interactive components of a software application.

In any automation framework, A well-defined and robust locator strategy helps ensure that automated tests are reliable, maintainable, and less prone to failure when the UI changes.

This blog will explore diverse techniques for recognizing elements and propose optimal approaches tailored for Flutter-based apps. Within the Flutter framework, these approaches are commonly referred to as “finders.”

To facilitate understanding, I will furnish a widget tree, screen UI, and corresponding locator findings in this blog.

Locator Methods in Flutter:

Flutter provides various methods for finding locators -

By Text :

The “find by text” locator is a way to find and interact with UI elements based on the text they display.

Eg. In the below screen, we want to identify the highlighted element whose text is ‘Todo’ in Tab

Finder todoTab = find.text('Todo')

This strategy Simplifies test code, enhances readability, and maintains focus on user experience but it's Prone to maintenance issues if text changes frequently, may face challenges in localized apps, and potential ambiguity in cases of identical texts at multiple places.

By Key :

It is a locator strategy used to locate and interact with UI elements based on their unique keys. Each widget in Flutter can be assigned a key, providing a way to precisely identify and reference that specific widget within the widget tree.

Finding locators through keys are better approach when contrasted with alternative methods.

Eg. In the below screen, we want to identify the highlighted element whose text is ‘Todo’ and whose Key is ‘todoTabKey’ in Tab.

Finder todoTab = find.byKey(Key('todoTabKey'))

It Provides precise and stable identification of widgets, enhancing test resilience and effectiveness but may Require responsible key assignment to widgets.

By Icon :

This “find by icon” locator is a strategy to locate UI elements based on their associated icons. This method is particularly useful for testing scenarios where identification and interaction with specific icon-based elements are required.

Eg. In the below screen, we want to identify the highlighted element which is the plus Icon.

 Finder plusIcon = find.byIcon(LineIcons.plus);

It’s Prone to maintenance issues if the icon changes frequently.

By Type :

This “find by type” locator is a strategy used to locate UI elements based on their widget type.

Eg. In the below screen, we want to identify the highlighted element that is a plus Icon but resides inside FloatingActionButton.

Finder floatingButton = find.byType(FloatingActionButton);

It is particularly beneficial for custom Widgets defined as per application need.

By Descendent :

The “find by descendant” finder strategy allows for locator chaining, aiding in the identification of a target element within a specific section.

For instance, in the provided scenario, if we aim to pinpoint the highlighted tab bar labeled ‘Todo’ in the screenshot, directly using the text locator may result in ambiguity due to multiple occurrences of ‘Todo’ text. In such cases, targeting the ‘Todo’ text within the TabBar becomes achievable through descendants.

Finder todoTab = find.descendant(of: find.byType(TabBar), matching: find.text('Todo'));

It Facilitates precise targeting within specific UI sections, minimizing ambiguity in element identification.

By Ancestor :

The “find by ancestor” finder strategy is a method used to locate UI elements where our target elements are ancestors of any child widget.

For instance, if we aim to identify the entire TodoTile with the text ‘Meet with Boss’ as a child in the provided screenshot, we can achieve this by specifying the child as the text ‘Meet with Boss’ and designating its ancestor as the type ‘TodoTile’.

Finder desiredTile = find.ancestor(of: find.text('Meet with Boss'), matching: find.byType(TodoTile));

Each strategy comes with its advantages and considerations. We can use which suits best to specific cases.

Thanks !.

--

--

Akanksha
CommandDash

I am Akanksha Gupta. By Profession I am Software Engineer with 6 years of experience in IT Industry. Writing and Sharing is my hobby. Living my life fully :)