Skip to content

Hooks

In a workflow, you can use provider plugin functions. Generator plugins can also generate jobs that use provider plugin functions.

Sometimes you may want to customize the resulting steps. If you are calling those functions directly, you can add steps before or after the call, but this can be tedious if you have many calling points. And if you are using generator plugins, you have no control.

The OpenTestFactory orchestrator supports hooks that help in this regard. A hook is a point where you can alter the default behavior.

Hooks are currently defined for provider plugin functions: you can define steps that will be added before the function steps or after the function steps. They are also defined for channel handlers: you can customize the workspace preparation process as well as the workspace cleanup process of your jobs.

Hooks are statements of the form:

hooks:
- name: my pre-checkout hook
  events:
  - categoryPrefix: actions
    category: checkout
  before:
  - run: echo about to perform a checkout

They have mandatory name and events parts. They must also have either a before part or an after one (or both). Finally, they may have a conditional part, if, to restrict their scopes.

You can define hooks in your workflow, in which case they will apply to your workflow only. You can also define hooks for your provider plugins and channel handlers, at installation or configuration time, in which case they will apply to all workflows that use the plugin or channel handler.

Defining hooks in your workflow

In your workflow, you can add a hooks section. In this example, hello world will be echoed in the console just before running the Robot Framework test.

apiVersion: opentestfactory.org/v1alpha1
kind: Workflow
metadata:
  name: RobotFramework Example
hooks:
  - name: robot setup
    events:
    - category: robot
      categoryPrefix: robotframework
    before:
    - run: echo hello world
jobs:
  keyword-driven:
    runs-on: [windows, robotframework]
    steps:
    - uses: actions/checkout@v2
      with:
        repository: https://github.com/robotframework/RobotDemo.git
    - run: 'dir'
      working-directory: RobotDemo
    - uses: robotframework/robot@v1
      with:
        datasource: RobotDemo/keyword_driven.robot

Defining provider hooks using a definition file

Please refer to “Common provider settings” for examples and instructions if you want to define hooks using a definition file.

Defining job hooks using a definition file

Please refer to “Agent channel plugin” and “SSH channel plugin” for examples and instructions if you want to define job hooks in your channel handlers using a definition file.

Use cases

Additional attachments

Context

On your site, you are using a specific library with your testing framework that takes screenshots during test execution and put them in a known directory (target/screenshots).

The screenshots will have random names, but are all in PNG format, with the .png file name extension.

You want to have those screenshots attached to the test case execution in your test case manager.

Implementation

hooks:
- name: screenshots loader
  events:
  - categoryPrefix: robotframework
    category: execute
  after:
  - uses: actions/get-files
    with:
      pattern: *.png
    working-directory: target/screenshots

If you are unsure of the directory content before running the test, you can add a before section to ensure it is cleaned:

  before:
  - uses: actions/delete-file
    with:
      path: *.png
    working-directory: target/screenshots
    continue-on-error: true

The continue-on-error argument is added so that the job can continue if the directory does not yet exist.

You can insert this hook in your workflow or your provider plugin configuration file.

JUnit detailed execution logs

Context

JUnit execution logs can be verbose, but they are helpful when trying to investigate technical issues.

The JUnit provider stores its execution log in a target/junit-run-log.txt file.

You want to have this execution log displayed if the test execution fails.

Implementation

hooks:
- name: execution logs on failure (linux)
  events:
  - categoryPrefix: junit
    category: execute
  if: runner.os == 'linux'
  after:
  - run: find . -name junit-run-log.txt -print | xargs cat
    if: failure()
- name: execution logs on failure (windows)
  events:
  - categoryPrefix: junit
    category: execute
  if: runner.os == 'windows'
  after:
  - run: '@for /f %%i in (''dir /b/s "junit-run-log.txt"'') do @type %%i'
    if: failure()

You insert this hook in your JUnit plugin configuration file. (You should do it in the plugin configuration file so that it applies to all workflows. You can test it in a workflow, though.)

Audit logs

Context

As a platform manager, you want to record whenever the execute and cucumber functions of the Cucumber plugin are called. You have Linux and Windows execution environments.

Implementation

hooks:
- name: audit log (linux)
  events:
  - categoryPrefix: cucumber
    category: execute
  if: runner.os == 'linux'
  before:
  - run: logger -n 192.168.1.2 "Cucumber is about to be used"
- name: audit log (windows)
  events:
  - categoryPrefix: cucumber
    category: execute
  if: runner.os == 'windows'
  before:
  - run: eventcreate /Id 7777 /D "Cucumber is about to be used" /T INFO /L system

You insert this hook in your Cucumber plugin configuration file. (You should do it in the plugin configuration file so that it applies to all workflows. You can test it in a workflow, though.)

Keep the execution workspace on failure

Context

You want to keep the execution workspace on failure, to be able to investigate the issue.

Implementation

hooks:
- name: keep workspace on failure
  events:
  - channel: teardown
  if: failure()
  before:
  - keep-workspace: true
    if: failure()

You insert this hook in the hook definition file you have defined for your Agent channel handler or SSH channel handler.

If a job fails, there will be an entry in the execution log telling you the workspace was kept, and the workspace will be available for investigation.

[2023-06-22T16:46:53] [job ...] Keeping workspace 'C:\Users\me\work\6ca11248-a555-4a77-a186-d89d9958df04' on execution environment

Start and stop a service

Context

To save resources, you want to start a specific service before running your test using a given testing framework, and you want to stop if after the test execution.

You want this behavior for explicit use of the testing framework as well as for implicit use (for tests executed via a generator plugin).

Implementation

hooks:
- name: manage myservice
  events:
  - categoryPrefix: robotframework
    category: execute
  - categoryPrefix: robotframework
    category: robot
  before:
  - run: service start myservice
  after:
  - run: service stop myservice
    if: always()
    continue-on-error: true

The continue-on-error: argument is used so that the job can continue even if something went wrong while stopping the service.

The if: always() argument is used so that the service is stopped even if an execution error occurred in a previous step.

You insert this hook in your Robot Framework plugin configuration file. (You should do it in the plugin configuration file so that it applies to all workflows. You can test it in a workflow, though.)

Conditional behavior

Context

As a platform manager, you want to provide an optional database service to your users when using a given function.

They will have to set a NEED_DATABASE environment variable to activate it.

Example
jobs:
  my_job:
    ...
    steps:
    ...
    - uses: myplugin/myfunction
      variables:
        NEED_DATABASE: yes
    ...

They may also choose to set the environment variable at job- or workflow-level, so that the service is available for all functions in the job or workflow, respectively.

Implementation

hooks:
- name: manage database
  events:
  - categoryPrefix: myplugin
    category: myfunction
  if: variables.NEED_DATABASE == 'yes'
  before:
  - run: start_db
  after:
  - run: stop_db
    if: always()
    continue-on-error: true

This differs from the ‘Start and stop a service’ use-case in that no code is added if the feature is not used.

You insert this hook in your myplugin plugin configuration file. (You should do it in the plugin configuration file so that it applies to all workflows. You can test it in a workflow, though.)

Next steps

Here are some helpful resources for taking your next steps with the OpenTestFactory hooks: