Skip to content

Commit

Permalink
Merge pull request #13 from nassauwinter/main
Browse files Browse the repository at this point in the history
Make dev up-to-date with main branch
  • Loading branch information
nassauwinter authored Aug 17, 2023
2 parents 134f034 + 4125a73 commit 627c8af
Show file tree
Hide file tree
Showing 26 changed files with 946 additions and 87 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build_and_load_to_pypi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ name: Building artifacts and load them to PYPI index
on:
push:
branches: [ main ]
paths:
- 'VERSION.txt'

jobs:
Build_release:

runs-on: ubuntu-latest
runs-on: ubuntu-20.04

steps:
- uses: actions/setup-python@v4
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/pr_checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ name: PR checks
on:
pull_request:
branches: [ main, dev ]
paths:
- 'zephyr/**'
push:
branches: [ dev ]

jobs:
Run_PR_checks:

runs-on: ubuntu-latest
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [ '3.7', '3.8', '3.9' ]
python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10', '3.11' ]

steps:
- name: Check out repository code
Expand All @@ -37,4 +39,4 @@ jobs:
pipenv run pip list --local
- name: Test with tox
run: pipenv run tox
run: pipenv run tox
3 changes: 0 additions & 3 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,3 @@ pylint = "*"
build = "*"
twine = "*"
tox-gh-actions = "*"

