catcher.steps package

Submodules

catcher.steps.check module

class catcher.steps.check.All(body: dict, negative=False)[source]

Bases: catcher.steps.check.Operator

Fail if any check on the iterable fail.

Input:
Of:The source to check. Can be list or dictionary.
<check>:Check to perform on each element of the iterable.
Examples:

Pass if all elements of var has k == a

check:
    all:
        of: '{{ var }}'
        equals: {the: '{{ ITEM.k }}', is: 'a'}
operation(variables) → bool[source]
operator(data)[source]
class catcher.steps.check.And(body: dict, negative=False)[source]

Bases: catcher.steps.check.Operator

Fail if any of the conditions fails.

Input:The list of other checks.
Examples:

This is the same as 1 in list and list[1] != ‘b’ and list[2] > 2

check:
    and:
        - contains: {the: 1, in: '{{ list }}'}
        - equals: {the: '{{ list[1] }}', is_not: 'b'}
        - equals: {the: '{{ list[2] > 2 }}', is_not: true}
end
operation(variables) → bool[source]
class catcher.steps.check.Any(body: dict, negative=False)[source]

Bases: catcher.steps.check.All

Fail if all checks on the iterable fail.

Input:
Of:The source to check. Can be list or dictionary.
<check>:Check to perform on each element of the iterable.
Examples:

Fail if var doesn’t contain element with k == a

check:
    any:
        of: '{{ var }}'
        equals: {the: '{{ ITEM.k }}', is: 'a'}
operator(data)[source]
class catcher.steps.check.Check(_body=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Run check and fail if it was not successful.

There are two types of checks: terminators and nodes. Terminators like equals or contains just perform checks while nodes contain like all, any, or and others contain other checks.

Check has a short form

check: '{{ variable }}'

which equals

check:
    equals: {the: '{{ variable }}', is: true}
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
class catcher.steps.check.Contains(body: dict, negative=False)[source]

Bases: catcher.steps.check.Operator

Fail if list of dictionary doesn’t contain the value

Input:
The:value to contain
In:variable to check
Not_in:inverted in. Only one can be used at a time.
Examples:

Check ‘a’ not in variable ‘list’

check:
    contains: {the: 'a', not_in: '{{ list }}'}

Check variable ‘dict’ has key a.

check:
    contains: {the: 'a', in: '{{ dict }}'}
determine_source(body: dict)[source]
operation(variables: dict)[source]
static to_long_form(source: any, value: any)[source]
class catcher.steps.check.Equals(body: dict, negative=False)[source]

Bases: catcher.steps.check.Operator

Fail if elements are not equal

Input:
The:value
Is:variable to compare
Is_not:inverted is. Only one can be used at a time.
Examples:

Check ‘bar’ equals variable ‘foo’

check: {equals: {the: 'bar', is: '{{ foo }}'}}

Check list’s third element is not greater than 2.

check: {equals: {the: '{{ list[2] > 2 }}', is_not: true}}
determine_source(body: dict)[source]
operation(variables: dict) → bool[source]
static to_long_form(source: any, value: any)[source]
class catcher.steps.check.Operator(body: dict, negative=False)[source]

Bases: object

body
static find_operator(source: dict) → catcher.steps.check.Operator[source]
operation(variables: dict) → bool[source]
class catcher.steps.check.Or(body: dict, negative=False)[source]

Bases: catcher.steps.check.And

Fail if all conditions fail.

Input:The list of other checks.
Examples:

This is the same as 1 in list or list[1] != ‘b’ or list[2] > 2

check:
    or:
        - contains: {the: 1, in: '{{ list }}'}
        - equals: {the: '{{ list[1] }}', is_not: 'b'}
        - equals: {the: '{{ list[2] > 2 }}', is_not: true}
end

catcher.steps.echo module

class catcher.steps.echo.Echo(_path: str = None, _body=None, to=None, from_file=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Print a string constant, variable or file to the console or file.

Input:
From:data source. Can be variable or constant string
From_file:file in resources.
To:output to file. Optional If not set - stdout will be used. Not resources-related

Has short from which just prints variable to stdout.

Examples:

Use short form to print variable to stdout

echo: '{{ var }}'

Print constant + variable to file

echo: {from: 'constant and {{ var }}', to: debug.output}

Use echo to register new variable

echo: {from: '{{ RANDOM_STR }}@test.com', register: {user_email: '{{ OUTPUT }}'}}

Read file content to a variable

echo: {from_file: debug.output, to: '{{ user_email }}'}
action(includes: dict, variables: dict) → tuple[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}

catcher.steps.external module

class catcher.steps.external.External(_module: str = None, **kwargs)[source]

Bases: catcher.steps.step.Step

action(includes: dict, variables: dict) → tuple[source]

Call external script.

Parameters:
  • includes – testcase’s includes
  • variables – variables
Returns:

script’s output

catcher.steps.external_step module

class catcher.steps.external_step.ExternalStep(**kwargs)[source]

Bases: catcher.steps.step.Step

Implement this step in case you are adding external python module to catcher-modules project

action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

variables and step’s output. Output is optional.

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT }}'}

