Skip to content

Commit

Permalink
Merge pull request #44 from eficode/pydantic
Browse files Browse the repository at this point in the history
Introduce pydantic to validate Oxygen handler result values. Fixes #43
  • Loading branch information
Tattoo authored Oct 27, 2023
2 parents dbd28be + abffa99 commit ffed224
Show file tree
Hide file tree
Showing 25 changed files with 1,019 additions and 974 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Then `results_robot_output.xml` will be created under `path/to/`.

### [Read the developer guide on how to write your own handler](DEVGUIDE.md)

You might also want to look at [specification for handler results](handler_result_specification.md)

### Configuring your handler to Oxygen

Oxygen knows about different handlers based on the [`config.yml`](https://github.com/eficode/robotframework-oxygen/blob/master/config.yml) file. This configuration file can be interacted with through Oxygen's command line.
Expand Down
132 changes: 132 additions & 0 deletions handler_result_specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Oxygen handler result specification
```
{
"$defs": {
"OxygenKeywordDict": {
"properties": {
"pass": {
"title": "Pass",
"type": "boolean"
},
"name": {
"title": "Name",
"type": "string"
},
"elapsed": {
"title": "Elapsed",
"type": "number"
},
"tags": {
"items": {
"type": "string"
},
"title": "Tags",
"type": "array"
},
"messages": {
"items": {
"type": "string"
},
"title": "Messages",
"type": "array"
},
"teardown": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"keywords": {
"items": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"title": "Keywords",
"type": "array"
}
},
"required": [
"pass",
"name"
],
"title": "OxygenKeywordDict",
"type": "object"
},
"OxygenSuiteDict": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"tags": {
"items": {
"type": "string"
},
"title": "Tags",
"type": "array"
},
"setup": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"teardown": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"suites": {
"items": {
"$ref": "#/$defs/OxygenSuiteDict"
},
"title": "Suites",
"type": "array"
},
"tests": {
"items": {
"$ref": "#/$defs/OxygenTestCaseDict"
},
"title": "Tests",
"type": "array"
}
},
"required": [
"name"
],
"title": "OxygenSuiteDict",
"type": "object"
},
"OxygenTestCaseDict": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"keywords": {
"items": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"title": "Keywords",
"type": "array"
},
"tags": {
"items": {
"type": "string"
},
"title": "Tags",
"type": "array"
},
"setup": {
"$ref": "#/$defs/OxygenKeywordDict"
},
"teardown": {
"$ref": "#/$defs/OxygenKeywordDict"
}
},
"required": [
"name",
"keywords"
],
"title": "OxygenTestCaseDict",
"type": "object"
}
},
"allOf": [
{
"$ref": "#/$defs/OxygenSuiteDict"
}
]
}
```
50 changes: 0 additions & 50 deletions parser_specification.md

This file was deleted.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
robotframework>=3.0.4
junitparser==2.0
PyYAML>=3.13
pydantic>=2.4.2

### Dev
mock>=2.0.0
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
install_requires=[
'robotframework>=3.0.4',
'junitparser==2.0',
'PyYAML>=3.13'
'PyYAML>=3.13',
'pydantic>=2.4.2'
],
packages=find_packages(SRC),
package_dir={'': 'src'},
Expand Down
9 changes: 7 additions & 2 deletions src/oxygen/base_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from inspect import signature, Parameter

from oxygen.errors import MismatchArgumentException
from .errors import MismatchArgumentException
from .robot_interface import (RobotInterface, get_keywords_from,
set_special_keyword)

from .utils import validate_with_deprecation_warning

class BaseHandler(object):
DEFAULT_CLI = {tuple(['result_file']): {}}
Expand Down Expand Up @@ -132,6 +132,8 @@ def _build_results(self, keyword, setup_keyword, teardown_keyword):
f'parse_results expects at least {accepted_params_min} '
'arguments but got 1')

self._validate(test_results)

_, result_suite = self._interface.result.build_suite(
100000, test_results)

Expand All @@ -149,6 +151,9 @@ def _build_results(self, keyword, setup_keyword, teardown_keyword):

self._inject_suite_report(test, result_suite)

def _validate(self, oxygen_result_dict):
validate_with_deprecation_warning(oxygen_result_dict, self)

def _inject_suite_report(self, test, result_suite):
'''Add the given suite to the parent suite of the test case.
Expand Down
4 changes: 4 additions & 0 deletions src/oxygen/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ class MismatchArgumentException(Exception):

class InvalidConfigurationException(Exception):
pass


class InvalidOxygenResultException(Exception):
pass
9 changes: 0 additions & 9 deletions src/oxygen/gatling.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ def _transform_tests(self, result_file):
keyword = {
'name': ' | '.join(columns),
'pass': True,
'tags': [],
'messages': [],
'teardown': [],
'keywords': [],
}

if status == 'KO':
Expand All @@ -77,9 +74,6 @@ def _transform_tests(self, result_file):

test_case = {
'name': step_name,
'tags': [],
'setup': [],
'teardown': [],
'keywords': [keyword]
}

Expand All @@ -88,9 +82,6 @@ def _transform_tests(self, result_file):
test_suite = {
'name': 'Gatling Scenario',
'tags': self._tags,
'setup': [],
'teardown': [],
'suites': [],
'tests': test_cases,
}

Expand Down
9 changes: 0 additions & 9 deletions src/oxygen/junit.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ def _transform_tests(self, node):
suite_dict = {
'name': 'JUnit Execution',
'tags': self._tags,
'setup': [],
'teardown': [],
'suites': [],
'tests': [],
}

if isinstance(node, JUnitXmlTestSuite):
Expand All @@ -63,8 +60,6 @@ def _transform_test_suite(self, test_suite):
suite_dict = {
'name': test_suite.name,
'tags': [],
'setup': [],
'teardown': [],
'suites': [],
'tests': [],
}
Expand All @@ -91,9 +86,7 @@ def _transform_test_case(self, test_case):
test_dict = {
'name': '{} (Execution)'.format(test_case.name),
'pass': True,
'tags': [],
'messages': [],
'teardown': [],
'keywords': [],
}

Expand Down Expand Up @@ -126,8 +119,6 @@ def _transform_test_case(self, test_case):
test_case_dict = {
'name': test_case.name,
'tags': [],
'setup': [],
'teardown': [],
'keywords': [
test_dict,
],
Expand Down
2 changes: 2 additions & 0 deletions src/oxygen/oxygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
InvalidConfigurationException,
ResultFileNotFoundException)
from .robot_interface import RobotInterface
from .utils import validate_with_deprecation_warning
from .version import VERSION


Expand Down Expand Up @@ -301,6 +302,7 @@ def convert_to_robot_result(self, args):
output_filename = self.get_output_filename(args.get('result_file'))
parsed_results = args['func'](
**{k: v for (k, v) in args.items() if not callable(v)})
validate_with_deprecation_warning(parsed_results, args['func'])
robot_suite = RobotInterface().running.build_suite(parsed_results)
robot_suite.run(output=output_filename,
log=None,
Expand Down
Loading

0 comments on commit ffed224

Please sign in to comment.