Skip to content

Commit

Permalink
fix: add more unittests in map_param CONTEXT replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
rgonalo committed Apr 27, 2023
1 parent c259449 commit b202b9f
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 64 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -12,9 +12,9 @@ jobs:
fail-fast: false

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Python 3.9
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: '3.9'
- name: Install dependencies
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Expand Up @@ -22,11 +22,13 @@ v3.0.0
- New optional config property `options` in [Chrome] section to configure Chrome options instead of using old
property `goog:chromeOptions` in [Capabilities] section.
- New optional config property `base_path` in [Server] section to allow using old Selenium 3 or Appium 1 remote servers
- Update [RANDOM_PHONE_NUMBER] replacement using new `DataGenerator` class
- Remove support for lettuce tests
- Remove deprecated parameter `context` from `map_param` and POEditor methods
- Remove deprecated config property `restart_driver_fail` in [Driver] section
- Remove deprecated environment variables `Section_option`, `Config_environment` and `env`
- Update `[RANDOM_PHONE_NUMBER]` replacement using new `DataGenerator` class
- Update `[CONTEXT:a.b.c]` replacement to search data in context, context.storage and context.feature_storage
- Update `[CONTEXT:a.b.c]` replacement to allow dictionaries or classes in context fields

v2.7.0
------
Expand Down
58 changes: 0 additions & 58 deletions toolium/test/utils/test_dataset_map_param.py
Expand Up @@ -16,7 +16,6 @@
limitations under the License.
"""

import mock
import os
import pytest

Expand Down Expand Up @@ -194,63 +193,6 @@ def test_a_conf_param_without_project_config():
assert expected == result


def test_a_context_param():
"""
Verification of a mapped parameter as CONTEXT
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
dataset.behave_context = context

result_att = map_param("[CONTEXT:attribute]")
expected_att = "attribute value"
assert expected_att == result_att


def test_a_context_param_storage():
"""
Verification of a mapped parameter as CONTEXT saved in storage
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
dataset.behave_context = context

result_st = map_param("[CONTEXT:storage_key]")
expected_st = "storage entry value"
assert expected_st == result_st


def test_a_context_param_with_dots():
"""
Verification of a mapped parameter with dots as CONTEXT
"""
context = mock.MagicMock()

class Obj(object):
pass
one = Obj()
one.two = "the value"

context.one = one
dataset.behave_context = context

result_att = map_param("[CONTEXT:one.two]")
expected_att = "the value"
assert expected_att == result_att

three = Obj()
three.four = "the other value"

context.storage = {"three": three}
dataset.behave_context = context

result_att = map_param("[CONTEXT:three.four]")
expected_att = "the other value"
assert expected_att == result_att


def test_a_poe_param_single_result():
"""
Verification of a POE mapped parameter with a single result for a reference
Expand Down
239 changes: 239 additions & 0 deletions toolium/test/utils/test_dataset_map_param_context.py
@@ -0,0 +1,239 @@
# -*- coding: utf-8 -*-
"""
Copyright 2023 Telefónica Investigación y Desarrollo, S.A.U.
This file is part of Toolium.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import mock
import pytest

from toolium.utils import dataset
from toolium.utils.dataset import map_param


def test_a_context_param():
"""
Verification of a mapped parameter as CONTEXT
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
context.feature_storage = {"feature_storage_key": "feature storage entry value"}
dataset.behave_context = context

result_att = map_param("[CONTEXT:attribute]")
expected_att = "attribute value"
assert expected_att == result_att


def test_a_context_param_storage():
"""
Verification of a mapped parameter as CONTEXT saved in storage
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
context.feature_storage = {"feature_storage_key": "feature storage entry value"}
dataset.behave_context = context

result_st = map_param("[CONTEXT:storage_key]")
expected_st = "storage entry value"
assert expected_st == result_st


def test_a_context_param_feature_storage():
"""
Verification of a mapped parameter as CONTEXT saved in feature storage
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
context.feature_storage = {"feature_storage_key": "feature storage entry value"}
dataset.behave_context = context

result_st = map_param("[CONTEXT:feature_storage_key]")
expected_st = "feature storage entry value"
assert expected_st == result_st


def test_a_context_param_storage_and_feature_storage():
"""
Verification of a mapped parameter as CONTEXT saved in storage and feature storage
"""
context = mock.MagicMock()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
context.feature_storage = {"storage_key": "feature storage entry value"}
dataset.behave_context = context

result_st = map_param("[CONTEXT:storage_key]")
expected_st = "storage entry value"
assert expected_st == result_st


