connect-devops-testing-library


Nameconnect-devops-testing-library JSON
Version 25.2 PyPI version JSON
download
home_pagehttps://github.com/cloudblue/connect-devops-testing-library
SummaryTesting framework to ease Connect EaaS Processors development.
upload_time2023-04-03 07:58:09
maintainer
docs_urlNone
authorCloudBlue LLC
requires_python>=3.7,<4
licenseApache-2.0
keywords connect eaas testing framework
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Connect DevOps Testing Library

![pyversions](https://img.shields.io/pypi/pyversions/connect-devops-testing-library.svg) [![PyPi Status](https://img.shields.io/pypi/v/connect-devops-testing-library.svg)](https://pypi.org/project/connect-devops-testing-library/) [![Build Status](https://github.com/cloudblue/connect-devops-testing-library/actions/workflows/test.yml/badge.svg)](https://github.com/cloudblue/connect-devops-testing-library/actions/workflows/test.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=connect-devops-testing-library&metric=alert_status)](https://sonarcloud.io/dashboard?id=connect-devops-testing-library)

Testing library to ease Connect EaaS Processors development.

## Install

`Connect DevOps Testing Library` can be installed
from [pypi.org](https://pypi.org/project/connect-devops-testing-library/) using pip:

```bash
$ pip install connect-devops-testing-library
```

## Usage

DevOps Testing Library has a small request builder to ease the manipulation of the connect requests during testing:

````python
from connect.devops_testing import fixtures
import os

template = os.path.dirname(__file__) + '/request.json'

request = (fixtures.make_request_builder(template)
           .with_type('purchase')
           .with_asset_product('PRD-000-000-000', 'Product Name')
           .with_asset_configuration_param('SOME_ASSET_CFG__PARAM_ID_A', 'some_cfg_value_a')
           .with_asset_param('SOME_ASSET_PARAM_ID_001', 'some_value_001')
           .with_asset_param('SOME_ASSET_PARAM_ID_002', 'some_value_002')
           .build())
````

DevOps Testing Library also has several built-in assert functions that can be easily used to evaluate a connect request
response:

```python
from connect.devops_testing import asserts

asserts.request_status(request, 'approved')
asserts.asset_status(request, 'active')
asserts.asset_param_value_not_equal(request, 'SOME_ASSET_PARAM_ID_001', 'some_expected_value')
```

Using these two features you can easily create a small test to check a purchase request of your processor:

```python
from connect.devops_testing import fixtures, asserts
from my_ext.extension import MyExtension
import os


def test_should_approve_request(mocked_connect_client, mocked_service_client, logger, eaas_config):
    template = os.path.dirname(__file__) + '/request.json'

    # prepare the request.
    request = (fixtures.make_request_builder(template)
               .with_type('purchase')
               .with_status('pending')
               .with_asset_param('subscription_id', '')
               .build())

    # instantiate and execute the extension for the given request.
    extension = MyExtension(mocked_connect_client, logger, eaas_config)
    result = extension.process_asset_adjustment_request(request)

    # evaluate the task result and request.
    asserts.task_response_status(result, 'success')
    asserts.request_status(request, 'approved')
    asserts.asset_status(request, 'active')
    asserts.asset_param_value(request, 'subscription_id', '==', 'ID:123456789')
```

Additionally, you may want to create real end-to-end test calling Connect and evaluating the processed request, for this
you should use the built-in request dispatcher. The dispatcher will take automatically the required credentials from the
environment variables in `CONNECT_API_KEY` and `CONNECT_API_URL`. Alternatively, you can pass explicitly the credentials
to the `make_request_dispatcher(api_key=XXX, api_url=YYY)` function. Let's see example:

```python
from connect.devops_testing import asserts, fixtures
import os


def test_should_approve_purchase_request_successfully():
    template = os.path.dirname(__file__) + '/request.json'

    # prepare the request.
    request = (fixtures.make_request_builder(template)
               .with_type('purchase')
               .with_status('pending')
               .with_asset_param('subscription_id', '')
               .build())

    # dispatch the request to connect and wait some time so the 
    # processor can process the request.
    request = (fixtures.make_request_dispatcher()
               .provision_request(request, 10, 20))

    # evaluate the processed request.
    asserts.request_status(request, 'approved')
    asserts.asset_status(request, 'active')
    asserts.asset_param_value(request, 'subscription_id', '==', 'ID:123456789')
```

Once the request is dispatched the Dispatcher will reload the request again every `10` seconds a maximum of `20`
attempts. If the request has not been processed the asserts may fail. The wait time between request reload can be
configured directly in the `.provision_request(timeout=10, max_attempt=20)` method call.

Obviously, some Connect processors may take a lot of time to process a request, for those type of processors this kind
of end-to-end test is not suitable.

### Behavior Driven Development

Finally, the DevOps Testing Library also allows you to easily use Behave! BDD tool for you test. You just need to set
the following code in your `features/environment.py` file

```python
from behave import use_fixture

# import the built-in steps for e2e testing. 
from connect.devops_testing.bdd import steps
from connect.devops_testing.bdd.fixtures import (
    use_connect_request_dispatcher,
    use_connect_request_builder,
    use_connect_request_store,
)


def before_all(context):
    # attach the request dispatcher to the behave context.
    use_fixture(
        fixture_func=use_connect_request_dispatcher,
        context=context,
    )
    # attach the request builder to the behave context.
    use_fixture(
        fixture_func=use_connect_request_builder,
        context=context,
    )


def before_feature(context, feature):
    # reset the request store for each feature
    use_fixture(
        fixture_func=use_connect_request_store,
        context=context,
        reset=True
    )

```

It's time to define the feature file in `features/purchase.feature`:

```gherkin
Feature: Purchase a new subscription.

  Scenario: Customer buys a subscription.
    Given a new valid email address
    When subscription request is processed
    Then the subscription id is provided
```

Now let's define the steps in `features/steps/purchase.py` file

```python
from behave import given, then
from connect.devops_testing import asserts
import os


@given("a new valid email address")
def step_impl(context):
    template = os.path.dirname(__file__) + '/request.json'

    context.request = (context.builder
                       .from_file(template)
                       .with_asset_param('CUSTOMER_EMAIL_ADDRESS', 'vincent.vega@gmail.com'))


@then("the subscription id is provided")
def step_impl(context):
    asserts.request_status(context.request, 'approved')
    asserts.asset_status(context.request, 'active')
    asserts.asset_param_value_not_equal(context.request, 'CUSTOMER_EMAIL_ADDRESS', '')
```

The `@step("subscription request is processed")` is provided by the DevOps Testing Library.

Available BDD steps:

| Step | Description |
| ------------- | ------------- |
| `request is processed`  | Process the request into Connect Platform. |
| `subscription request is processed`  | Alias of `request is processed`. |
| `tier configuration request is processed`  | Alias of `request is processed`. |
| `tier config request`  | Loads a tier configuration request template. |
| `asset request`  | Loads an asset request template. |
| `request with id "{request_id}"`  | Sets the request id. |
| `request with status "{request_status}"`  | Set the request status. |
| `request with configuration account "{account_id}"`  | Set the request tier configuration account id. |
| `request with product "{product_id}"`  | Set the request product id. |
| `request with marketplace "{marketplace_id}"`  | Set the request marketplace id. |
| `request with reseller level "{level}"`  | Set the request tier configuration reseller level. |
| `request with parameter "{parameter}" with value "{value}"`  | Set a request parameter value by parameter id. |
| `request with parameter "{parameter}" value "{values}" checked`  | Check a request checkbox parameter values by id. |
| `request with parameter "{parameter}" value "{values}" not checked`  | Uncheck a request checkbox parameter values by id. |
| `request with parameter "{parameter}" without value`  | Unset the request parameter value by id. |
| `request with parameter "{parameter}" with value error "{value}"`  | Set the request parameter value error by id. |
| `request with parameter "{parameter}" without value error`  | Unset the request parameter value error. |
| `request parameter "{parameter}" value is "{value}"`  | Assert that the value of the given parameter by id is the expected one. |
| `request parameter "{parameter}" value contains "{value}"`  | Assert that the value of the given parameter by id contains the expected value. |
| `request parameter "{parameter}" value match "{pattern}"`  | Assert that the value of the given parameter by id match the expected regex expression. |
| `request parameter "{parameter}" value error is "{value_error}"`  | Assert that the value error of the given parameter by id the expected one.  |
| `request parameter "{parameter}" value error contains "{value_error}"`  | Assert that the value error of the given parameter by id contains the expected value. |
| `request parameter "{parameter}" value error match "{pattern}"`  | Assert that the value error of the given parameter by id match the expected regex expression. |
| `request status is "{request_status}"`  | Assert that the status of the request is the expected one. |

## License

`Connect DevOps Testing Library` is released under
the [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/cloudblue/connect-devops-testing-library",
    "name": "connect-devops-testing-library",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7,<4",
    "maintainer_email": "",
    "keywords": "connect,eaas,testing,framework",
    "author": "CloudBlue LLC",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/f2/d9/9e4a8e7efb503564d063f18187b36594d8430aa9e60f897bf4296483b553/connect_devops_testing_library-25.2.tar.gz",
    "platform": null,
    "description": "# Connect DevOps Testing Library\n\n![pyversions](https://img.shields.io/pypi/pyversions/connect-devops-testing-library.svg) [![PyPi Status](https://img.shields.io/pypi/v/connect-devops-testing-library.svg)](https://pypi.org/project/connect-devops-testing-library/) [![Build Status](https://github.com/cloudblue/connect-devops-testing-library/actions/workflows/test.yml/badge.svg)](https://github.com/cloudblue/connect-devops-testing-library/actions/workflows/test.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=connect-devops-testing-library&metric=alert_status)](https://sonarcloud.io/dashboard?id=connect-devops-testing-library)\n\nTesting library to ease Connect EaaS Processors development.\n\n## Install\n\n`Connect DevOps Testing Library` can be installed\nfrom [pypi.org](https://pypi.org/project/connect-devops-testing-library/) using pip:\n\n```bash\n$ pip install connect-devops-testing-library\n```\n\n## Usage\n\nDevOps Testing Library has a small request builder to ease the manipulation of the connect requests during testing:\n\n````python\nfrom connect.devops_testing import fixtures\nimport os\n\ntemplate = os.path.dirname(__file__) + '/request.json'\n\nrequest = (fixtures.make_request_builder(template)\n           .with_type('purchase')\n           .with_asset_product('PRD-000-000-000', 'Product Name')\n           .with_asset_configuration_param('SOME_ASSET_CFG__PARAM_ID_A', 'some_cfg_value_a')\n           .with_asset_param('SOME_ASSET_PARAM_ID_001', 'some_value_001')\n           .with_asset_param('SOME_ASSET_PARAM_ID_002', 'some_value_002')\n           .build())\n````\n\nDevOps Testing Library also has several built-in assert functions that can be easily used to evaluate a connect request\nresponse:\n\n```python\nfrom connect.devops_testing import asserts\n\nasserts.request_status(request, 'approved')\nasserts.asset_status(request, 'active')\nasserts.asset_param_value_not_equal(request, 'SOME_ASSET_PARAM_ID_001', 'some_expected_value')\n```\n\nUsing these two features you can easily create a small test to check a purchase request of your processor:\n\n```python\nfrom connect.devops_testing import fixtures, asserts\nfrom my_ext.extension import MyExtension\nimport os\n\n\ndef test_should_approve_request(mocked_connect_client, mocked_service_client, logger, eaas_config):\n    template = os.path.dirname(__file__) + '/request.json'\n\n    # prepare the request.\n    request = (fixtures.make_request_builder(template)\n               .with_type('purchase')\n               .with_status('pending')\n               .with_asset_param('subscription_id', '')\n               .build())\n\n    # instantiate and execute the extension for the given request.\n    extension = MyExtension(mocked_connect_client, logger, eaas_config)\n    result = extension.process_asset_adjustment_request(request)\n\n    # evaluate the task result and request.\n    asserts.task_response_status(result, 'success')\n    asserts.request_status(request, 'approved')\n    asserts.asset_status(request, 'active')\n    asserts.asset_param_value(request, 'subscription_id', '==', 'ID:123456789')\n```\n\nAdditionally, you may want to create real end-to-end test calling Connect and evaluating the processed request, for this\nyou should use the built-in request dispatcher. The dispatcher will take automatically the required credentials from the\nenvironment variables in `CONNECT_API_KEY` and `CONNECT_API_URL`. Alternatively, you can pass explicitly the credentials\nto the `make_request_dispatcher(api_key=XXX, api_url=YYY)` function. Let's see example:\n\n```python\nfrom connect.devops_testing import asserts, fixtures\nimport os\n\n\ndef test_should_approve_purchase_request_successfully():\n    template = os.path.dirname(__file__) + '/request.json'\n\n    # prepare the request.\n    request = (fixtures.make_request_builder(template)\n               .with_type('purchase')\n               .with_status('pending')\n               .with_asset_param('subscription_id', '')\n               .build())\n\n    # dispatch the request to connect and wait some time so the \n    # processor can process the request.\n    request = (fixtures.make_request_dispatcher()\n               .provision_request(request, 10, 20))\n\n    # evaluate the processed request.\n    asserts.request_status(request, 'approved')\n    asserts.asset_status(request, 'active')\n    asserts.asset_param_value(request, 'subscription_id', '==', 'ID:123456789')\n```\n\nOnce the request is dispatched the Dispatcher will reload the request again every `10` seconds a maximum of `20`\nattempts. If the request has not been processed the asserts may fail. The wait time between request reload can be\nconfigured directly in the `.provision_request(timeout=10, max_attempt=20)` method call.\n\nObviously, some Connect processors may take a lot of time to process a request, for those type of processors this kind\nof end-to-end test is not suitable.\n\n### Behavior Driven Development\n\nFinally, the DevOps Testing Library also allows you to easily use Behave! BDD tool for you test. You just need to set\nthe following code in your `features/environment.py` file\n\n```python\nfrom behave import use_fixture\n\n# import the built-in steps for e2e testing. \nfrom connect.devops_testing.bdd import steps\nfrom connect.devops_testing.bdd.fixtures import (\n    use_connect_request_dispatcher,\n    use_connect_request_builder,\n    use_connect_request_store,\n)\n\n\ndef before_all(context):\n    # attach the request dispatcher to the behave context.\n    use_fixture(\n        fixture_func=use_connect_request_dispatcher,\n        context=context,\n    )\n    # attach the request builder to the behave context.\n    use_fixture(\n        fixture_func=use_connect_request_builder,\n        context=context,\n    )\n\n\ndef before_feature(context, feature):\n    # reset the request store for each feature\n    use_fixture(\n        fixture_func=use_connect_request_store,\n        context=context,\n        reset=True\n    )\n\n```\n\nIt's time to define the feature file in `features/purchase.feature`:\n\n```gherkin\nFeature: Purchase a new subscription.\n\n  Scenario: Customer buys a subscription.\n    Given a new valid email address\n    When subscription request is processed\n    Then the subscription id is provided\n```\n\nNow let's define the steps in `features/steps/purchase.py` file\n\n```python\nfrom behave import given, then\nfrom connect.devops_testing import asserts\nimport os\n\n\n@given(\"a new valid email address\")\ndef step_impl(context):\n    template = os.path.dirname(__file__) + '/request.json'\n\n    context.request = (context.builder\n                       .from_file(template)\n                       .with_asset_param('CUSTOMER_EMAIL_ADDRESS', 'vincent.vega@gmail.com'))\n\n\n@then(\"the subscription id is provided\")\ndef step_impl(context):\n    asserts.request_status(context.request, 'approved')\n    asserts.asset_status(context.request, 'active')\n    asserts.asset_param_value_not_equal(context.request, 'CUSTOMER_EMAIL_ADDRESS', '')\n```\n\nThe `@step(\"subscription request is processed\")` is provided by the DevOps Testing Library.\n\nAvailable BDD steps:\n\n| Step | Description |\n| ------------- | ------------- |\n| `request is processed`  | Process the request into Connect Platform. |\n| `subscription request is processed`  | Alias of `request is processed`. |\n| `tier configuration request is processed`  | Alias of `request is processed`. |\n| `tier config request`  | Loads a tier configuration request template. |\n| `asset request`  | Loads an asset request template. |\n| `request with id \"{request_id}\"`  | Sets the request id. |\n| `request with status \"{request_status}\"`  | Set the request status. |\n| `request with configuration account \"{account_id}\"`  | Set the request tier configuration account id. |\n| `request with product \"{product_id}\"`  | Set the request product id. |\n| `request with marketplace \"{marketplace_id}\"`  | Set the request marketplace id. |\n| `request with reseller level \"{level}\"`  | Set the request tier configuration reseller level. |\n| `request with parameter \"{parameter}\" with value \"{value}\"`  | Set a request parameter value by parameter id. |\n| `request with parameter \"{parameter}\" value \"{values}\" checked`  | Check a request checkbox parameter values by id. |\n| `request with parameter \"{parameter}\" value \"{values}\" not checked`  | Uncheck a request checkbox parameter values by id. |\n| `request with parameter \"{parameter}\" without value`  | Unset the request parameter value by id. |\n| `request with parameter \"{parameter}\" with value error \"{value}\"`  | Set the request parameter value error by id. |\n| `request with parameter \"{parameter}\" without value error`  | Unset the request parameter value error. |\n| `request parameter \"{parameter}\" value is \"{value}\"`  | Assert that the value of the given parameter by id is the expected one. |\n| `request parameter \"{parameter}\" value contains \"{value}\"`  | Assert that the value of the given parameter by id contains the expected value. |\n| `request parameter \"{parameter}\" value match \"{pattern}\"`  | Assert that the value of the given parameter by id match the expected regex expression. |\n| `request parameter \"{parameter}\" value error is \"{value_error}\"`  | Assert that the value error of the given parameter by id the expected one.  |\n| `request parameter \"{parameter}\" value error contains \"{value_error}\"`  | Assert that the value error of the given parameter by id contains the expected value. |\n| `request parameter \"{parameter}\" value error match \"{pattern}\"`  | Assert that the value error of the given parameter by id match the expected regex expression. |\n| `request status is \"{request_status}\"`  | Assert that the status of the request is the expected one. |\n\n## License\n\n`Connect DevOps Testing Library` is released under\nthe [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Testing framework to ease Connect EaaS Processors development.",
    "version": "25.2",
    "split_keywords": [
        "connect",
        "eaas",
        "testing",
        "framework"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3f6421f60ac146055da32d59748fd5ca4c915e8b45f6ea7df6858c810cea0a76",
                "md5": "55a8d574ab1f39659f778641e7ce9b5d",
                "sha256": "b63a1d7f958b0ca4d8fbfe540afd06aa160229a87b9acf3c9b6a3fe2968d432f"
            },
            "downloads": -1,
            "filename": "connect_devops_testing_library-25.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "55a8d574ab1f39659f778641e7ce9b5d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7,<4",
            "size": 19223,
            "upload_time": "2023-04-03T07:58:08",
            "upload_time_iso_8601": "2023-04-03T07:58:08.632140Z",
            "url": "https://files.pythonhosted.org/packages/3f/64/21f60ac146055da32d59748fd5ca4c915e8b45f6ea7df6858c810cea0a76/connect_devops_testing_library-25.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f2d99e4a8e7efb503564d063f18187b36594d8430aa9e60f897bf4296483b553",
                "md5": "45e9e2972c5ef84c5420e613b7332741",
                "sha256": "53118db5dee658c00bf3071e081ecd9dc3df217cf7fd29488e4dcf991ffa8a6b"
            },
            "downloads": -1,
            "filename": "connect_devops_testing_library-25.2.tar.gz",
            "has_sig": false,
            "md5_digest": "45e9e2972c5ef84c5420e613b7332741",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7,<4",
            "size": 19307,
            "upload_time": "2023-04-03T07:58:09",
            "upload_time_iso_8601": "2023-04-03T07:58:09.818825Z",
            "url": "https://files.pythonhosted.org/packages/f2/d9/9e4a8e7efb503564d063f18187b36594d8430aa9e60f897bf4296483b553/connect_devops_testing_library-25.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-03 07:58:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "cloudblue",
    "github_project": "connect-devops-testing-library",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "connect-devops-testing-library"
}
        
Elapsed time: 0.84778s