in_data will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
simple_input(variables)[source]

Use this method to get simple input as python object, with all templates filled in

Parameters:variables
Returns:python object

catcher.steps.loop module

class catcher.steps.loop.Loop(_get_action=None, _get_actions=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Repeat one or several actions till the condition is true or for each element of the collection. Is useful, when you need to wait for some process to start or for async execution to finish.

Input:
While:perform action while the condition is true
  • if: your condition. It can be in short format: if: ‘{{ counter < 10 }}’ and
    long one: if: {equals: {the: ‘{{ counter }}’, is_not: 10000}}. The clause format is the same as in [checks](checks.md)
  • do: the aciton to be performed. Can be a list of actions or single one.
  • max_cycle: the limit of reductions. Optional default is no limit.
Foreach:iterate data structure
  • in: variable or static list. ITEM variable can be used to access each element of the data structure.
    Data structure can be list, dict or any other python data structure which supports iteration.
  • do: the action to be performed. Can be a list of actions or single one.
Examples:

Perform a single echo wile counter is less than 10

loop:
    while:
        if: '{{ counter < 10 }}'
        do:
            echo: {from: '{{ counter + 1 }}', register: {counter: '{{ OUTPUT }}'}}
        max_cycle: 100000

Perform to actions: consume message from kafka and send token via POST http. Do it until server returns passed true in http response.

loop:
    while:
        if:
            equals: {the: '{{ passed }}', is_not: True}
        do:
            - kafka:
                  consume:
                      server: '127.0.0.1:9092'
                      group_id: 'test'
                      topic: 'test_consume_with_timestamp'
                      timeout: {seconds: 5}
                      where:
                          equals: '{{ MESSAGE.timestamp > 1000 }}'
                  register: {token: '{{ OUTPUT.data.token }}'}
            - http:
                post:
                  headers: {Content-Type: 'application/json'}
                  url: 'http://test.com/check_my_token'
                  body: {'token': '{{ token }}'}
                register: {passed: '{{ OUTPUT.passed }}'}

Iterate over iterator variable, produce each element to kafka as json and debug it to file.

loop:
    foreach:
        in: '{{ iterator }}'
        do:
            - kafka:
                  produce:
                      server: '127.0.0.1:9092'
                      topic: 'test_produce_json'
                      data: '{{ ITEM|tojson }}'
            - echo: {from: '{{ ITEM }}', to: '{{ ITEM["filename"] }}.output'}

Iterate over several different configurations.

variables:
    db_1: 'test:test@localhost:5433/db1'
    db_2:
        url: 'test:test@localhost:5434/db2'
        type: postgres
    db_3:
        dbname: 'db3'
        user: 'test'
        password: 'test'
        host: 'localhost'
        port: 5435
        type: 'postgres'
steps:
    - loop:
        foreach:
            in: '["{{ db_1 }}", {{ db_2 }}, {{ db_3 }}]'
            do:
                - postgres:
                    request:
                        conf: '{{ ITEM }}'
                        query: 'select count(*) from test'
                    register: {documents: '{{ OUTPUT }}'}
                - check:
                    equals: {the: '{{ documents.count }}', is: 2}

Note that db_1 template has additional quotes "{{ db_1 }}". Your in should contain valid object. As db_1 is just a string - it should be put in quotes. Otherwise in value will be corrupted. Always make sure your in value is valid. It may also have some difficulties with json as string.

action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}

