DEV Community

Cover image for Keep Appium out of your test code: BasePage + lazy locators
Mayvin Ramasawmy
Mayvin Ramasawmy

Posted on

Keep Appium out of your test code: BasePage + lazy locators

If your test methods import AndroidDriver, call findElement directly, or know what a locator strategy is, your tests are coupled to Appium. The day a selector changes or the driver setup moves, that coupling spreads the edit across every test you've written.

The fix is an abstraction layer your tests talk to instead. Tests describe intent — loginScreen.signIn(user) — and never see the driver underneath.

What the article builds:

  • 🧱 A BasePage that runs PageFactory.initElements with AppiumFieldDecorator, so every screen object inherits element wiring for free
  • 🐌 Lazy locators — @AndroidFindBy fields resolve to real elements at interaction time, not at construction
  • 🔌 A Spring-managed DriverManager that owns the session so screen objects receive an already-initialized driver
  • 💉 Constructor injection that passes that single driver down through the framework
  • ⚖️ The SRP and DIP reasoning for why the driver lives in one place

One concrete detail worth knowing: because AppiumFieldDecorator makes locators lazy, instantiating a screen object does not query the UI. Nothing touches the device until you actually call a method that uses a field. That's why you can construct screen objects in a constructor without the app being on the right screen yet — a common source of confusion when people expect @AndroidFindBy to fail immediately on a missing element.

This is Article 3 of a series building a mobile framework end to end. If your tests are tangled up with Appium internals, this is the layer that separates them.

👉 Read the full guide here: https://www.mobile-automation.io/driver-setup-screen-objects-mobile-framework/

Top comments (2)

Collapse
 
ariless profile image
Darya Belaya

The lazy instantiation note is the part that caught me out. In WDIO, creating a new page object also doesn't touch the app - it's just an object in memory. I had a deep link scenario that left the app on a detail screen; the Before hook of the next scenario constructed fresh LoginPage objects and nothing happened to the app. It was still on the detail screen. The next scenario called loginPage.waitForVisible() and timed out waiting for a login title that wasn't there.
Fix was explicit app restart in the After hook. Same principle: constructing a page object is memory allocation, not UI navigation.

Collapse
 
mayvinrmm profile image
Mayvin Ramasawmy

Perfect real-world example — thanks for sharing the actual failure, not just the principle. And it proves the trap isn't Appium-specific: you hit it in WDIO, the article's in Java/Appium, but it's the same root cause. Creating the object is just memory — the app has no idea it happened.

The deep-link case is the nastiest because nothing errors. The app's just on the wrong screen until waitForVisible() times out and sends you debugging the locator instead of the state. Your After-hook restart is the right fix. One thing I'd add: an explicit "we're on screen X" check at the start of a scenario turns that silent timeout into a fast, obvious failure.