Usage¶
This guide provides a basic overview of how to install and run a test recipe using the pypts framework.
Installation¶
This section provides the neccesary information needed to setup the environment and test to run. Before using pypts, you may need to install the following system dependencies for PySide6 (Qt GUI framework):
sudo dnf install libxcb libxcb-devel
sudo dnf install xcb-util xcb-util-wm xcb-util-keysyms xcb-util-image xcb-util-renderutil
To setup the test, start in the desired directory. Make a virtual environment. Name is arbitrary.
python -m venv .venv
Activate the environment. Install the package from Acc-PyPI CERN.
python -m pip install pts-framework==0.2.0
There are two ways of setting up the pypts framework after the package has been installed. A package-based setup or a minimal setup consisting of only test and recipe.
1. Minimal setup pypts-framework¶
The minimal setup does not use package-based recipe, see “Recipe YAML format”, but uses a gui. Through the gui, the recipe is loaded, which runs the tests. An example of the package structure is:
my_cwd/
├── .venv
├── tests/
│ ├── __init__.py
│ └── tests.py
└── my_recipe.yaml
But the only requirements is the recipe and the tests described in the recipe. Note: tests are required to be at least one directory down from the cwd.
To run the test, the following command is required.
python -m pypts
This initializes the GUI where the recipe can be loaded and run.
This pypts framework should not have a package in its recipe.
Setting up the framework¶
To setup the test from scratch, you can either use the provided initialization script or manually configure the environment. If using the init_env_min.exe executable:
init_env_min
This will set up the entire required framework. To understand the setup process, check the __main__.py file to see how the GUI is initialized.
Using the framework¶
To use the framework, the __main__.py file is required. Once the entire framework is set up, execute the following command to run the tests:
python -m pypts
This initializes the standard GUI. From the GUI, you can perform the following actions:
Open: Click to load the recipe into the framework. The recipe will be displayed in the GUI.
Start: Click to begin recipe execution. The tests will run according to the recipe definition.
Stop: Click to halt the currently running test. The framework will cleanly shut down and finalize results before displaying a summary in the GUI.
If the recipe includes a UserInteractionStep, interactive buttons will appear on the right side of the GUI below any displayed images.
For the current panelized GUI structure, see GUI Architecture.
2. Package-based pypts-framework¶
If the test is expected to be package-based, a different setup is required. With the installed package, the following structure is necessary:
CWD/
├── .venv
├── pyproject.toml
└── package/
├── __init__.py # package root
├── __main__.py # required to initialize the package
├── recipe.yaml # inside package folder
└── tests/ # Not required to put tests in their own directory.
├── __init__.py # tests as subpackage
├── test_module1.py
└── test_module2.py
The recipe is not required to be inside the package, however the tests are. To compile into its own package, run:
pip install -e .
This will initialize your software as a package that can now be called:
python -m package
Setting up the framework¶
To setup the test from scratch, you can either use the provided initialization script or manually configure the environment. If using the init_env_pack.exe executable:
init_env_pack
This will set up the entire required framework. When making package-based tests using the PTS framework, it is required to include a pyproject.toml file that describes the package contents and its required libraries.
The framework requires the pts-framework to operate and must be installed. To make the package callable via python -m package, run:
python -m pip install -e .
This installs the package in editable mode so it can be executed directly.
Using the framework¶
To use the framework, the __main__.py file is required. Once the entire framework is set up, you can run the package-based framework with:
python -m package
This initializes the standard GUI. From the GUI, you can perform the following actions:
Open: Click to load the recipe into the framework. The recipe will be displayed in the GUI.
Start: Click to begin recipe execution. The tests will run according to the recipe definition.
Stop: Click to halt the currently running test. The framework will cleanly shut down and finalize results before displaying a summary in the GUI.
If the recipe includes a UserInteractionStep, interactive buttons will appear on the right side of the GUI below any displayed images.
For the current panelized GUI structure, see GUI Architecture.
Setting up required files for package-based pypts-framework¶
The required files for a package based setup are the files __main__.py and pyproject.toml mentioned in the section above.
The __main__.py file is responsible for running the code. It is constructed as below.
from pypts import run_pts
from pypts.startup import create_and_start_gui
import sys
if __name__ == '__main__':
api = run_pts()
window, app = create_and_start_gui(api, recipe_file="optional path to recipe if gui should start with preloaded recipe")
# Start the Qt event loop
exit_code = app.exec()
# Exit with the application's exit code
sys.exit(exit_code)
The main file does not require anything else to initialize and run the GUI. In create_and_start_gui() there is an optional argument which is the recipe_file=. By giving this the path to your recipe, the GUI will have the recipe preloaded upon startup.
The pyproject file operates similarily to a makefile and is the construction of a package based on the files inside. This allows for calling the package like python -m package
1. Define your Recipe (my_recipe.yaml)¶
Create a YAML file defining your test sequence. The recipe consists of a main document defining metadata and global variables, followed by documents defining named sequences. See Recipe YAML Format for full explaination of all steps available for recipe.
# SPDX-FileCopyrightText: 2026 CERN <home.cern>
# SPDX-License-Identifier: CC-BY-SA-4.0
---
name: Device acceptance recipe
version: "1.0"
recipe_version: 2.0.0
description: Configure a device, measure it, and disconnect safely.
main_sequence: Main
test_package: my_project.tests
globals:
device_address: COM3
test_voltage: 5.0
---
sequence_name: Main
description: Run the device acceptance flow.
parameters: {}
locals:
measurement: null
outputs: {}
setup_steps:
- steptype: PythonModuleStep
step_name: Configure device
description: Configure the device before measurement.
action_type: method
module: device_driver.py
method_name: setup_device
input_mapping:
port: {type: global, global_name: device_address}
voltage: {type: global, global_name: test_voltage}
output_mapping:
success: {type: passfail}
steps:
- steptype: WaitStep
step_name: Initial delay
description: Allow the device to settle.
input_mapping:
wait_time: {type: direct, value: 2}
output_mapping: {}
- steptype: PythonModuleStep
step_name: Take measurement
description: Read and validate the configured voltage.
action_type: method
module: device_driver.py
method_name: read_measurement
input_mapping: {}
output_mapping:
measured_value: {type: local, local_name: measurement}
status: {type: range, min: 4.8, max: 5.2}
teardown_steps:
- steptype: PythonModuleStep
step_name: Disconnect device
description: Close the device connection during teardown.
action_type: method
module: device_driver.py
method_name: disconnect
input_mapping: {}
output_mapping: {}
Note
Replace device_driver.py with the actual name of your Python module containing the methods called by PythonModuleStep. Adding the path should not be done as the system automatically
detects the path to the specified test. Therefore, avoid naming modules the same unless you specify a test_package as described below.
Alternative: Resource-Based Module Loading¶
For better distribution and deployment, you can use resource-based module loading by organizing your test modules as Python packages:
The complete example above already uses resource-based loading. The focused fields are:
# Header fragment
test_package: my_project.tests
# PythonModuleStep fragment
module: device_driver.py # Resolves to my_project.tests.device_driver
Package Structure Example:
my_project/
├── __init__.py
├── tests/
│ ├── __init__.py
│ ├── device_driver.py
│ └── other_test_modules.py
└── my_recipe.yaml
Benefits of Resource-Based Loading:
Distribution: Test modules are bundled with your package
Reliability: No dependency on current working directory
Deployment: Tests are guaranteed available if package is installed
Standards: Uses Python’s standard import mechanism
Naming: Avoids errors appearing as a result of tests having the same name between packages
2. Run the Recipe (__main__.py)¶
In situations where a level of user interaction with buttons is required, the one above is not enough. For a level of user interaction with steptype UserInteractionStep, a GUI is added.
As the above, use the run_pts function from the pypts.pts module to execute the recipe file. Use the function create_and_start_gui() from the pypts.startup module to create a gui and start it, using the execution of the run_pts.
from pypts._version import version as __version__
import logging
import sys
import os
from pypts.pts import run_pts
from pypts.startup import create_and_start_gui
logger = logging.getLogger(__name__)
# Configure basic logging
log_format = '%(levelname)s : %(name)s : %(message)s'
logging.basicConfig(level=logging.DEBUG, format=log_format)
# Reduce verbosity of noisy libraries
logging.getLogger("paramiko.transport").setLevel("WARN")
if __name__ == '__main__':
"""Main entry point for the PTS application.
Sets up the QApplication, MainWindow, logging, RecipeEventProxy,
and connects signals/slots between the proxy and the window.
Starts the recipe execution and event processing threads.
"""
api = run_pts()
window, app = create_and_start_gui(api)
exit_code = app.exec()
sys.exit(exit_code)
It can also be initialized through the command:
python -m pypts
3. Check the Reports¶
After execution (or during, for the CSV), check the ~/pts_reports/ directory for:
report.csv: Incrementally updated CSV file with detailed step results.report.html: HTML version of the report generated after the recipe finishes.
4. Migrating from File-Based to Resource-Based Loading¶
Both file-based and ressource-based loading are possible for the framework. If you have existing recipes using file-based module loading, here’s how to migrate:
Step 1: Organize Test Modules
Convert your test file structure to a proper Python package:
# Before (file-based)
my_project/
├── tests/
│ ├── test_module1.py
│ └── test_module2.py
└── recipe.yaml
# After (resource-based)
my_project/
├── __init__.py # NEW: Makes it a package
├── tests/
│ ├── __init__.py # NEW: Makes tests a subpackage
│ ├── test_module1.py
│ └── test_module2.py
└── recipe.yaml
Step 2: Update Recipe Configuration
Add the dotted test_package field and make module paths relative to it:
# File-based module field
module: tests/test_module1.py
# Resource-based header and module fields
test_package: my_project.tests
module: test_module1.py # Relative to my_project.tests
Step 3: Install and Test
Make sure your package is properly installed:
# Install in development mode
pip install -e .
# Or install normally
pip install .
Step 4: Verify Package Structure
Test that your modules can be imported:
# This should work without errors
import my_project.tests.test_module1
Common Migration Issues¶
Import Errors: Make sure all directories have __init__.py files
Module Not Found: Verify the test_package field matches your actual package structure
Path Issues: Use paths relative to test_package. For example,
helpers/test_module.py imports my_project.tests.helpers.test_module.
Package Installation: Ensure your package is installed in the Python environment where you’re running pypts
5. Running a Recipe¶
Once your recipe is defined and your environment is set up, you can execute the recipe through the graphical user interface.
Starting the GUI
Launch the application using one of these commands:
# For minimal setup
python -m pypts
# For package-based setup
python -m package
The GUI window will open, displaying the PTS runtime interface as a panelized window. At a high level:
the top area contains the menu bar, toolbar, and screen-state tabs
the left side contains either the idle placeholder, the live step table, or the final results panel
the right side contains the operator interaction panel and the runtime log
See GUI Architecture for the structural details and component breakdown.
Loading a Recipe
In the GUI toolbar, click the “Open” button (folder icon) to load your recipe YAML file. The recipe will be validated and prepared for execution. Once loaded, the recipe name and description appear in the left panel, and the step list is populated with all steps defined in your recipe.
Executing the Recipe
After loading a recipe:
Click the “Start” button (play icon) in the toolbar to begin recipe execution
The GUI will display the current step being executed in the left panel
Step results are updated in real-time with color-coded status indicators:
Green: Step passed
Red: Step failed
Yellow: Step skipped or warning
Blue: Step in progress
User Interaction Steps
During recipe execution, if a UserInteractionStep is encountered:
A message box appears on the right side of the GUI with instructions
If the step includes an image, it will be displayed in the image panel
Interactive buttons are dynamically created for user responses (e.g., “Pass”, “Fail”, “Retry”, etc.)
Click the appropriate button to respond to the step request
The recipe will continue after your response is processed
Stopping Execution
To halt recipe execution at any time, click the “Stop” button (stop icon) in the toolbar. The current step will attempt to gracefully terminate, and results collected up to that point will be available for review.
Viewing Results
As the recipe executes:
Left Panel - Step List: Shows all steps with their execution status while the recipe is running
Left Panel - Results Tree: Displays a hierarchical view of step results after execution completes
Right Panel - Interaction Panel: Shows operator prompts, images, and action buttons
Right Panel - Log Console: Contains detailed logging information and debug messages
Reports Directory: After execution, check
~/pts_reports/for CSV and HTML reports
6. Creating and Editing Recipes with Recipe Creator tool¶
For users who prefer a visual approach to recipe creation and editing, the Recipe
Creator tool provides an interactive recipe editor. In the codebase this editor
is implemented by the YamVIEW package.
Launching Recipe Creator
You can access Recipe Creator through the main PTS GUI:
Open the PTS application as described above
In the menu bar, navigate to Edit → Edit Recipe
A new window will open with the Recipe Creator recipe editor
The runtime GUI and YamVIEW are separate applications. The runtime GUI
launches the editor as a separate process, but both now share the same theme
layer and dark-mode behavior. See GUI Architecture.
Alternatively, if you have Recipe Creator installed separately, you can launch it directly:
python -m pypts.YamView.recipe_creator
Creating a New Recipe
In the Recipe Creator editor: 1. Click File → New Recipe (or the folder icon in the toolbar) 2. A dialog will appear prompting you to configure initial recipe settings 3. Fill in the recipe metadata (name, description, version) 4. Click OK to generate a template recipe 5. The YAML preview will appear on the right side of the editor
Editing Recipes
The Recipe Creator editor provides three main editing surfaces:
Sequencer Panel (Left): hierarchical sequence/step editor with toolbar actions
YAML Editor (Right): direct YAML text editing with syntax highlighting
Interactive Dialogs: double-click any step to open a configuration dialog
Adding Sequences and Steps
In the Sequencer Panel:
Click the “Add Sequence Folder” button (folder icon) to create a new sequence
Click the “➕” button to add a new step to the selected sequence
A dialog will open allowing you to configure the step type, parameters, and mappings
Select the appropriate step type from the dropdown (e.g., PythonModuleStep, WaitStep, UserInteractionStep)
Fill in the required fields for the selected step type
Click OK to add the step to the recipe
Disabling Steps
To temporarily disable steps without removing them:
Select one or more steps in the Sequencer Panel
Click the “±” button (Disable/Enable button)
A dialog will appear listing all steps in the selected sequence
Check the “Skip” checkbox for any steps you want to skip during execution
Check the “Continue on Error” checkbox to allow the recipe to continue even if a step fails
Click OK to apply the changes
Saving Recipes
To save your recipe:
Click File → Save Recipe (Ctrl+S) to save to the current file
Click File → Save Recipe As to save to a new location
Use the “Save” button in the toolbar (disk icon)
Validation and Recovery
The YamVIEW editor includes safety features:
Recipe Status Bar: Shows validation status at the top (green for valid, red for errors)
Recipe Verification: Recipes are automatically verified on save; if invalid, you’ll be prompted to fix errors
Recovery: Click “Restore last working recipe state” (reload icon) to revert to the last successfully validated version
Dark Mode: follows the operating system theme automatically and can still be toggled manually from View → Toggle Dark Mode
YAML Synchronization
The editor keeps the YAML view and the Sequencer in sync:
Edits in the YAML view are reflected in the Sequencer automatically
Changes in the Sequencer are immediately updated in the YAML view
Line highlighting shows which YAML section corresponds to the selected step