Efficiency Unleashed: The Power of Automation in Our Flutter Adventure

BTLA Tech Team
3 min readApr 4, 2024

This is the fourth blog of this series of blog posts highlighting our experiences with flutter and what’s next for mobile apps.

In the app development lifecycle, Quality Assurance is pivotal. We conduct Sanity Testing to ensure stability of new functionality and Regression Testing to verify existing features remain unaffected. To enhance efficiency, we implemented an Automation framework for basic sanity testing, streamlining our QA process by having it as a part of the CI/CD pipeline.

The Automation framework was implemented using WDIO (WebdriverIO) with Appium in Node.js.

WDIO and Appium

WDIO (WebdriverIO) and Appium are leading frameworks in mobile and web automation, powered by Node.js. WDIO offers a versatile testing framework, facilitating cross-platform testing across browsers and mobile devices. Appium serves as a unified interface for automating iOS and Android applications, seamlessly integrating with WDIO to enable comprehensive testing of web and mobile applications.

This choice offered several advantages:

  • Accelerated execution times compared to alternative frameworks like Pytest and TestNG.
  • Expedited development cycles in contrast to other frameworks like Pytest and TestNG.
  • Leveraging an inheritance architecture minimized the amount of code required for each page and ensured scalability for future enhancements.

Addressing Automation Challenges in Flutter

Automating apps in Flutter poses challenges due to the absence of standardized locators for UI elements. To overcome this hurdle, we leveraged the Flutter Semantic class. By wrapping our UI elements with a Semantic widget, one could assign specific locators, enhancing automation capabilities.

// Example of wrapping a UI element with a Semantic widget
Semantics(
label: 'Button',
child: ElevatedButton(
onPressed: () {
// Button functionality
},
child: Text('Submit'),
),
)

Using Semantic widgets, one can provide explicit labels for UI elements, facilitating robust automation testing. This approach ensured reliable element identification and improved the efficiency of the testing processes.

Using this Automation Framework we were able to cut down our QA efforts significantly and achieve faster release cycles for the application.

Disabling Semantics for Release Applications

One downside of the Semantics class is its performance overhead, especially in release applications. To mitigate this, we created a wrapper around the Semantics class called ByjusSemantics.

class ByjusSemantics extends StatelessWidget {
final String label;
final bool container;
final Widget child;
final bool? isLogsEnabled;

const ByjusSemantics({
Key? key,
required this.label,
required this.container,
required this.child,
this.isLogsEnabled,
}) : super(key: key);

@override
Widget build(BuildContext context) {
if (isLogsEnabled ?? kDebugMode) {
return Semantics(
label: label,
container: container,
child: child,
);
} else {
return child;
}
}
}

With ByjusSemantics, one can conditionally enable or disable Semantics based on whether the app is running in debug mode or release mode.

Example Usage:

ByjusSemantics(
label: 'Button',
container: true,
child: ElevatedButton(
onPressed: () {
// Button functionality
},
child: Text('Submit'),
),
)

In conclusion, our Automation framework built on WDIO and Appium played a pivotal role in our Flutter migration journey. By leveraging these powerful tools, we streamlined testing processes, ensuring the reliability and scalability of our Flutter applications across web and mobile platforms. With comprehensive automation in place, we were able to navigate complexities, overcome challenges, and ultimately achieve success in our migration efforts all while reducing QA efforts significantly.

--

--