catcher.steps.http module

class catcher.steps.http.Http(**kwargs)[source]

Bases: catcher.steps.step.Step

Perform an http request: from just getting the information from the server to pushing a file to it.

Input:
<method>:http method. Most frequent are get/post/put/delete. See docs for details
  • headers: Dictionary with custom headers. Optional
  • url: url to call
  • response_code: Code to await. Use ‘x’ for a wildcard or ‘-’ to set a range between 2 codes.
    Optional default is 200.
  • body: body to send. Optional.
  • body_from_file: File can be used as data source. Optional.
  • files: send file from resources (only for methods which support it). Optional
  • verify: Verify SSL Certificate in case of https. Optional. Default is true.
  • should_fail: true, if this request should fail, f.e. to test connection refused. Will fail the test if no errors.
  • session: http session name. Cookies are saved between sessions. Optional. Default session is ‘default’.
    If set to null - there would be no session.
  • fix_cookies: if true will make cookies secure if you use https and not secure if you don’t. Optional.
    Default is true. Is useful when you don’t have tls for your test env, but can’t change infra.
  • timeout: number of seconds to wait for response. Optional. Default is no timeout (wait forever)
Files:is a single file or list of files, where <file_param> is a name of request param. If you don’t specify headers ‘multipart/form-data’ will be set automatically.
  • <file_param>: path to the file
  • type: file mime type
Cookies:All requests are run in the session, sharing cookies got from previous requests. If you wish to start new empty session use session. If you don’t want a session to be saved use session: null
Examples:

Put data to server and await 200-299 code

http:
  put:
    url: 'http://test.com?user_id={{ user_id }}'
    body: {'foo': bar}
    response_code: 2XX

Put data to server and await 201-3XX code

http:
  put:
    url: 'http://test.com?user_id={{ user_id }}'
    body: {'foo': bar}
    response_code: 201-3xx

Post data to server with custom header

http:
  post:
    headers: {Content-Type: 'application/json', Authorization: '{{ token }}'}
    url: 'http://test.com?user_id={{ user_id }}'
    body: {'foo': bar}

Post file to remote server

http:
  post:
    url: 'http://test.com'
    body_from_file: "data/answers.json"

SSL without verification

http:
  post:
    url: 'https://my_server.de'
    body: {'user':'test'}
    verify: false

Manual set of json body. tojson will convert ‘var’ to json string

http:
  post:
    url: 'http://test.com?user_id={{ user_id }}'
    body: '{{ var |tojson }}'

Set json by providing json headers and passing python object to body

http:
  post:
    url: 'http://test.com?user_id={{ user_id }}'
    headers: {Content-Type: 'application/json'}
    body: '{{ var  }}'

Send file with a post request

http:
  post:
    url: 'http://example.com/upload'
    files:
        file: 'subdir/my_file_in_resources.csv'
        type: 'text/csv'

Send multiple files with a single post request

http:
  post:
    url: 'http://example.com/upload'
    files:
        - my_csv_file: 'one.csv'
          type: 'text/csv'
        - my_json_file: 'two.json'
          type: 'application/json'

Test disconnected service:

steps:
- docker:
    disconnect:
        hash: '{{ my_container }}'
- http:
    get:
        url: '{{ my_container_url }}'
        should_fail: true

Test correct and incorrect login (clear cookies):

