1
\$\begingroup\$

I am writing a python module to interact to the ROD (remedy on demand) BMC ticketing product. So far I have only written the log in and log out methods and tests. Before I crack on with the more complex methods I hope someone can review the current test strategy and happy to hear any suggestions for improvements.

rodAPI.py

import requests
class RodApi:
 def __init__(self, fqdn, username, password, token_type="AR-JWT"):
 self.username = username
 self.password = password
 self.fqdn = fqdn
 self.token_type = token_type
 self.login_url = f"https://{fqdn}/api/jwt/login"
 self.logout_url = f"https://{fqdn}/api/jwt/logout"
 self.token = None
 def login(self) -> bool:
 data = {"username": self.username, "password": self.password}
 headers = {"content-type": "application/x-www-form-urlencoded"}
 response = requests.post(self.login_url, data=data, headers=headers)
 print(f"connecting to URL: {self.login_url}")
 print(f"https status code: {response.status_code}")
 self.token = response.text
 if response.status_code == 200:
 return True
 return False
 def logout(self) -> bool:
 headers = {"Authorization": f"{self.token_type} {self.token}"}
 response = requests.post(self.logout_url, headers=headers)
 print(f"connecting to URL: {self.logout_url}")
 print(f"https status code: {response.status_code}")
 if response.status_code == 204:
 print(f"Logged out with a status of: {response.status_code}")
 return True
 else:
 print(f"Error logging out: {response.text}")
 return False

test_rodAPI

import pytest
from rodAPI import RodApi
@pytest.fixture()
def rod_api_instance():
 rod_api = RodApi("example.com", "some_user", "some_password")
 return rod_api
@pytest.fixture()
def rod_api_logged_in_instance(responses, rod_api_instance):
 responses.add(responses.POST, rod_api_instance.login_url, body="some_token_string")
 rod_api_instance.login()
 return rod_api_instance
def test_login_success(responses, rod_api_instance: RodApi):
 responses.add(responses.POST, rod_api_instance.login_url, body="some_token_string")
 result = rod_api_instance.login()
 assert result is True
 assert rod_api_instance.token == "some_token_string"
def test_login_fail(responses, rod_api_instance: RodApi):
 responses.add(responses.POST, rod_api_instance.login_url, status=404)
 result = rod_api_instance.login()
 assert result is False
def test_logout_success(responses, rod_api_logged_in_instance: RodApi):
 responses.add(responses.POST, rod_api_logged_in_instance.logout_url, status=204)
 result = rod_api_logged_in_instance.logout()
 assert result is True
def test_logout_fail(responses, rod_api_logged_in_instance: RodApi):
 responses.add(responses.POST, rod_api_logged_in_instance.logout_url, status=404)
 result = rod_api_logged_in_instance.logout()
 assert result is False
```
Reinderien
70.9k5 gold badges76 silver badges256 bronze badges
asked Jan 1, 2021 at 15:29
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Redundant headers

Read https://github.com/psf/requests/blob/master/requests/models.py#L514 - your use of

 headers = {"content-type": "application/x-www-form-urlencoded"}

should not be needed.

Out-of-order progress

You print

 print(f"connecting to URL: {self.login_url}")

when this has already happened. Either say "connected to", or move this statement before your post.

Exception degradation

Resist the urge to sabotage the Python exception system. Rather than returning booleans from your methods, call response.raise_for_status, and optionally wrap that in a try/except/raise MyException() from e with your own exception type. raise_for_status will also obviate your status code checks.

answered Jan 1, 2021 at 15:59
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for the feedback, I wasnt aware of raise for status, I have taken all your feedback and incorporated it into my code and testing strategy. \$\endgroup\$ Commented Jan 1, 2021 at 20:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.