iac-test


Nameiac-test JSON
Version 0.2.5 PyPI version JSON
download
home_pagehttps://github.com/netascode/iac-test
SummaryA CLI tool to render and execute Robot Framework tests using Jinja templating.
upload_time2023-11-17 13:36:29
maintainerDaniel Schmidt
docs_urlNone
authorDaniel Schmidt
requires_python>=3.8,<4.0
licenseLICENSE
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![Tests](https://github.com/netascode/iac-test/actions/workflows/test.yml/badge.svg)](https://github.com/netascode/iac-test/actions/workflows/test.yml)
![Python Support](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-informational "Python Support: 3.8, 3.9, 3.10, 3.11, 3.12")

# iac-test

A CLI tool to render and execute [Robot Framework](https://robotframework.org/) tests using [Jinja](https://jinja.palletsprojects.com/) templating. Combining Robot's language agnostic syntax with the flexibility of Jinja templating allows dynamically rendering a set of test suites from the desired infrastructure state expressed in YAML syntax.

```shell
$ iac-test -h
Usage: iac-test [OPTIONS]

  A CLI tool to render and execute Robot Framework tests using Jinja
  templating.

Options:
  --version                  Show the version and exit.
  -v, --verbosity LVL        Either CRITICAL, ERROR, WARNING, INFO or DEBUG
  -d, --data PATH            Path to data YAML files. (env: IAC_TEST_DATA)
                             [required]
  -t, --templates DIRECTORY  Path to test templates. (env: IAC_TEST_TEMPLATES)
                             [required]
  -f, --filters DIRECTORY    Path to Jinja filters. (env: IAC_TEST_FILTERS)
  --tests DIRECTORY          Path to Jinja tests. (env: IAC_TEST_TESTS)
  -o, --output DIRECTORY     Path to output directory. (env: IAC_TEST_OUTPUT)
                             [required]
  -i, --include TEXT         Selects the test cases by tag (include). (env:
                             IAC_TEST_INCLUDE)
  -e, --exclude TEXT         Selects the test cases by tag (exclude). (env:
                             IAC_TEST_EXCLUDE)
  --render-only              Only render tests without executing them. (env:
                             IAC_TEST_RENDER_ONLY)
  --dry-run                  Dry run flag. See robot dry run mode. (env:
                             IAC_DRY_RUN)
  -h, --help                 Show this message and exit.
```

All data from the YAML files (`--data` option) will first be combined into a single data structure which is then provided as input to the templating process. Each template in the `--templates` path will then be rendered and written to the `--output` path. If the `--templates` path has subfolders, the folder structure will be retained when rendering the templates.

After all templates have been rendered [Pabot](https://pabot.org/) will execute all test suites in parallel and create a test report in the `--output` path. The `--skiponfailure non-critical` argument will be used by default, meaning all failed tests with a `non-critical` tag will show up as "skipped" instead of "failed" in the final test report.

## Installation

Python 3.7+ is required to install `iac-test`. Don't have Python 3.7 or later? See [Python 3 Installation & Setup Guide](https://realpython.com/installing-python/).

`iac-test` can be installed in a virtual environment using `pip`:

```shell
pip install iac-test
```

The following Robot libraries are installed with `iac-test`:

- [RESTinstance](https://github.com/asyrjasalo/RESTinstance)
- [Requests](https://github.com/MarketSquare/robotframework-requests)
- [JSONLibrary](https://github.com/robotframework-thailand/robotframework-jsonlibrary)

Any other libraries can of course be added via `pip`.

## Ansible Vault Support

Values in YAML files can be encrypted using [Ansible Vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html). This requires Ansible (`ansible-vault` command) to be installed and the following two environment variables to be defined:

```
export ANSIBLE_VAULT_ID=dev
export ANSIBLE_VAULT_PASSWORD=Password123
```

`ANSIBLE_VAULT_ID` is optional, and if not defined will be omitted.

## Additional Tags

### Reading Environment Variables

The `!env` YAML tag can be used to read values from environment variables.

```yaml
root:
  name: !env VAR_NAME
```

## Example

`data.yaml` located in `./data` folder:

```yaml
---
root:
  children:
    - name: ABC
      param: value
    - name: DEF
      param: value
```

`test1.robot` located in `./templates` folder:

```
*** Settings ***
Documentation   Test1

*** Test Cases ***
{% for child in root.children | default([]) %}

Test {{ child.name }}
    Should Be Equal   {{ child.param }}   value
{% endfor %}
```

After running `iac-test` with the following parameters:

```shell
iac-test --data ./data --templates ./templates --output ./tests
```

The following rendered Robot test suite can be found in the `./tests` folder:

```
*** Settings ***
Documentation   Test1

*** Test Cases ***

Test ABC
    Should Be Equal   value   value

Test DEF
    Should Be Equal   value   value
```

As well as the test results and reports:

```shell
$ tree -L 1 tests
tests
├── log.html
├── output.xml
├── pabot_results
├── report.html
├── test1.robot
└── xunit.xml
```

## Custom Jinja Filters

Custom Jinja filters can be used by providing a set of Python classes where each filter is implemented as a separate `Filter` class in a `.py` file located in the `--filters` path. The class must have a single attribute named `name`, the filter name, and a `classmethod()` named `filter` which has one or more arguments. A sample filter can be found below.

```python
class Filter:
    name = "filter1"

    @classmethod
    def filter(cls, data):
        return str(data) + "_filtered"
```

## Custom Jinja Tests

Custom Jinja tests can be used by providing a set of Python classes where each test is implemented as a separate `Test` class in a `.py` file located in the `--tests` path. The class must have a single attribute named `name`, the test name, and a `classmethod()` named `test` which has one or more arguments. A sample test can be found below.

```python
class Test:
    name = "test1"

    @classmethod
    def test(cls, data1, data2):
        return data1 == data2
```

## Rendering Directives

Special rendering directives exist to render a single test suite per (YAML) list item. The directive can be added to the Robot template as a Jinja comment following this syntax:

```
{# iterate_list <YAML_PATH_TO_LIST> <LIST_ITEM_ID> <JINJA_VARIABLE_NAME> #}
```

After running `iac-test` with the data from the previous [example](#example) and the following template:

```
{# iterate_list root.children name child_name #}
*** Settings ***
Documentation   Test1

*** Test Cases ***
{% for child in root.children | default([]) %}
{% if child.name == child_name %}

Test {{ child.name }}
    Should Be Equal   {{ child.param }}   value
{% endif %}
{% endfor %}
```

The following test suites will be rendered:

```shell
$ tree -L 2 tests
tests
├── ABC
│   └── test1.robot
└── DEF
    └── test1.robot
```

A similar directive exists to put the test suites in a common folder though with a unique filename.

```
{# iterate_list_folder <YAML_PATH_TO_LIST> <LIST_ITEM_ID> <JINJA_VARIABLE_NAME> #}
```

The following test suites will be rendered:

```shell
$ tree -L 2 tests
tests
└── test1
    ├── ABC.robot
    └── DEF.robot
```

## Select Test Cases By Tag

It is possible to include and exclude test cases by tag names with the `--include` and `--exclude` CLI options. These options are directly passed to the Pabot/Robot executor and are documented [here](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#by-tag-names).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/netascode/iac-test",
    "name": "iac-test",
    "maintainer": "Daniel Schmidt",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "danischm@cisco.com",
    "keywords": "",
    "author": "Daniel Schmidt",
    "author_email": "danischm@cisco.com",
    "download_url": "https://files.pythonhosted.org/packages/41/c3/732c0f616f9685e7831713c76cc69afd7b46f9b05b8ec0941eccc469c16e/iac_test-0.2.5.tar.gz",
    "platform": null,
    "description": "[![Tests](https://github.com/netascode/iac-test/actions/workflows/test.yml/badge.svg)](https://github.com/netascode/iac-test/actions/workflows/test.yml)\n![Python Support](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-informational \"Python Support: 3.8, 3.9, 3.10, 3.11, 3.12\")\n\n# iac-test\n\nA CLI tool to render and execute [Robot Framework](https://robotframework.org/) tests using [Jinja](https://jinja.palletsprojects.com/) templating. Combining Robot's language agnostic syntax with the flexibility of Jinja templating allows dynamically rendering a set of test suites from the desired infrastructure state expressed in YAML syntax.\n\n```shell\n$ iac-test -h\nUsage: iac-test [OPTIONS]\n\n  A CLI tool to render and execute Robot Framework tests using Jinja\n  templating.\n\nOptions:\n  --version                  Show the version and exit.\n  -v, --verbosity LVL        Either CRITICAL, ERROR, WARNING, INFO or DEBUG\n  -d, --data PATH            Path to data YAML files. (env: IAC_TEST_DATA)\n                             [required]\n  -t, --templates DIRECTORY  Path to test templates. (env: IAC_TEST_TEMPLATES)\n                             [required]\n  -f, --filters DIRECTORY    Path to Jinja filters. (env: IAC_TEST_FILTERS)\n  --tests DIRECTORY          Path to Jinja tests. (env: IAC_TEST_TESTS)\n  -o, --output DIRECTORY     Path to output directory. (env: IAC_TEST_OUTPUT)\n                             [required]\n  -i, --include TEXT         Selects the test cases by tag (include). (env:\n                             IAC_TEST_INCLUDE)\n  -e, --exclude TEXT         Selects the test cases by tag (exclude). (env:\n                             IAC_TEST_EXCLUDE)\n  --render-only              Only render tests without executing them. (env:\n                             IAC_TEST_RENDER_ONLY)\n  --dry-run                  Dry run flag. See robot dry run mode. (env:\n                             IAC_DRY_RUN)\n  -h, --help                 Show this message and exit.\n```\n\nAll data from the YAML files (`--data` option) will first be combined into a single data structure which is then provided as input to the templating process. Each template in the `--templates` path will then be rendered and written to the `--output` path. If the `--templates` path has subfolders, the folder structure will be retained when rendering the templates.\n\nAfter all templates have been rendered [Pabot](https://pabot.org/) will execute all test suites in parallel and create a test report in the `--output` path. The `--skiponfailure non-critical` argument will be used by default, meaning all failed tests with a `non-critical` tag will show up as \"skipped\" instead of \"failed\" in the final test report.\n\n## Installation\n\nPython 3.7+ is required to install `iac-test`. Don't have Python 3.7 or later? See [Python 3 Installation & Setup Guide](https://realpython.com/installing-python/).\n\n`iac-test` can be installed in a virtual environment using `pip`:\n\n```shell\npip install iac-test\n```\n\nThe following Robot libraries are installed with `iac-test`:\n\n- [RESTinstance](https://github.com/asyrjasalo/RESTinstance)\n- [Requests](https://github.com/MarketSquare/robotframework-requests)\n- [JSONLibrary](https://github.com/robotframework-thailand/robotframework-jsonlibrary)\n\nAny other libraries can of course be added via `pip`.\n\n## Ansible Vault Support\n\nValues in YAML files can be encrypted using [Ansible Vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html). This requires Ansible (`ansible-vault` command) to be installed and the following two environment variables to be defined:\n\n```\nexport ANSIBLE_VAULT_ID=dev\nexport ANSIBLE_VAULT_PASSWORD=Password123\n```\n\n`ANSIBLE_VAULT_ID` is optional, and if not defined will be omitted.\n\n## Additional Tags\n\n### Reading Environment Variables\n\nThe `!env` YAML tag can be used to read values from environment variables.\n\n```yaml\nroot:\n  name: !env VAR_NAME\n```\n\n## Example\n\n`data.yaml` located in `./data` folder:\n\n```yaml\n---\nroot:\n  children:\n    - name: ABC\n      param: value\n    - name: DEF\n      param: value\n```\n\n`test1.robot` located in `./templates` folder:\n\n```\n*** Settings ***\nDocumentation   Test1\n\n*** Test Cases ***\n{% for child in root.children | default([]) %}\n\nTest {{ child.name }}\n    Should Be Equal   {{ child.param }}   value\n{% endfor %}\n```\n\nAfter running `iac-test` with the following parameters:\n\n```shell\niac-test --data ./data --templates ./templates --output ./tests\n```\n\nThe following rendered Robot test suite can be found in the `./tests` folder:\n\n```\n*** Settings ***\nDocumentation   Test1\n\n*** Test Cases ***\n\nTest ABC\n    Should Be Equal   value   value\n\nTest DEF\n    Should Be Equal   value   value\n```\n\nAs well as the test results and reports:\n\n```shell\n$ tree -L 1 tests\ntests\n\u251c\u2500\u2500 log.html\n\u251c\u2500\u2500 output.xml\n\u251c\u2500\u2500 pabot_results\n\u251c\u2500\u2500 report.html\n\u251c\u2500\u2500 test1.robot\n\u2514\u2500\u2500 xunit.xml\n```\n\n## Custom Jinja Filters\n\nCustom Jinja filters can be used by providing a set of Python classes where each filter is implemented as a separate `Filter` class in a `.py` file located in the `--filters` path. The class must have a single attribute named `name`, the filter name, and a `classmethod()` named `filter` which has one or more arguments. A sample filter can be found below.\n\n```python\nclass Filter:\n    name = \"filter1\"\n\n    @classmethod\n    def filter(cls, data):\n        return str(data) + \"_filtered\"\n```\n\n## Custom Jinja Tests\n\nCustom Jinja tests can be used by providing a set of Python classes where each test is implemented as a separate `Test` class in a `.py` file located in the `--tests` path. The class must have a single attribute named `name`, the test name, and a `classmethod()` named `test` which has one or more arguments. A sample test can be found below.\n\n```python\nclass Test:\n    name = \"test1\"\n\n    @classmethod\n    def test(cls, data1, data2):\n        return data1 == data2\n```\n\n## Rendering Directives\n\nSpecial rendering directives exist to render a single test suite per (YAML) list item. The directive can be added to the Robot template as a Jinja comment following this syntax:\n\n```\n{# iterate_list <YAML_PATH_TO_LIST> <LIST_ITEM_ID> <JINJA_VARIABLE_NAME> #}\n```\n\nAfter running `iac-test` with the data from the previous [example](#example) and the following template:\n\n```\n{# iterate_list root.children name child_name #}\n*** Settings ***\nDocumentation   Test1\n\n*** Test Cases ***\n{% for child in root.children | default([]) %}\n{% if child.name == child_name %}\n\nTest {{ child.name }}\n    Should Be Equal   {{ child.param }}   value\n{% endif %}\n{% endfor %}\n```\n\nThe following test suites will be rendered:\n\n```shell\n$ tree -L 2 tests\ntests\n\u251c\u2500\u2500 ABC\n\u2502   \u2514\u2500\u2500 test1.robot\n\u2514\u2500\u2500 DEF\n    \u2514\u2500\u2500 test1.robot\n```\n\nA similar directive exists to put the test suites in a common folder though with a unique filename.\n\n```\n{# iterate_list_folder <YAML_PATH_TO_LIST> <LIST_ITEM_ID> <JINJA_VARIABLE_NAME> #}\n```\n\nThe following test suites will be rendered:\n\n```shell\n$ tree -L 2 tests\ntests\n\u2514\u2500\u2500 test1\n    \u251c\u2500\u2500 ABC.robot\n    \u2514\u2500\u2500 DEF.robot\n```\n\n## Select Test Cases By Tag\n\nIt is possible to include and exclude test cases by tag names with the `--include` and `--exclude` CLI options. These options are directly passed to the Pabot/Robot executor and are documented [here](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#by-tag-names).\n",
    "bugtrack_url": null,
    "license": "LICENSE",
    "summary": "A CLI tool to render and execute Robot Framework tests using Jinja templating.",
    "version": "0.2.5",
    "project_urls": {
        "Documentation": "https://github.com/netascode/iac-test",
        "Homepage": "https://github.com/netascode/iac-test",
        "Repository": "https://github.com/netascode/iac-test"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f92488af4e3036f1df283d9c8f50a7aa6089a470cfedac3eb364e72d9242cf41",
                "md5": "664f7a83aa3361225cec9ece58d8e355",
                "sha256": "ee495a25ade16608c4cd75cf41f51301dae481b165b2aa2be415ec8e94aadba2"
            },
            "downloads": -1,
            "filename": "iac_test-0.2.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "664f7a83aa3361225cec9ece58d8e355",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 16978,
            "upload_time": "2023-11-17T13:36:27",
            "upload_time_iso_8601": "2023-11-17T13:36:27.813063Z",
            "url": "https://files.pythonhosted.org/packages/f9/24/88af4e3036f1df283d9c8f50a7aa6089a470cfedac3eb364e72d9242cf41/iac_test-0.2.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "41c3732c0f616f9685e7831713c76cc69afd7b46f9b05b8ec0941eccc469c16e",
                "md5": "469a13c61c30db0feb1257459da79ccc",
                "sha256": "36e9daf879cd35b9cf9a99bc2f9eb5093011a6432e40d1d66d1b1b6884c5e4af"
            },
            "downloads": -1,
            "filename": "iac_test-0.2.5.tar.gz",
            "has_sig": false,
            "md5_digest": "469a13c61c30db0feb1257459da79ccc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 16548,
            "upload_time": "2023-11-17T13:36:29",
            "upload_time_iso_8601": "2023-11-17T13:36:29.409370Z",
            "url": "https://files.pythonhosted.org/packages/41/c3/732c0f616f9685e7831713c76cc69afd7b46f9b05b8ec0941eccc469c16e/iac_test-0.2.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-17 13:36:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "netascode",
    "github_project": "iac-test",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "iac-test"
}
        
Elapsed time: 0.14999s