pyATS Easypy enables the execution of multiple test scripts organized through a job file, with built-in logging and reporting features. It is commonly used in production environments where structured test execution and result archiving are required.

pyATS Easypy and Job FIle

Test scripts in pyATS can be executed in two ways: Standalone execution and Easypy execution.
So far, we have used the standalone method to run individual test scripts.

Easypy execution is designed for production environments, where structured logging, reporting, and archiving are essential. When scripts are run through the Easypy runtime, the environment takes full control of execution and offers several key benefits:

  • Run multiple test scripts together via a job file

  • Automatically generate task logs, result reports, and log archives

pyATS Easypy Features
pyATS Easypy Features

In this lesson, we won’t dive deeply into the full capabilities of job files. Instead, we will create a simple job file to execute multiple test scripts using the Easypy environment, and demonstrate its logging and reporting features.

pyATS Easypy Configuration Example

To demonstrate pyATS Easypy, I have prepared two AEtest test scripts:

The first script prints the IOS version of the devices to ensure they are all running the most current version.

The second script pings an external IP address (8.8.8.8) to verify that Internet connectivity is still functional.

The only difference between these scripts and the AEtest scripts we’ve previously discussed is that no testbed file is provided directly as input. Instead, the testbed is passed through pyATS Easypy at runtime.

(majid) majid@majid-ubuntu:~/devnet/pyats$ cat 8.1.easypy_testscript1.py
from pyats import aetest
from genie.testbed import load
from pyats.async_ import pcall

class Version_Check(aetest.Testcase):
    @aetest.setup
    def setup(self, testbed):
        self.testbed = load(testbed)
        self.device_list = [dev for dev in self.testbed.devices.values()]

    @aetest.test
    def check_version(self):
        def get_version(device):
            device.connect(log_stdout=False)

            output = device.parse('show version')

            print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("device=",device.name," version=",output['version']['version'])
            print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")

            device.disconnect()

        # Use pcall correctly by passing the devices as a positional argument
        pcall(get_version, device=self.device_list)


if __name__ == '__main__':
    aetest.main()
(majid) majid@majid-ubuntu:~/devnet/pyats$ cat 8.2.easypy_testscript2.py
import json
from genie.testbed import load
from pyats.async_ import pcall
from pyats import aetest
from genie.conf import Genie

class PingCheck(aetest.Testcase):
    @aetest.setup
    def setup(self, testbed):
        self.testbed = load(testbed)
        self.device_list = [dev for dev in self.testbed.devices.values()]

    @aetest.test
    def check_ping(self):
        def ping_test(device):
            device.connect(log_stdout=False)
            output = device.execute("ping 8.8.8.8")
            print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            print("device=",device.name," ping output=",output)
            print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
            device.disconnect()

        pcall(ping_test, device=self.device_list)


if __name__ == '__main__':
    aetest.main()

What’s new here is the introduction of a simple job file, named 8.run_testcases_using_easypy.py, which is used to execute both test scripts.

(majid) majid@majid-ubuntu:~/devnet/pyats$ cat 8.run_testcases_using_easypy.py
from pyats.easypy import run

def main():
    run('8.1.easypy_testscript1.py')
    run('8.2.easypy_testscript2.py')

While job files in pyATS are powerful and can include conditional logic, loops, and advanced orchestration, we will not explore those capabilities in this lesson. Our focus is simply on using a basic job file to run multiple scripts.

By running the command „pyats run job –help“, you can view the wide range of options and arguments supported by Easypy. These include:

  • Specifying testbed and job files

  • Configuring execution logic for test scripts

  • Setting up logging and reporting

  • Defining email notifications

  • And many other advanced parameters for customizing your test runs

(majid) majid@majid-ubuntu:~/devnet/pyats$ pyats run job --help
  from pyats.cli.__main__ import main
Usage:
  pyats run job [file] [options]

Example
-------
  pyats run job /path/to/jobfile.py
  pyats run job /path/to/jobfile.py --testbed-file /path/to/testbed.yaml

Description:
  Runs a pyATS job file with the provided arguments, generating & report result.

Configuration:
  -C, --configuration FILE
                        easypy configuration yaml file for plugins

Job Information:
  JOBFILE               target jobfile to be launched
  --job-uid             Unique ID identifiying this job run
  --pyats-configuration
                        pyats configuration override file

Suite Info:
...
Tasks:
  --task-uids LOGIC     Logic string to match task UIDs to run eg: "Or('Task-[12]')"

Mailing:
...
Reporting:
...
Runinfo:
...
Liveview:
...
Testbed:
  -t, --testbed-file    Specify testbed file location

Clean:
...
Bringup:
...
Rerun:
...
xUnit:
...
HTML Logging:
...
mapleClean:
...
Abstract:
...
pyATS Health:
...
TopologyUpPlugin:
...
WebEx:
...
General Options:
...

We then execute the job file using the pyATS Easypy command:

