From: Fiete Ostkamp Date: Tue, 17 Feb 2026 13:47:18 +0000 (+0100) Subject: Improve project setup X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=HEAD;p=testsuite%2Fpython-testing-utils.git Improve project setup - migrate from nose [0] to pytest - remove six and future packages since their functionality is now part of python 3 base - improve READMEs - bump version to 11.0.1 [0] last released in 2015! Issue-ID: INT-2354 Change-Id: I65ce6853d53e1b24d4976b8b183db4a463475ee4 Signed-off-by: Fiete Ostkamp --- diff --git a/.gitignore b/.gitignore index 70a57dd..ecee922 100644 --- a/.gitignore +++ b/.gitignore @@ -259,4 +259,6 @@ typings/ # End of https://www.gitignore.io/api/node,sonar,maven,eclipse,sonarqube,intellij+all -.flattened-pom.xml \ No newline at end of file +.flattened-pom.xml +.venv +venv diff --git a/README.md b/README.md new file mode 100644 index 0000000..582c16a --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +Python Testing Utils +======================= + +Robot Framework library and utilities for ONAP end-to-end testing. + +Project Structure +----------------- +- robotframework-onap/ - Main Robot Framework library package + - ONAPLibrary/ - Robot keywords for ONAP components (AAI, SDC, SO, etc.) + - vcpeutils/ - vCPE-specific utilities + - tests/ - Unit tests + +Quick Start +----------- + +1. Create and activate a virtual environment: + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +2. Install the package in development mode: + +```bash +cd robotframework-onap +pip install -e . +pip install -r test-requirements.txt +``` + +3. Run tests: + +```bash +pytest tests/ -v +``` + +4. Run linting: + +```bash +tox -e pep8 +tox -e pylint +``` + +Using tox +--------- +Run all checks (tests, pep8, pylint): + +```bash +cd robotframework-onap +tox +``` + +Run specific target: + +```bash +tox -e py3 # Run tests with coverage +tox -e pep8 # Run flake8 linting +tox -e pylint # Run pylint +``` + +Requirements +------------ +- Python 3.7+ diff --git a/robotframework-onap/ONAPLibrary/HEATKeywords.py b/robotframework-onap/ONAPLibrary/HEATKeywords.py index b553f12..848a6f4 100644 --- a/robotframework-onap/ONAPLibrary/HEATKeywords.py +++ b/robotframework-onap/ONAPLibrary/HEATKeywords.py @@ -21,7 +21,6 @@ import copy from hashlib import md5 from paramiko import RSAKey from paramiko.ssh_exception import PasswordRequiredException -from six import string_types from ONAPLibrary.Utilities import Utilities @@ -40,9 +39,9 @@ class HEATKeywords(object): def get_yaml(self, template_file): """Template Yaml To Json reads a YAML Heat template file returns a JSON string that can be used included in an Openstack Add Stack Request""" - if isinstance(template_file, string_types): - fin = open(template_file, 'r') - yamlobj = yaml.load(fin) + if isinstance(template_file, str): + with open(template_file, 'r') as fin: + yamlobj = yaml.safe_load(fin) return yamlobj return None @@ -51,14 +50,13 @@ class HEATKeywords(object): """Template Yaml To Json reads a YAML Heat template file returns a JSON string that can be used included in an Openstack Add Stack Request""" contents = None - if isinstance(template_file, string_types): - fin = open(template_file, 'r') - yamlobj = yaml.load(fin) - fin.close() + if isinstance(template_file, str): + with open(template_file, 'r') as fin: + yamlobj = yaml.safe_load(fin) if 'heat_template_version' in yamlobj: datetime = yamlobj['heat_template_version'] yamlobj['heat_template_version'] = str(datetime) - fout = io.BytesIO() + fout = io.StringIO() json.dump(yamlobj, fout) contents = fout.getvalue() fout.close() @@ -68,12 +66,11 @@ class HEATKeywords(object): def env_yaml_to_json(self, template_file): """Env Yaml To JSon reads a YAML Heat env file and returns a JSON string that can be used included in an Openstack Add Stack Request""" - if isinstance(template_file, string_types): - fin = open(template_file, 'r') - yamlobj = yaml.load(fin) - fin.close() + if isinstance(template_file, str): + with open(template_file, 'r') as fin: + yamlobj = yaml.safe_load(fin) if 'parameters' in yamlobj: - fout = io.BytesIO() + fout = io.StringIO() json.dump(yamlobj['parameters'], fout) contents = fout.getvalue() fout.close() diff --git a/robotframework-onap/ONAPLibrary/HTTPKeywords.py b/robotframework-onap/ONAPLibrary/HTTPKeywords.py index 34bee78..88dd56c 100644 --- a/robotframework-onap/ONAPLibrary/HTTPKeywords.py +++ b/robotframework-onap/ONAPLibrary/HTTPKeywords.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from six.moves import urllib +from urllib import parse as urlparse from robot.api.deco import keyword import urllib3 @@ -25,12 +25,12 @@ class HTTPKeywords(object): @keyword def url_encode_string(self, barestring): """URL Encode String takes in a string and converts it into fully 'percent-encoded' string""" - return urllib.parse.quote(barestring) + return urlparse.quote(barestring) @keyword def url_parse(self, url): """ Get pieces of the URL """ - return urllib.parse.urlparse(url) + return urlparse.urlparse(url) @keyword def disable_warnings(self): diff --git a/robotframework-onap/ONAPLibrary/JSONKeywords.py b/robotframework-onap/ONAPLibrary/JSONKeywords.py index 70fa2c0..d48299a 100644 --- a/robotframework-onap/ONAPLibrary/JSONKeywords.py +++ b/robotframework-onap/ONAPLibrary/JSONKeywords.py @@ -15,7 +15,6 @@ import json from robot.api.deco import keyword from deepdiff import DeepDiff -from six import string_types class JSONKeywords(object): @@ -27,11 +26,11 @@ class JSONKeywords(object): def _json_compare(self, left, right, cmp): """_json_compare takes two strings or JSON objects and checks their DeepDiff using cmp function.""" - if isinstance(left, string_types): + if isinstance(left, str): left_json = json.loads(left) else: left_json = left - if isinstance(right, string_types): + if isinstance(right, str): right_json = json.loads(right) else: right_json = right diff --git a/robotframework-onap/ONAPLibrary/JSONPathKeywords.py b/robotframework-onap/ONAPLibrary/JSONPathKeywords.py index d5ed23a..fc44b2f 100644 --- a/robotframework-onap/ONAPLibrary/JSONPathKeywords.py +++ b/robotframework-onap/ONAPLibrary/JSONPathKeywords.py @@ -13,7 +13,6 @@ # limitations under the License. import json -from six import string_types from robot.api.deco import keyword from jsonpath_rw import parse @@ -31,7 +30,7 @@ class JSONPathKeywords(object): which is converted into string if needed and then compares them, returning the matches.""" jsonpath_expr = parse(expression) - if isinstance(target, string_types): + if isinstance(target, str): search_json = json.dumps(target) else: search_json = target diff --git a/robotframework-onap/README.md b/robotframework-onap/README.md new file mode 100644 index 0000000..4331646 --- /dev/null +++ b/robotframework-onap/README.md @@ -0,0 +1,72 @@ +Robotframework-ONAP +======================= + +Robot Framework library for ONAP testing. + +Packages +-------- +- ONAPLibrary - Robot keywords for ONAP components (AAI, SDC, SO, SDNC, etc.) +- vcpeutils - vCPE service orchestration utilities + +Installation +------------ + +```bash +pip install -e . +``` + +Development Setup +----------------- + +1. Create virtual environment (from repo root): + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +2. Install in development mode with test dependencies: + +```bash +pip install -e . +pip install -r test-requirements.txt +``` + +3. Run tests: + +```bash +pytest tests/ -v +``` + +Or with coverage: + +```bash +pytest tests/ --cov=ONAPLibrary --cov=vcpeutils --cov-report=html +``` + +Using tox +--------- +Available targets: + +- py3: Run unit tests with coverage +- pep8: Python linting with flake8 +- pylint: Python linting with pylint + +Run all targets: + +```bash +tox +``` + +Run specific target: + +```bash +tox -e py3 +tox -e pep8 +tox -e pylint +``` + +Requirements +------------ +- Python 3.7+ +- See requirements.txt for dependencies diff --git a/robotframework-onap/requirements.txt b/robotframework-onap/requirements.txt index 9f8bb6d..a3ea3cc 100644 --- a/robotframework-onap/requirements.txt +++ b/robotframework-onap/requirements.txt @@ -4,7 +4,6 @@ pbr deepdiff dnspython -future jinja2 jsonpath-rw kafka-python @@ -12,8 +11,7 @@ paramiko protobuf pyyaml requests -robotframework-requests==0.9.3 +robotframework-requests>=0.9.6 robotlibcore-temp -six urllib3 more-itertools diff --git a/robotframework-onap/setup.cfg b/robotframework-onap/setup.cfg index 8ebf4a0..8bfed92 100644 --- a/robotframework-onap/setup.cfg +++ b/robotframework-onap/setup.cfg @@ -2,7 +2,7 @@ name = robotframework-onap author = Daniel Rose author_email = dr695h@att.com -version = 11.0.0 +version = 11.0.1 home-page = https://github.com/onap/testsuite-python-testing-utils classifier = Development Status :: 4 - Beta @@ -18,6 +18,12 @@ classifier = [options] python_requires = >=3.7 +[tool:pytest] +testpaths = tests +python_files = *Test.py *Tests.py *_test.py test_*.py +python_classes = *Test *Tests Test* +python_functions = test_* test + [files] packages = vcpeutils diff --git a/robotframework-onap/test-requirements.txt b/robotframework-onap/test-requirements.txt index fc71db2..ef92446 100644 --- a/robotframework-onap/test-requirements.txt +++ b/robotframework-onap/test-requirements.txt @@ -1,11 +1,11 @@ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -coverage!=4.4,>=4.0 # Apache-2.0 -mock>=2.0 # BSD -nose # LGPL +coverage>=4.0 # Apache-2.0 +pytest>=7.0.0 +pytest-cov flake8 # MIT pylint # GPLv2 requests requests-mock -more-itertools~=5.0.0 +more-itertools diff --git a/robotframework-onap/tox.ini b/robotframework-onap/tox.ini index 953b640..58856f6 100644 --- a/robotframework-onap/tox.ini +++ b/robotframework-onap/tox.ini @@ -1,9 +1,6 @@ [tox] envlist = pep8,pylint,py3 distdir = {toxinidir}/dist -modules = - ONAPLibrary - vcpeutils [testenv] deps = @@ -12,26 +9,24 @@ deps = install_command = pip install {opts} {packages} [testenv:pep8] -basepython = python3.8 +basepython = python3 changedir = {toxinidir} commands = - flake8 --max-line-length 120 {[tox]modules} + flake8 --max-line-length 120 ONAPLibrary vcpeutils [testenv:pylint] -basepython = python3.8 +basepython = python3 deps = pyflakes pylint commands = - pylint -f parseable --ignore-imports=y --disable=locally-disabled --max-line-length 120 --exit-zero -ry {[tox]modules} + pylint -f parseable --ignore-imports=y --disable=locally-disabled --max-line-length 120 --exit-zero -ry ONAPLibrary vcpeutils [testenv:py3] -basepython = python3.8 -commands = nosetests --with-xunit \ - --all-modules \ - --with-coverage \ - --cover-tests \ - --cover-package=ONAPLibrary,vcpeutils \ - --cover-xml \ - --cover-html \ - tests +basepython = python3 +commands = pytest tests/ \ + --junitxml=test-results.xml \ + --cov=ONAPLibrary \ + --cov=vcpeutils \ + --cov-report=xml \ + --cov-report=html diff --git a/version.properties b/version.properties index 04b9414..c65eadc 100644 --- a/version.properties +++ b/version.properties @@ -4,7 +4,7 @@ major=11 minor=0 -patch=0 +patch=1 base_version=${major}.${minor}.${patch}