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_sourcesinconfig.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 inelements.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:
It walks through eight stages, in order:
- Prints the welcome banner and the golden path.
- Asks what you want to automate:
mobileorweb. - Offers to pip-install the matching engines (Appium for mobile, Selenium + Playwright for web).
- 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. - Names the project folder and picks where it lives.
- Runs a short config Q&A scoped to your platform choice, then writes a commented, platform-correct
config.yaml. - Verifies the environment and the fresh project with
optics doctor. - 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¶
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 versiondeviceName: Your device nameudid: Your device's unique identifier (find withadb 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: 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 frominput_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):
Finding XPaths¶
Use Appium Inspector or your device's UI Automator to find element XPaths:
- Connect Appium Inspector to your device
- Navigate to the screen with your element
- Click the element in the inspector
- Copy the XPath
- Paste into
Element_ID_xpathcolumn
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¶
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¶
Column Explanations¶
- test_case: Name of your test scenario
- test_step: Module to execute (references
module_namefrommodules.csv)
Special Test Cases¶
Suite Setup - Runs before all tests:
Suite Teardown - Runs after all tests:
Regular Test:
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¶
Why Are Dry Runs Needed?¶
- Detects missing files (like
elements.csvor 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¶
What Happens During Execution¶
- Framework reads your
config.yamland connects to device - Loads all elements from
elements.csv - Loads all modules from
modules.csv - Loads element images from
input_templates/ - Executes test cases in order from
test_cases.csv - 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_Namewith PNG filename for clarity
2. Screenshot Management¶
- Organize
input_templates/with subfolders for different screens - Name images to match their
Element_IDexactly - 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.csvwhen 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: DEBUGinconfig.yamlfor detailed logs - Enable
file_log: trueto 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.yamlwith 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.csvfor each action sequence - Build test cases in
test_cases.csvcombining 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_IDreferences 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.pngis less clear thanbutton_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¶
- Check logs in the test output directory
- Verify elements exist with Appium Inspector
- Test individual modules before full test cases
- Verify the
dry_runworks before executing to save time - Ensure all file paths and element names match exactly (case-sensitive)
- Verify PNG files are in correct location and named correctly
- Check image quality and cropping of templates