pyats run job 8.run_testcases_using_easypy.py --testbed-file  testbed.yaml
...
2025-05-28T11:51:53: %EASYPY-INFO:     testscript   = /home/majid/devnet/pyats/8.1.easypy_testscript1.py
<module 'pyats.aetest.testscript.8.1.easypy_testscript1' from '/home/majid/devnet/pyats/8.1.easypy_testscript1.py'>
...
2025-05-28T11:51:53: %LOG-INFO: >>>> Begin child log /home/majid/.pyats/runinfo/8.run_testcases_using_easypy.2025May28_11:51:48.768120/TaskLog.Task-1:pid-908117
2025-05-28T11:51:53: %LOG-INFO: >>>> Begin child log /home/majid/.pyats/runinfo/8.run_testcases_using_easypy.2025May28_11:51:48.768120/TaskLog.Task-1:pid-908132
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
device= R1  version= 17.1.1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
device= R2  version= 17.1.1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
...
2025-05-28T11:52:07: %EASYPY-INFO:     testscript   = /home/majid/devnet/pyats/8.2.easypy_testscript2.py
<module 'pyats.aetest.testscript.8.2.easypy_testscript2' from '/home/majid/devnet/pyats/8.2.easypy_testscript2.py'>
...
2025-05-28T11:52:08: %LOG-INFO: >>>> Begin child log /home/majid/.pyats/runinfo/8.run_testcases_using_easypy.2025May28_11:51:48.768120/TaskLog.Task-2:pid-908302
2025-05-28T11:52:08: %LOG-INFO: >>>> Begin child log /home/majid/.pyats/runinfo/8.run_testcases_using_easypy.2025May28_11:51:48.768120/TaskLog.Task-2:pid-908316
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
device= R1  ping output= Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 7/7/8 ms
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
device= R2  ping output= Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
...
2025-05-28T11:52:22: %EASYPY-INFO: +------------------------------------------------------------------------------+
2025-05-28T11:52:22: %EASYPY-INFO: |                                Easypy Report                                 |
2025-05-28T11:52:22: %EASYPY-INFO: +------------------------------------------------------------------------------+
2025-05-28T11:52:22: %EASYPY-INFO: pyATS Instance   : /home/majid
2025-05-28T11:52:22: %EASYPY-INFO: Python Version   : cpython-3.12.3 (64bit)
2025-05-28T11:52:22: %EASYPY-INFO: CLI Arguments    : /home/majid/bin/pyats run job 8.run_testcases_using_easypy.py --testbed-file testbed.yaml
2025-05-28T11:52:22: %EASYPY-INFO: User             : majid
2025-05-28T11:52:22: %EASYPY-INFO: Host Server      : majid-ubuntu
2025-05-28T11:52:22: %EASYPY-INFO: Host OS Version  : Ubuntu 24.04 noble (x86_64)
2025-05-28T11:52:22: %EASYPY-INFO:
2025-05-28T11:52:22: %EASYPY-INFO: Job Information
2025-05-28T11:52:22: %EASYPY-INFO:     Name         : 8.run_testcases_using_easypy
2025-05-28T11:52:22: %EASYPY-INFO:     Start time   : 2025-05-28 11:51:53.470119+02:00
2025-05-28T11:52:22: %EASYPY-INFO:     Stop time    : 2025-05-28 11:52:21.679563+02:00
2025-05-28T11:52:22: %EASYPY-INFO:     Elapsed time : 0:00:29
2025-05-28T11:52:22: %EASYPY-INFO:     Archive      : /home/majid/.pyats/archive/25-05/8.run_testcases_using_easypy.2025May28_11:51:48.768120.zip
...
2025-05-28T11:52:22: %EASYPY-INFO: Task-1: 8.1.easypy_testscript1
2025-05-28T11:52:22: %EASYPY-INFO: `-- Version_Check                                                         PASSED
2025-05-28T11:52:22: %EASYPY-INFO:     |-- setup                                                             PASSED
2025-05-28T11:52:22: %EASYPY-INFO:     `-- check_version                                                     PASSED
2025-05-28T11:52:22: %EASYPY-INFO: Task-2: 8.2.easypy_testscript2
2025-05-28T11:52:22: %EASYPY-INFO: `-- PingCheck                                                             PASSED
2025-05-28T11:52:22: %EASYPY-INFO:     |-- setup                                                             PASSED
2025-05-28T11:52:22: %EASYPY-INFO:     `-- check_ping                                                        PASSED
2025-05-28T11:52:22: %EASYPY-INFO: Sending report email...
...
Pro Tip
-------
    Try the following command to view your logs:
        pyats logs view

In this example, the only argument passed to Easypy is the testbed file, demonstrating how testbed configuration can be provided at the Easypy runtime level instead of inside individual scripts.

Easypy begins by loading and running each test script defined in the job file. In this case, two AEtest scripts were executed: one that checks IOS versions of the devices to verify they are up to date, and another that performs connectivity checks by pinging a public IP (8.8.8.8). For each device, the test output is displayed, including version details and ping results with success rates.

At the end of execution, Easypy generates a structured summary report showing the results of each test section and script. Both scripts completed successfully with all test sections marked as PASSED. Additional metadata, such as job start/stop time, elapsed duration, archive location, and environment details, are also logged. Easypy also creates individual task logs and a zipped archive of all outputs, ready for review or automated distribution (e.g., email reports).

Monitor pyATS Logs and Reports

To monitor the logging and reporting results of a „pyats run job“ execution, we use the „pyats logs view“ command. This command launches a graphical web interface that provides a structured overview of the logs and reports generated during the pyATS job run.

Once executed, it hosts a local webpage displaying a summary of test results, including pass/fail status, a detailed results table, logs, and the commands executed during the test. The interface enables users to navigate through archived logs, examine individual test outcomes, and analyze execution details in a clear and organized format.

The screenshots below confirm that the test run was successful, with all tasks passing. The logs include execution metadata such as timestamps, testbed configurations, and command outputs. Additionally, the interface offers access to downloadable artifacts like reports, environment configurations, and test logs for further analysis.

pyats logs view results
pyats logs view results
pyats logs view overview
pyats logs view overview
Back to: Network Automation with pyATS & Genie (in Progress) > Automating Network Testcases with AEtest

Leave a Reply

Your email address will not be published. Required fields are marked *


Post comment