def test_a_context_param_dict():
"""
Verification of a mapped parameter in a dict as CONTEXT
"""
class Context(object):
pass
context = Context()

context.one = {"two": {"three": "the value"}}
dataset.behave_context = context

result_att = map_param("[CONTEXT:one.two.three]")
expected_att = "the value"
assert expected_att == result_att


def test_a_context_param_class():
"""
Verification of a mapped parameter in a class as CONTEXT
"""
class Context(object):
pass
context = Context()

class OneClass(object):
pass
one = OneClass()

class TwoClass(object):
pass
two = TwoClass()
two.three = "the value"
one.two = two
context.one = one
dataset.behave_context = context

result_att = map_param("[CONTEXT:one.two.three]")
expected_att = "the value"
assert expected_att == result_att


def test_a_context_param_dict_class():
"""
Verification of a mapped parameter in a dict inside a class as CONTEXT
"""
class Context(object):
pass
context = Context()

class TwoClass(object):
pass
two = TwoClass()
two.three = "the value"
context.one = {"two": two}
dataset.behave_context = context

result_att = map_param("[CONTEXT:one.two.three]")
expected_att = "the value"
assert expected_att == result_att


def test_a_context_param_storage_class():
"""
Verification of a mapped parameter in a class as CONTEXT saved in storage
"""
class Context(object):
pass
context = Context()

class OneClass(object):
pass
one = OneClass()

class TwoClass(object):
pass
two = TwoClass()
two.three = "the value"
one.two = two
context.storage = {"one": one}
context.feature_storage = {}
dataset.behave_context = context

result_att = map_param("[CONTEXT:one.two.three]")
expected_att = "the value"
assert expected_att == result_att


def test_a_context_param_without_storage():
"""
Verification of a mapped parameter as CONTEXT when storage is not initialized
"""
class Context(object):
pass
context = Context()
context.attribute = "attribute value"
dataset.behave_context = context

result_att = map_param("[CONTEXT:attribute]")
expected_att = "attribute value"
assert expected_att == result_att


def test_a_context_param_unknown():
"""
Verification of an unknown mapped parameter as CONTEXT
"""
class Context(object):
pass
context = Context()
context.attribute = "attribute value"
context.storage = {"storage_key": "storage entry value"}
context.feature_storage = {}
dataset.behave_context = context

with pytest.raises(Exception) as excinfo:
map_param("[CONTEXT:unknown]")
assert "'unknown' key not found in context" == str(excinfo.value)


def test_a_context_param_class_unknown():
"""
Verification of an unknown mapped parameter in a class as CONTEXT
"""
class Context(object):
pass
context = Context()
context.storage = {}
context.feature_storage = {}

class OneClass(object):
pass
context.one = OneClass()
context.one.two = "the value"
dataset.behave_context = context

with pytest.raises(Exception) as excinfo:
map_param("[CONTEXT:one.three]")
assert "'three' attribute not found in OneClass class in context" == str(excinfo.value)


def test_a_context_param_dict_unknown():
"""
Verification of an unknown mapped parameter in a dict as CONTEXT
"""
class Context(object):
pass
context = Context()

context.one = {"two": {"three": "the value"}}
dataset.behave_context = context

with pytest.raises(Exception) as excinfo:
map_param("[CONTEXT:one.three]")
assert f"'three' key not found in {context.one} value in context" == str(excinfo.value)
11 changes: 9 additions & 2 deletions toolium/utils/dataset.py
Expand Up @@ -593,7 +593,11 @@ def get_value_from_context(param, context):
:return: mapped value
"""
parts = param.split('.')
context_storage = collections.ChainMap(context.storage, context.feature_storage)
try:
context_storage = collections.ChainMap(context.storage, context.feature_storage)
except AttributeError:
# When before_feature is not called, context.storage and context.feature_storage are not available
context_storage = {}
if parts[0] in context_storage:
value = context_storage[parts[0]]
elif hasattr(context, parts[0]):
Expand All @@ -609,7 +613,10 @@ def get_value_from_context(param, context):
elif hasattr(value, part):
value = getattr(value, part)
else:
msg = f"key or attribute '{part}' not found in context"
if isinstance(value, dict):
msg = f"'{part}' key not found in {value} value in context"
else:
msg = f"'{part}' attribute not found in {type(value).__name__} class in context"
logger.error(msg)
raise Exception(msg)
return value
Expand Down

0 comments on commit b202b9f

Please sign in to comment.