steps:
    - http:
        post:
            url: 'http://test.com/login.php?user_id={{ user_id }}'
            body: {'pwd': secret}
            response_code: 2XX
            session: 'user1'
        name: "Do a login"
    - http:
        get:
            url: 'http://test.com/protected_path'
            response_code: 2XX
            session: 'user1'
        name: "Logged-in user can access protected_path"
    - http:
        get:
            url: 'http://test.com/protected_path'
            response_code: 401
            session: 'user2'
        name: "protected_path can't be accessed without login"
action(includes: dict, variables: dict) → Union[tuple, dict][source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
sessions = {}

grpc - perform a remote procedure call request

class catcher.steps.grpc_step.GRPC(call=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Perform a remote procedure call with protobuffers layer.

Input:
Call:Make a remote procedure call
  • url: server url
  • function: service and method you are going to call separated by dot. Case insensitive (MyClass.my_function)
  • schema: path to the .proto resource file. Optional Ignore it if reflection is configured on the server side
  • data: data to pass. Optional
Examples:

calculator.proto

message Number {
    float value = 1;
}

service Calculator {
    rpc SquareRoot(Number) returns (Number) {}
}

test

grpc:
    call:
        url: 'localhost:50051'
        function: calculator.squareroot
        schema: 'calculator.proto'
        data: {'value': 2}
    register: {'my_value': '{{ OUTPUT.value }}'

Complex schema case:

grpc:
    call:
        url: 'localhost:50051'
        function: greeter.greet
        schema: 'greeter.proto'
        data:
            result:
                url: '{{ my_url }}'
                title: 'test'
                snippets: 'test2'
    register: {value: '{{ OUTPUT.name }}'}

Useful tip: if you’d like to use templates in your .proto file - do not do it in the original resources, as Catcher shouldn’t modify them. Use echo step to fill a template and create another .proto file for you.

action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}

catcher.steps.run module

class catcher.steps.run.Run(ignore_errors=False, _body=None, run=None, include=None, tag=None, variables=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Run another test, included later. Is useful when you need to run the same code from different tests or to repeat the same steps inside one test but with different input variables.

Input:
Include:include name. If contains dot - everything after dot will be considered as tag. In case of multiple dots the last one will be considered as tag.
Variables:Variables to override. Optional
Examples:

Use short form to run sign_up

include:
    file: register_user.yaml
    as: sign_up
steps:
    # .... some steps
    - run: sign_up
    # .... some steps

Run sign_up include test twice for 2 different users

include:
    file: register_user.yaml
    as: sign_up
variables:
    users: ['{{ random("email") }}', '{{ random("email") }}']
steps:
    # .... some steps
    - run:
        include: sign_up
        variables:
            user: '{{ users[0] }}'
    # .... some steps
    - run:
        include: sign_up
        variables:
            user: '{{ users[1] }}'

Include sign_up and run all steps with tag register from it.

include:
    file: register_and_login.yaml
    as: sign_up
steps:
    - run:
        include: sign_up.register

Include one.yaml from main and run only before tag of it. main.yaml -> one.yaml -> two.yaml. main.yaml

include:
    file: one.yaml
    as: one
steps:
    - run: 'one.before'

one.yaml

include:
    file: two.yaml
    as: run_me
steps:
    - run:
        include: two.run_me
        tag: before
    - echo: {from: '{{ bar }}', to: after.output, tag: after}

two.yaml

steps:
    - echo: {from: '1', to: foo.output, tag: run_me}
    - echo: {from: '2', to: baz.output, tag: two}
    - echo: {from: '3', to: bar.output, tag: three}
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
catcher.steps.run.get_tag(include: str) → str[source]

catcher.steps.sh_step module

class catcher.steps.sh_step.Sh(command=None, path=None, return_code=0, **kwargs)[source]

Bases: catcher.steps.step.Step

Run shell command and return output.

Input:
  • command: Command to run.
  • path: Path to be used as a root for the command. Optional.
  • return_code: expected return code. Optional. 0 is default.
Examples:

List current directory

- sh:
    command: 'ls -la'

Determine if running in docker

variables:
    docker: true
steps:
    - sh:
        command: "grep 'docker|lxc' /proc/1/cgroup"
        return_code: 1
        ignore_errors: true
        register: {docker: false}
    - echo: {from: 'In docker: {{ docker }}'}
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}

catcher.steps.step module

class catcher.steps.step.MetaStep[source]

Bases: type

exception catcher.steps.step.SkipException(message)[source]

Bases: Exception

class catcher.steps.step.Step(register=None, name=None, ignore_errors=False, skip_if=None, **kwargs)[source]

Bases: object

Abstract class for all Steps. Operates with common properties, available for all steps.

Register:register a new variable at the end of this step. Optional
Name:Set name for this step. Is used for passed steps output. Optional
Ignore_errors:Do not stop the test if this step fails. Can be useful with running includes. Optional
Tag:Tag this step to be called via run with tag. Optional
Skip_if:Skip condition. This step will be skipped if condition is true. Optional
Run_if:Run type for final action. Optional. ‘pass’ will run action only if test passes, ‘fail’ will run action only if test fails. ‘always’ will always run action. It is the default value.
Actions:Each step can have one ore multiple actions. In case of one action actions list is not necessary and you can use short form. Also - in case of several actions each should have its own properties like register, tag etc…

One action - short form.

http:
    post:  # register client and get id
         url: '{{ user_service_url }}/sign_up'
         body: {email: '{{ email }}', name: '{{ user }}'}

Multiple actions.

http:
    actions:
      - post:  # register client and get id
          url: '{{ user_service_url }}/sign_up'
          body: {email: '{{ email }}', name: 'TestUser'}
      - post:  # fill some personal data
          url: '{{ user_service_url }}/data'
          body: {gender: 'M', age: 22, firstName: 'John', lastName: 'Doe'}
Examples:

Register new variable after echo step finishes.

echo: {from: '{{ RANDOM_STR }}@test.com', register: {user_email: '{{ OUTPUT }}'}}

Tag both http actions with sign_up

http:
    actions:
      - post:  # register client and get id
          url: '{{ user_service_url }}/sign_up'
          headers: {Content-Type: 'application/json'}
          body: {email: '{{ email }}', name: 'TestUser'}
          response_code: 201
        register: {token: '{{ OUTPUT.data.token }}'}
        tag: sign_up
      - post:  # fill some personal data
          url: '{{ user_service_url }}/data'
          headers: {Content-Type: 'application/json', Authorization: '{{ token }}'}
          body: {gender: 'M', age: 22, firstName: 'John', lastName: 'Doe'}
        register: {uuid: '{{ OUTPUT.data.uuid }}'}
        tag: sign_up

Use custom name for the step

http:
    post:  # register client and get id
         url: '{{ user_service_url }}/sign_up'
         headers: {Content-Type: 'application/json'}
         body: {email: '{{ email }}', name: '{{ user }}'}
         response_code: 201
    name: 'Register {{ user }} on remote server'

Ignore errors and continue to another step

http: {get: {url: 'http://test.com', response_code: 200}, ignore_errors: true}

Skip one step based on variable got

steps:
    - http:
        get:
            url: '{{ my_web_service }}/api/v1/users?id={{ user_id }}'
        register: {registration_type: '{{ OUTPUT.data.registration }}'}
        name: 'Determine registration type for user {{ user_id }}'
    - postgres:
        request:
            conf: 'test:test@localhost:5433/test'
            query: "insert into loans(value) values(1000) where user_id == '{{ user_id }}';"
        name: 'Update user loan for facebook user'
        skip_if:
            equals: {the: '{{ registration_type }}', is_not: 'facebook'}
    - couchbase:
        request:
            conf:
                bucket: loans
                host: localhost
            put:
                key: '{{ user_id }}'
                value: {value: 1000}
        skip_if:
            equals: {the: '{{ registration_type }}', is_not: 'other'}

Run step and do some clean up after

steps:
    - http:
        get:
            url: '{{ my_web_service }}/api/v1/users?id={{ user_id }}'
        register: {registration_type: '{{ OUTPUT.data.registration }}'}
        name: 'Determine registration type for user {{ user_id }}'
    - postgres:
        request:
            conf: '{{ postgres_conf }}'
            query: "insert into loans(value) values(1000) where user_id == '{{ user_id }}';"
        name: 'Update user loan for facebook user'
finally:
    - postgres:
        request:
            conf: '{{ postgres_conf }}'
            query: "delete from loans(value) where user_id == '{{ user_id }}';"
        name: 'Clean up user'
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
check_skip(variables: dict)[source]
static filter_predefined_keys(kwargs: dict)[source]
process_register(variables, output: dict = None) → dict[source]
catcher.steps.step.register_class(target_class)[source]
catcher.steps.step.update_variables(func)[source]

Use this decorator on Step.action implementation.

Your action method should always return variables, or both variables and output.

This decorator will update variables with output.

catcher.steps.stop module

class catcher.steps.stop.Stop(**kwargs)[source]

Bases: catcher.steps.step.Step

Stop a test without error

Input:
If:condition
Examples:

Stop execution if migration was applied.

steps:
    - postgres:
        request:
            conf: '{{ migrations_postgres }}'
            query: "select count(*) from migration where hash = '{{ TEST_NAME }}';"
        register: {result: '{{ OUTPUT }}'}
        tag: check
        name: 'check_migration_{{ TEST_NAME }}'
    - stop:
        if:
            equals: {the: '{{ result }}', is: 1}
    - postgres:
        request:
            conf: '{{ migrations_postgres }}'
            query: "insert into migration(id, hash) values(1, '{{ TEST_NAME }}');"
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
exception catcher.steps.stop.StopException(message)[source]

Bases: Exception

catcher.steps.wait module

class catcher.steps.wait.Wait(_get_action=None, _get_actions=None, **kwargs)[source]

Bases: catcher.steps.step.Step

Wait for a static delay or until some substep finished successfully. Is extremely useful for testing asnyc systems or when you are waiting for some service to launch.

Input:
Days:several days
Hours:several hours
Minutes:several minutes
Seconds:several seconds
Microseconds:several microseconds
Milliseconds:several milliseconds
Nanoseconds:several nanoseconds
For:(list of actions) will repeat them till they all finishes successfully. Will fail if time ends.
Examples:

Wait for 1 minute 30 seconds

wait: {minutes: 1, seconds: 30}

Wait for http to be ready. Will repeat inner http step till is succeeded or fails after 5 seconds

wait:
    seconds: 5
    for:
        http:
            put:
                url: 'http://localhost:8000/mockserver/expectation'
                body:
                    httpRequest: {'path': '/some/path'}
                    httpResponse: {'body': 'hello world'}
                response_code: 201

Wait for postgres to be populated

wait:
    seconds: 30
    for:
        - postgres:
              request:
                  conf: '{{ pg_conf }}'
                  query: 'select count(*) from users'
              register: {documents: '{{ OUTPUT }}'}
        - check: {equals: {the: '{{ documents }}', is_not: 0}}
action(includes: dict, variables: dict) → dict[source]

Perform an action.

Parameters:
  • includes – Script includes.
  • variables – Script variables.
Returns:

step output

For code above

postgres:
    request:
        conf:
            dbname: test
            user: test
            password: test
            host: localhost
            port: 5433
        query: 'select count(*) from test'
register: {documents: '{{ OUTPUT.count }}'}

step’s input will be

{'request' : {'conf': {'dbname': 'test', 'user': 'test', 'password': 'test', 'host': 'localhost', 'port': 5433},
              'query': 'select count(*) from test'}
}
run_loop(includes, variables)[source]

Module contents