[requires]
python_version = "3.8"
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
![PyPI](https://img.shields.io/pypi/v/zephyr-python-api)
![PyPI - License](https://img.shields.io/pypi/l/zephyr-python-api)
### Project description
This is a set of wrappers for Zephyr Scale (TM4J) REST API. This means you can interact with Zephyr Scale without GUI, access it with python code and create automation scripts for your every day interactions.

NOTE: Currently only Scale Cloud wrappers are implemented.
This is a set of wrappers for Zephyr Scale (TM4J) REST API. This means you can interact with Zephyr Scale without GUI, access it with python code and create automation scripts for your every day interactions.

To be done:
* Scale Server wrappers implementations
* Usage examples
* More usage examples
* Tests, tests and tests for gods of testing
* Convenient docs
* Implementing higher level wrappers representing Test Case, Test Cycle, etc.

### Installation

Expand All @@ -30,7 +30,7 @@ zscale = ZephyrScale(token=<your_token>)

Zephyr Server (TM4J) auth:
```python
from zephyr import API_V1, ZephyrScale
from zephyr import ZephyrScale

# Auth can be made with Jira token
auth = {"token": "<your_jira_token>"}
Expand All @@ -41,7 +41,7 @@ auth = {"username": "<your_login>", "password": "<your_password>"}
# or even session cookie dict
auth = {"cookies": "<session_cookie_dict>"}

zscale = ZephyrScale(api=API_V1, base_url=<your_base_url>, **auth)
zscale = ZephyrScale.server_api(base_url=<your_base_url>, **auth)
```

Then it is possible to interact with api wrappers:
Expand All @@ -58,6 +58,10 @@ test_case = zapi.test_cases.get_test_case("<test_case_id>")
creation_result = zapi.test_cases.create_test_case("<project_key>", "test_case_name")
```

### Troubleshooting

For troubleshooting see [TROUBLESHOOTING.md](TROUBLESHOOTING.md)


### License

Expand Down
5 changes: 5 additions & 0 deletions TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Reporting to Zephyr

- The Cucumber format is different from Behave reporter format.
In case you want to report test executions from output Behave file,
please use some custom formatter for Behave output, i.e. https://pypi.org/project/behave-cucumber-formatter/.
1 change: 1 addition & 0 deletions VERSION.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.3
72 changes: 72 additions & 0 deletions examples/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Usage examples of Zephyr Scale Server API wrappers.
"""
import logging

from zephyr import ZephyrScale


# Enable logging with level Debug for more verbosity
logging.basicConfig(level=logging.DEBUG)


# Specify your Jira context to operate with:
base_url = "https://http://localhost:2990/jira/rest/atm/1.0/"


# Deside the type of authorization. It could be a token, username/password or cookies
auth = {"token": "<your_jira_token>"}
# auth = {"username": "<your_username>", "password": "your_pass"}
# auth = {"cookies": "<your_cookie_dict>"}

# Create an instance of Zephyr Scale
zscale = ZephyrScale.server_api(base_url=base_url, **auth)


# Now we can start playing with the Zephyr API!
test_cases = zscale.api.test_cases

# Get a test case:
case_data = test_cases.get_test_case("<your_case_id>")

# Create a test case:
creation_data = test_cases.create_test_case("<your_project_key>", "Test case name")

# Update a test case:
test_script = {
"type": "STEP_BY_STEP",
"steps": [
{
"description": "Description for the step 1",
"testData": "Some test data",
"expectedResult": "Expectations"
},
{
"description": "Step 2 description",
"testData": "Some more test data",
"expectedResult": "Expected result for the step 2"
}]}
update_data = test_cases.update_test_case("<your_case_id>",
objective=f"New_test_objective",
testScript=test_script)

# Delete a test case:
deleted = test_cases.delete_test_case("<case_id_you_don't_need_anymore>")

# Get test case attachments:
attachments = test_cases.get_attachments("<your_case_id>")

# Create a test case attachment (upload):
upload_result = test_cases.create_attachment("<your_case_id>", "path_to_attachment_file")

# Get the latest execution result for the test case:
execution_data = test_cases.get_latest_result("<your_case_id>")

# Get attachments for a specified step:
test_cases.get_step_attachments("<your_case_id>", "<step_id>")

# Create an attachment for step:
test_cases.create_step_attachment("<your_case_id>", "<step_id>", "path_to_attachment_file")

# Search test cases with JQL:
search = test_cases.search_cases(query='projectKey = "<your_awesome_porojects_key>"')
8 changes: 6 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = zephyr-python-api
version = 0.0.1.dev2
version = file: VERSION.txt
author = Petr Sharapenko
author_email = nassauwinter@gmail.com
description = Zephyr (TM4J) Python REST API wrapper
Expand All @@ -10,14 +10,18 @@ url = https://github.com/nassauwinter/zephyr-python-api
project_urls =
Bug Tracker = https://github.com/nassauwinter/zephyr-python-api/issues
classifiers =
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
License :: OSI Approved :: Apache Software License
Operating System :: OS Independent

[options]
packages = find:
python_requires = >=3.7
python_requires = >=3.6
install_requires =
requests

Expand Down
9 changes: 9 additions & 0 deletions tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[pytest]
markers =
unit: test Zephyr Scale modules
integration: test integration with Server/Cloud

log_cli = True
log_cli_level = DEBUG
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
54 changes: 0 additions & 54 deletions tests/test_scale.py

This file was deleted.

Empty file added tests/unit/__init__.py
Empty file.
63 changes: 63 additions & 0 deletions tests/unit/test_scale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from logging import Logger

import pytest

from zephyr.scale.scale import DEFAULT_BASE_URL, ZephyrScale


ZSESSION_PATH = "zephyr.scale.scale.ZephyrSession"
CLOUD_API_WRAP_PATH = "zephyr.scale.scale.CloudApiWrapper"
SERVER_API_WRAP_PATH = "zephyr.scale.scale.ServerApiWrapper"


@pytest.mark.unit
class TestZephyrScale:
@pytest.mark.parametrize("creation_kwargs, exp_url", [({}, DEFAULT_BASE_URL),
({"base_url": DEFAULT_BASE_URL}, DEFAULT_BASE_URL),
({"base_url": "test.com"}, "test.com")])
def test_scale_session_creation(self, creation_kwargs, exp_url, mocker):
session_mock = mocker.patch(ZSESSION_PATH)
mocker.patch(CLOUD_API_WRAP_PATH)

ZephyrScale(**creation_kwargs)

session_mock.assert_called_once_with(base_url=exp_url)

@pytest.mark.parametrize("creation_kwargs, api_version", [({}, CLOUD_API_WRAP_PATH),
({"api_version": "v2"}, CLOUD_API_WRAP_PATH),
({"api_version": "V2"}, CLOUD_API_WRAP_PATH),
({"api_version": "v1"}, SERVER_API_WRAP_PATH),
({"api_version": "V1"}, SERVER_API_WRAP_PATH)])
def test_scale_defining_version(self, creation_kwargs, api_version, mocker):
zsession_mock = mocker.patch(ZSESSION_PATH)
wrapper_mock = mocker.patch(api_version)

zephyr = ZephyrScale(**creation_kwargs)

assert isinstance(zephyr, ZephyrScale), f"Resulted object should be instance of {ZephyrScale}"
wrapper_mock.assert_called_once_with(zsession_mock())

@pytest.mark.parametrize("creation_kwargs, api_version", [({"base_url": "test.com"}, SERVER_API_WRAP_PATH)])
def test_server_cls_method(self, creation_kwargs, api_version, mocker):
zsession_mock = mocker.patch(ZSESSION_PATH)
wrapper_mock = mocker.patch(api_version)

zephyr = ZephyrScale.server_api(**creation_kwargs)
assert isinstance(zephyr, ZephyrScale), f"Resulted object should be instance of {ZephyrScale}"
wrapper_mock.assert_called_once_with(zsession_mock())

@pytest.mark.parametrize("creation_kwargs, exception",
[({"api_version": "v"}, ValueError)])
def test_scale_defining_version_exceptions(self, creation_kwargs, exception, mocker):
mocker.patch(ZSESSION_PATH)

with pytest.raises(exception):
ZephyrScale(**creation_kwargs)

def test_scale_logger(self, mocker):
mocker.patch(ZSESSION_PATH)
mocker.patch(CLOUD_API_WRAP_PATH)

zephyr = ZephyrScale()

assert isinstance(zephyr.logger, Logger)
Loading

0 comments on commit 627c8af

Please sign in to comment.