Skip to content

Getting Started Guide

This guide walks you through creating automated tests using Optics Framework — from a fresh install to your first executed test.

A few terms first

  • Engine — an installable backend that does the work: an action driver (Appium, Selenium, Playwright), an OCR engine, or an LLM. Install engines with optics setup.
  • Element source — where Optics looks for on-screen elements (the driver's page source, OCR text, or image matching), configured under elements_sources in config.yaml.
  • Locator — the value that identifies one element: an XPath, a text=… string, a CSS selector, or an image filename.
  • Element — a named locator you reference from a module as ${name}, defined in elements.csv.

In a hurry?

Run optics quickstart — the guided walkthrough below documents every stage, defaults included. The rest of the page explains each piece and how to do it by hand.

optics quickstart: The Guided Walkthrough

One command takes you from nothing to a runnable project:

optics quickstart

It walks through eight stages, in order:

  1. Prints the welcome banner and the golden path.
  2. Asks what you want to automate: mobile or web.
  3. Offers to pip-install the matching engines (Appium for mobile, Selenium + Playwright for web).
  4. Offers starting points: an empty project (recommended) or a packaged sample (contact, youtube, …). Picking a sample aimed at the other domain asks for confirmation first.
  5. Names the project folder and picks where it lives.
  6. Runs a short config Q&A scoped to your platform choice, then writes a commented, platform-correct config.yaml.
  7. Verifies the environment and the fresh project with optics doctor.
  8. Prints next steps tailored to your answers.

Every question ships with a default, so pressing Enter throughout yields a runnable project:

Stage What it asks Default (just press Enter)
Target mobile or web? mobile
Engines Install them now? yes
Starting point Empty project or a sample? empty project (recommended)
Project name Folder name for the new project my-optics-project
Location Where to create it current directory
Platform Android / iOS, or Playwright / Selenium Android (mobile), Playwright (web)
Details Device name, app id, server URL, browser, headless Working examples: emulator-5554, com.example.app, http://127.0.0.1:4723, Chromium, headed
Vision Find elements by on-screen text (EasyOCR)? no
Log level DEBUG to ERROR INFO

The defaults are runnable placeholders, not magic: edit the generated config.yaml whenever you like, or redo the Q&A with optics configure <folder>. Samples ship their own curated config.yaml, and the wizard keeps it unless you explicitly agree to overwrite.

Prerequisites, the short version

A standard Python 3.12+ virtualenv is all you need to start. Web targets need nothing more (the Playwright engine downloads its own browsers); mobile additionally needs a JDK (17+), Node.js + the Appium server, and the Android platform-tools — the full list lives in Installation. You don't need to settle this up front: the doctor check in stage 7 reports each gap with the exact command that fixes it.

The rest of this page explains what each stage sets up, so you can also drive every part yourself if you prefer full control.

Overview: Manual Setup

Step 1: Create Python Virtual Environment

mkdir test-code
cd test-code
python3 -m venv venv
source venv/bin/activate
pip install optics-framework

Important

Conda environments are not supported for easyocr and optics-framework together, due to conflicting requirements for numpy (version 1.x vs 2.x). Please use a standard Python virtual environment instead.

Step 2: Install the Engines You Need

The core install has no drivers. Add the ones your test needs — either as pip extras or via optics setup (the names match the config.yaml source keys). Not sure which ones you need? The guided walkthrough installs them for you based on your target platform:

optics setup --install appium easyocr
# equivalent to: pip install "optics-framework[appium,easyocr]"

Note

Intel-based Macs cannot download easyocr.

Mobile needs more than pip

optics setup installs the Python engine, but Appium mobile automation also needs system tools it can't install for you — a JDK (17+), Node.js + the appium server, and the Android platform-tools (adb). See Installation, and run optics doctor any time to see exactly what's still missing (with the command to fix each item).

Step 3: Create a New Test Project

optics init my_test_project --template contact

This copies the contact sample — a complete, runnable project — into ./my_test_project. Omit --template to scaffold an empty project you fill in yourself (or run optics quickstart for the fully guided walkthrough: engines + project + config + doctor check). Templates: contact, clock, calendar, youtube, gmail_web, playwright.

Project Structure

Your test project uses four main components that work together:

my_test_project/          # created in your current directory
├── config.yaml
├── modules/
|   └── modules.csv
├── test_data/
|   ├── elements.csv
|   └── input_templates/
└── test_cases/
    └── test_cases.csv

my_test_project/ - Your specific project name (you choose this)

Using Invoke API and API definition files

Projects that use the Invoke Api keyword include API definition YAML files, which are a separate asset from element files. The Invoke Api keyword does not use elements.csv or element YAML; it uses API definition data only. Add an api.yaml (or other YAML files under the project) that contains a top-level api or apis key. The runner auto-discovers and loads any such YAML files under the project directory. Example layout when using API tests:

my_test_project/
├── config.yaml
├── api.yaml
├── modules/
├── test_data/
|   ├── elements.csv
|   └── input_templates/
└── test_cases/

The API YAML format is different from element files: it defines collections, base URLs, endpoints, request/response, and optional extract rules. See the Invoke Api and Add Api sections in Keyword Usage, and sample api.yaml files

Configuring config.yaml

The config.yaml file tells the framework how to connect to your device and what tools to use for finding elements. The quickest way to create it is optics configure <project> — a short Q&A writes a platform-correct file for you (or optics configure <project> --edit to hand-tune every field in a TUI). You can also edit it directly, as shown below.

Driver Connection

Connects to your device/emulator:

driver_sources:
    - appium:
        enabled: true
        url: "http://127.0.0.1:4723/wd/hub"
        capabilities:
            automationName: UiAutomator2
            deviceName: emulator-5554
            platformName: Android

Key Settings to Update

  • platformVersion: Your Android/iOS version
  • deviceName: Your device name
  • udid: Your device's unique identifier (find with adb devices)
  • url: Your Appium server address (usually localhost)

Capturing UI Element Screenshots

Before defining elements in the CSV, you need to capture screenshots of the UI elements you want to interact with.

What is input_templates/?

This folder stores PNG images of buttons, icons, text fields, and other UI elements from your application. The framework uses these images to visually locate elements on the screen when other methods fail.

Best Practice

Organize input_templates/ with subfolders for different screens and name images to match their Element_ID exactly.

Defining Your Elements

Elements are the UI components you'll interact with – buttons, text fields, tabs, etc.

CSV Structure

Element_Name,Element_ID
  • Element_Name: the name you reference from modules as ${Element_Name}.
  • Element_ID: how to locate it — an XPath, a text=… string, a CSS selector, or an image filename from input_templates/.

Fallbacks. To give one element several locators (tried in order until one matches), add more columns whose names start with Element_ID — e.g. Element_ID_xpath, Element_ID_text, Element_ID_image. Only Element_Name and Element_ID* columns are read; any other column is ignored.

Example elements.csv

Element_Name,Element_ID_xpath,Element_ID_image,Element_ID_text
login_button,"//android.widget.Button[@resource-id=""com.app.login:id/btnLogin""]",button_login.png,Login

Here login_button is located by XPath first, then by matching button_login.png, then by the on-screen text Login.

Values as Data

An element can also just hold a value your steps consume via ${...} (e.g. text to type):

Element_Name,Element_ID
test_password,SecurePass123
retry_count,3

Finding XPaths

Use Appium Inspector or your device's UI Automator to find element XPaths:

  1. Connect Appium Inspector to your device
  2. Navigate to the screen with your element
  3. Click the element in the inspector
  4. Copy the XPath
  5. Paste into Element_ID_xpath column

Newlines and special characters in CSV

XPaths and other locator strings in CSV stay one line per row. To include a newline in a value (e.g. in @content-desc), use \n; for a tab use \t, and for a literal backslash use \\. Example: //android.widget.ImageView[@content-desc="I\nIcici Bank Limited"] in a cell is read as an XPath whose attribute value contains a real newline between I and Icici Bank Limited.

Creating Reusable Modules

Modules are sequences of actions that accomplish a specific task, such as building blocks.

CSV Structure

module_name,module_step,param_1,param_2,param_3,param_4,param_5

Column Explanations

  • module_name: Name of your module (can repeat for multi-step modules)
  • module_step: The action to perform (see common actions below)
  • param_1 to param_x: Parameters for the action (vary by action type)

Parameter Count

If your module has fewer param_x columns than the action requires, those extra parameters will be ignored — leading to incomplete or failed test execution. Always check the expected number of parameters for each keyword and ensure your CSV matches it exactly.

Common Actions

module_name,module_step,param_1,param_2,param_3,param_4,param_5
Launch Application,Launch App,,,,
Navigate To Settings,Press Element,${settings_icon},,,
Add Multiple Items,Run Loop,Add Single Item,item_name,${item_list},,
Close Application,Force Terminate App,,,,
Launch External App,Launch Other App,com.example.otherapp,,,,

Variable References

${element_name} references an element from elements.csv

Building Test Cases

Test cases combine modules into complete test scenarios.

CSV Structure

test_case,test_step

Column Explanations

  • test_case: Name of your test scenario
  • test_step: Module to execute (references module_name from modules.csv)

Special Test Cases

Suite Setup - Runs before all tests:

test_case,test_step
Suite Setup,Launch Application

Suite Teardown - Runs after all tests:

test_case,test_step
Suite Teardown,Close Application

Regular Test:

test_case,test_step
Verify User Login,User Login

Why Separate Test Cases from Modules?

Test cases define what to test, modules define how to do it. This separation lets you mix and match modules for different test scenarios.

Running Your Tests

Prerequisites

  • Python 3.12 installed on your system
  • Optics Framework installed in your virtual environment
  • Appium server running: appium
  • Android virtual device or physical device connected and verified: adb devices

Run optics doctor my_test_project to confirm all of the above at once — it reports each engine, tool, and config.yaml check as ✅/⚠️/❌ with the command to fix anything missing.

New to Appium or the Android SDK? Install them from their official docs — Appium and the Android platform tools. The Installation page lists what Optics itself needs.

Always Dry Run Test Cases Before Executing

optics dry_run my_test_project

Why Are Dry Runs Needed?

  • Detects missing files (like elements.csv or input templates) early
  • Verifies CSV and YAML syntax and formatting
  • Checks that all referenced elements and modules exist
  • Saves time by catching setup errors before full execution

Execute Test Cases

optics execute my_test_project

What Happens During Execution

  1. Framework reads your config.yaml and connects to device
  2. Loads all elements from elements.csv
  3. Loads all modules from modules.csv
  4. Loads element images from input_templates/
  5. Executes test cases in order from test_cases.csv
  6. Generates a test report with results and logs

Best Practices

1. Naming Conventions

  • Use descriptive names: login_button_xpath, login_button_text, etc.
  • Be consistent: if you use firsttest_case, use it everywhere
  • Include element type in name: _button, _field, _icon, _tab
  • Match Element_Name with PNG filename for clarity

2. Screenshot Management

  • Organize input_templates/ with subfolders for different screens
  • Name images to match their Element_ID exactly
  • Update screenshots when UI changes

3. Module Design

  • Keep modules focused on one task
  • Make modules reusable – avoid hardcoded values
  • Use variables (${variable_name}) for data that changes
  • Name modules clearly to describe their purpose

4. Element Definition

  • Prefer (text, image) over xpaths
  • Test each element can be found reliably
  • Update elements.csv when app UI changes

5. Test Organization

  • Always include Suite Setup and Suite Teardown
  • Group related tests together
  • Start with a clean state (use Setup to reset app)
  • Test one feature per test case
  • Name tests clearly: "Test_FeatureName_Scenario"

6. File Organization

my_test_project/
├── config.yaml
├── modules/
|   └── modules.csv
├── test_data/
|   ├── elements.csv
|   └── input_templates/
|       ├── button_login.png
|       └── field_username.png
└── test_cases/
    └── test_cases.csv

7. Debugging

  • Set log_level: DEBUG in config.yaml for detailed logs
  • Enable file_log: true to save logs to file
  • Test modules individually before combining them
  • Use meaningful module names that explain what failed
  • Check input_templates/ images load correctly
  • Verify element names match exactly (case-sensitive)

Checklist

Took the guided path?

optics quickstart already scaffolds the project, writes config.yaml, and verifies your environment and tools via optics doctor. Start at Defining Your Elements below — the remaining checkboxes are about authoring your first test.

  • Configure config.yaml with your device details
  • Capture screenshots of UI elements
  • Save screenshots to test_data/input_templates/
  • Define elements in elements.csv (with XPaths and image filenames)
  • Create modules in modules.csv for each action sequence
  • Build test cases in test_cases.csv combining modules
  • Start Appium server
  • Connect device/emulator
  • Dry run tests
  • Execute tests
  • Review test results and logs

Common Pitfalls to Avoid

Avoid These Mistakes

  • Hardcoding values - Use variables instead
  • Duplicate logic - Create reusable modules
  • Poor element identifiers - Elements should be unique and stable
  • Missing screenshots - Element_ID references non-existent PNG files
  • Wrong file paths - Ensure input_templates/ path is correct
  • No error handling - Define fallback element finding methods
  • Skipping Setup/Teardown - Always clean up after tests
  • Testing too much at once - Keep test cases focused
  • Outdated screenshots - Update images when UI changes
  • Generic element names - button1.png is less clear than button_login.png

Need Help?

Common Issues

Troubleshooting

  • Element not found: Check XPath in Appium Inspector, verify PNG exists in input_templates/
  • Wrong element clicked: Screenshot may be outdated or too similar to other elements
  • Test hangs: Check if app is waiting for user input or loading
  • Image match fails: Recapture screenshot on same device/resolution

Troubleshooting Steps

  1. Check logs in the test output directory
  2. Verify elements exist with Appium Inspector
  3. Test individual modules before full test cases
  4. Verify the dry_run works before executing to save time
  5. Ensure all file paths and element names match exactly (case-sensitive)
  6. Verify PNG files are in correct location and named correctly
  7. Check image quality and cropping of templates