-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a new test file tests/test_client.py
with comprehensive unit tests for RPClient
class
#237
base: develop
Are you sure you want to change the base?
Conversation
Add unit tests for client.py
Improve unit tests in elitea_test/test_client.py
Improve unit tests for RPClient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not LGTM
@pytest.fixture | ||
def rp_client(): | ||
return RPClient( | ||
endpoint="http://example.com", | ||
project="test_project", | ||
api_key="test_api_key", | ||
log_batch_size=20, | ||
is_skipped_an_issue=True, | ||
verify_ssl=True, | ||
retries=3, | ||
max_pool_size=50, | ||
launch_uuid="test_launch_uuid", | ||
http_timeout=(10, 10), | ||
log_batch_payload_size=1024, | ||
mode="DEFAULT", | ||
launch_uuid_print=False, | ||
print_output=OutputType.STDOUT | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixture looks OK-ish.
def test_launch_uuid(rp_client): | ||
assert rp_client.launch_uuid == "test_launch_uuid" | ||
|
||
def test_endpoint(rp_client): | ||
assert rp_client.endpoint == "http://example.com" | ||
|
||
def test_project(rp_client): | ||
assert rp_client.project == "test_project" | ||
|
||
def test_step_reporter(rp_client): | ||
assert isinstance(rp_client.step_reporter, StepReporter) | ||
|
||
def test_init_session(rp_client): | ||
rp_client._RPClient__init_session() | ||
assert isinstance(rp_client.session, Session) | ||
assert rp_client.session.headers['Authorization'] == 'Bearer test_api_key' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are OK, but have no much value, since it verifies setting class fields in constructor.
has_stats=True, | ||
code_ref=None, | ||
retry=False, | ||
test_case_id=None | ||
) | ||
assert result == "item_uuid" | ||
mock_start_test_item.assert_called_once() | ||
|
||
def test_finish_test_item(rp_client): | ||
with patch.object(rp_client, 'finish_test_item', return_value="response") as mock_finish_test_item: | ||
result = rp_client.finish_test_item( | ||
item_id="item_uuid", | ||
end_time="2023-01-01T00:00:00.000Z", | ||
status="PASSED", | ||
issue=None, | ||
attributes=[{"key": "value"}], | ||
description="Test Description", | ||
retry=False | ||
) | ||
assert result == "response" | ||
mock_finish_test_item.assert_called_once() | ||
|
||
def test_finish_launch(rp_client): | ||
with patch.object(rp_client, 'finish_launch', return_value="response") as mock_finish_launch: | ||
result = rp_client.finish_launch( | ||
end_time="2023-01-01T00:00:00.000Z", | ||
status="PASSED", | ||
attributes=[{"key": "value"}] | ||
) | ||
assert result == "response" | ||
mock_finish_launch.assert_called_once() | ||
|
||
def test_update_test_item(rp_client): | ||
with patch.object(rp_client, 'update_test_item', return_value="response") as mock_update_test_item: | ||
result = rp_client.update_test_item( | ||
item_uuid="item_uuid", | ||
attributes=[{"key": "value"}], | ||
description="Updated Description" | ||
) | ||
assert result == "response" | ||
mock_update_test_item.assert_called_once() | ||
|
||
def test_get_launch_info(rp_client): | ||
with patch.object(rp_client, 'get_launch_info', return_value={"info": "data"}) as mock_get_launch_info: | ||
result = rp_client.get_launch_info() | ||
assert result == {"info": "data"} | ||
mock_get_launch_info.assert_called_once() | ||
|
||
def test_get_item_id_by_uuid(rp_client): | ||
with patch.object(rp_client, 'get_item_id_by_uuid', return_value="item_id") as mock_get_item_id_by_uuid: | ||
result = rp_client.get_item_id_by_uuid("item_uuid") | ||
assert result == "item_id" | ||
mock_get_item_id_by_uuid.assert_called_once() | ||
|
||
def test_get_launch_ui_id(rp_client): | ||
with patch.object(rp_client, 'get_launch_ui_id', return_value=123) as mock_get_launch_ui_id: | ||
result = rp_client.get_launch_ui_id() | ||
assert result == 123 | ||
mock_get_launch_ui_id.assert_called_once() | ||
|
||
def test_get_launch_ui_url(rp_client): | ||
with patch.object(rp_client, 'get_launch_ui_url', return_value="http://example.com/launch") as mock_get_launch_ui_url: | ||
result = rp_client.get_launch_ui_url() | ||
assert result == "http://example.com/launch" | ||
mock_get_launch_ui_url.assert_called_once() | ||
|
||
def test_get_project_settings(rp_client): | ||
with patch.object(rp_client, 'get_project_settings', return_value={"settings": "data"}) as mock_get_project_settings: | ||
result = rp_client.get_project_settings() | ||
assert result == {"settings": "data"} | ||
mock_get_project_settings.assert_called_once() | ||
|
||
def test_log(rp_client): | ||
with patch.object(rp_client, 'log', return_value=("response",)) as mock_log: | ||
result = rp_client.log( | ||
time="2023-01-01T00:00:00.000Z", | ||
message="Test log message", | ||
level="INFO", | ||
attachment=None, | ||
item_id="item_uuid" | ||
) | ||
assert result == ("response",) | ||
mock_log.assert_called_once() | ||
|
||
def test_current_item(rp_client): | ||
with patch.object(rp_client, 'current_item', return_value="item_uuid") as mock_current_item: | ||
result = rp_client.current_item() | ||
assert result == "item_uuid" | ||
mock_current_item.assert_called_once() | ||
|
||
def test_clone(rp_client): | ||
with patch.object(rp_client, 'clone', return_value=rp_client) as mock_clone: | ||
result = rp_client.clone() | ||
assert result == rp_client | ||
mock_clone.assert_called_once() | ||
|
||
def test_close(rp_client): | ||
with patch.object(rp_client, 'close') as mock_close: | ||
rp_client.close() | ||
mock_close.assert_called_once() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are pointless at all. It mocks methods and then call this mocked methods, and then verifies that the mock is called. It doesn't even call real code.
def test_is_skipped_an_issue(rp_client): | ||
assert rp_client.is_skipped_an_issue is True | ||
|
||
def test_verify_ssl(rp_client): | ||
assert rp_client.verify_ssl is True | ||
|
||
def test_retries(rp_client): | ||
assert rp_client.retries == 3 | ||
|
||
def test_max_pool_size(rp_client): | ||
assert rp_client.max_pool_size == 50 | ||
|
||
def test_http_timeout(rp_client): | ||
assert rp_client.http_timeout == (10, 10) | ||
|
||
def test_log_batch_payload_size(rp_client): | ||
assert rp_client.log_batch_payload_size == 1024 | ||
|
||
def test_mode(rp_client): | ||
assert rp_client.mode == "DEFAULT" | ||
|
||
def test_launch_uuid_print(rp_client): | ||
assert rp_client.launch_uuid_print is False | ||
|
||
def test_print_output(rp_client): | ||
assert rp_client.print_output == OutputType.STDOUT | ||
|
||
def test_log_batch_size(rp_client): | ||
assert rp_client.log_batch_size == 20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are OK, but have no much value, since it verifies setting class fields in constructor.
@pytest.fixture | ||
def rp_client(): | ||
return RPClient( | ||
endpoint="http://example.com", | ||
project="test_project", | ||
api_key="test_api_key", | ||
log_batch_size=20, | ||
is_skipped_an_issue=True, | ||
verify_ssl=True, | ||
retries=3, | ||
max_pool_size=50, | ||
launch_uuid="test_launch_uuid", | ||
http_timeout=(10, 10), | ||
log_batch_payload_size=1024, | ||
mode="DEFAULT", | ||
launch_uuid_print=False, | ||
print_output=OutputType.STDOUT | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixture looks OK-ish.
def test_launch_uuid(rp_client): | ||
assert rp_client.launch_uuid == "test_launch_uuid" | ||
|
||
def test_endpoint(rp_client): | ||
assert rp_client.endpoint == "http://example.com" | ||
|
||
def test_project(rp_client): | ||
assert rp_client.project == "test_project" | ||
|
||
def test_step_reporter(rp_client): | ||
assert isinstance(rp_client.step_reporter, StepReporter) | ||
|
||
def test_init_session(rp_client): | ||
rp_client._RPClient__init_session() | ||
assert isinstance(rp_client.session, Session) | ||
assert rp_client.session.headers['Authorization'] == 'Bearer test_api_key' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are OK, but have no much value, since it verifies setting class fields in constructor.
has_stats=True, | ||
code_ref=None, | ||
retry=False, | ||
test_case_id=None | ||
) | ||
assert result == "item_uuid" | ||
mock_start_test_item.assert_called_once() | ||
|
||
def test_finish_test_item(rp_client): | ||
with patch.object(rp_client, 'finish_test_item', return_value="response") as mock_finish_test_item: | ||
result = rp_client.finish_test_item( | ||
item_id="item_uuid", | ||
end_time="2023-01-01T00:00:00.000Z", | ||
status="PASSED", | ||
issue=None, | ||
attributes=[{"key": "value"}], | ||
description="Test Description", | ||
retry=False | ||
) | ||
assert result == "response" | ||
mock_finish_test_item.assert_called_once() | ||
|
||
def test_finish_launch(rp_client): | ||
with patch.object(rp_client, 'finish_launch', return_value="response") as mock_finish_launch: | ||
result = rp_client.finish_launch( | ||
end_time="2023-01-01T00:00:00.000Z", | ||
status="PASSED", | ||
attributes=[{"key": "value"}] | ||
) | ||
assert result == "response" | ||
mock_finish_launch.assert_called_once() | ||
|
||
def test_update_test_item(rp_client): | ||
with patch.object(rp_client, 'update_test_item', return_value="response") as mock_update_test_item: | ||
result = rp_client.update_test_item( | ||
item_uuid="item_uuid", | ||
attributes=[{"key": "value"}], | ||
description="Updated Description" | ||
) | ||
assert result == "response" | ||
mock_update_test_item.assert_called_once() | ||
|
||
def test_get_launch_info(rp_client): | ||
with patch.object(rp_client, 'get_launch_info', return_value={"info": "data"}) as mock_get_launch_info: | ||
result = rp_client.get_launch_info() | ||
assert result == {"info": "data"} | ||
mock_get_launch_info.assert_called_once() | ||
|
||
def test_get_item_id_by_uuid(rp_client): | ||
with patch.object(rp_client, 'get_item_id_by_uuid', return_value="item_id") as mock_get_item_id_by_uuid: | ||
result = rp_client.get_item_id_by_uuid("item_uuid") | ||
assert result == "item_id" | ||
mock_get_item_id_by_uuid.assert_called_once() | ||
|
||
def test_get_launch_ui_id(rp_client): | ||
with patch.object(rp_client, 'get_launch_ui_id', return_value=123) as mock_get_launch_ui_id: | ||
result = rp_client.get_launch_ui_id() | ||
assert result == 123 | ||
mock_get_launch_ui_id.assert_called_once() | ||
|
||
def test_get_launch_ui_url(rp_client): | ||
with patch.object(rp_client, 'get_launch_ui_url', return_value="http://example.com/launch") as mock_get_launch_ui_url: | ||
result = rp_client.get_launch_ui_url() | ||
assert result == "http://example.com/launch" | ||
mock_get_launch_ui_url.assert_called_once() | ||
|
||
def test_get_project_settings(rp_client): | ||
with patch.object(rp_client, 'get_project_settings', return_value={"settings": "data"}) as mock_get_project_settings: | ||
result = rp_client.get_project_settings() | ||
assert result == {"settings": "data"} | ||
mock_get_project_settings.assert_called_once() | ||
|
||
def test_log(rp_client): | ||
with patch.object(rp_client, 'log', return_value=("response",)) as mock_log: | ||
result = rp_client.log( | ||
time="2023-01-01T00:00:00.000Z", | ||
message="Test log message", | ||
level="INFO", | ||
attachment=None, | ||
item_id="item_uuid" | ||
) | ||
assert result == ("response",) | ||
mock_log.assert_called_once() | ||
|
||
def test_current_item(rp_client): | ||
with patch.object(rp_client, 'current_item', return_value="item_uuid") as mock_current_item: | ||
result = rp_client.current_item() | ||
assert result == "item_uuid" | ||
mock_current_item.assert_called_once() | ||
|
||
def test_clone(rp_client): | ||
with patch.object(rp_client, 'clone', return_value=rp_client) as mock_clone: | ||
result = rp_client.clone() | ||
assert result == rp_client | ||
mock_clone.assert_called_once() | ||
|
||
def test_close(rp_client): | ||
with patch.object(rp_client, 'close') as mock_close: | ||
rp_client.close() | ||
mock_close.assert_called_once() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are pointless at all. It mocks methods and then call this mocked methods, and then verifies that the mock is called. It doesn't even call real code.
def test_is_skipped_an_issue(rp_client): | ||
assert rp_client.is_skipped_an_issue is True | ||
|
||
def test_verify_ssl(rp_client): | ||
assert rp_client.verify_ssl is True | ||
|
||
def test_retries(rp_client): | ||
assert rp_client.retries == 3 | ||
|
||
def test_max_pool_size(rp_client): | ||
assert rp_client.max_pool_size == 50 | ||
|
||
def test_http_timeout(rp_client): | ||
assert rp_client.http_timeout == (10, 10) | ||
|
||
def test_log_batch_payload_size(rp_client): | ||
assert rp_client.log_batch_payload_size == 1024 | ||
|
||
def test_mode(rp_client): | ||
assert rp_client.mode == "DEFAULT" | ||
|
||
def test_launch_uuid_print(rp_client): | ||
assert rp_client.launch_uuid_print is False | ||
|
||
def test_print_output(rp_client): | ||
assert rp_client.print_output == OutputType.STDOUT | ||
|
||
def test_log_batch_size(rp_client): | ||
assert rp_client.log_batch_size == 20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are OK, but have no much value, since it verifies setting class fields in constructor.
def test_get_item_id_by_uuid_not_found(rp_client): | ||
with patch.object(rp_client, 'get_item_id_by_uuid', return_value=None) as mock_get_item_id_by_uuid: | ||
result = rp_client.get_item_id_by_uuid("non_existent_uuid") | ||
assert result is None | ||
mock_get_item_id_by_uuid.assert_called_once() | ||
|
||
def test_start_launch_with_rerun(rp_client): | ||
with patch.object(rp_client, 'start_launch', return_value="launch_uuid") as mock_start_launch: | ||
result = rp_client.start_launch( | ||
name="Test Launch", | ||
start_time="2023-01-01T00:00:00.000Z", | ||
description="Test Description", | ||
attributes=[{"key": "value"}], | ||
rerun=True, | ||
rerun_of="previous_launch_uuid" | ||
) | ||
assert result == "launch_uuid" | ||
mock_start_launch.assert_called_once() | ||
|
||
def test_finish_test_item_with_issue(rp_client): | ||
issue = Issue(issue_type="BUG", comment="Test issue") | ||
with patch.object(rp_client, 'finish_test_item', return_value="response") as mock_finish_test_item: | ||
result = rp_client.finish_test_item( | ||
item_id="item_uuid", | ||
end_time="2023-01-01T00:00:00.000Z", | ||
status="FAILED", | ||
issue=issue, | ||
attributes=[{"key": "value"}], | ||
description="Test Description", | ||
retry=False | ||
) | ||
assert result == "response" | ||
mock_finish_test_item.assert_called_once() | ||
|
||
def test_log_with_attachment(rp_client): | ||
attachment = {"name": "screenshot.png", "data": b"binary_data", "mime": "image/png"} | ||
with patch.object(rp_client, 'log', return_value=("response",)) as mock_log: | ||
result = rp_client.log( | ||
time="2023-01-01T00:00:00.000Z", | ||
message="Test log message with attachment", | ||
level="INFO", | ||
attachment=attachment, | ||
item_id="item_uuid" | ||
) | ||
assert result == ("response",) | ||
mock_log.assert_called_once() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are pointless at all. It mocks methods and then call this mocked methods, and then verifies that the mock is called. It doesn't even call real code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a quick glance over the code, feel free to ignore :)
) | ||
|
||
def test_launch_uuid(rp_client): | ||
assert rp_client.launch_uuid == "test_launch_uuid" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather make a single test with no fixtures:
def test_constructor():
rp_client = ...
assert rp_client.field1 == "..."
assert rp_client.field2 == "..."
assert isinstance(rp_client.step_reporter, StepReporter) | ||
|
||
def test_init_session(rp_client): | ||
rp_client._RPClient__init_session() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is calling a private method. Sign of something wrong with design
|
||
def test_get_launch_info(rp_client): | ||
with patch.object(rp_client, 'get_launch_info', return_value={"info": "data"}) as mock_get_launch_info: | ||
result = rp_client.get_launch_info() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests like these don't make much sense because they are doing the following:
- Create an object
- Mock its function to return a value
- Call the function
- Assert it has been called and returned the value (Sure thing! What would it return otherwise?)
assert result == "item_id" | ||
mock_get_item_id_by_uuid.assert_called_once() | ||
|
||
def test_get_launch_ui_id(rp_client): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for this file. The only meaningful test is the one testing the constructor
By the way, the idea of creating an object via a fixture is ok for the tests if you need a fresh object per test. So, the code is correct
Add Integrational Tests
Add Integrational Tests for RPClient
tests/test_client.py
with comprehensive unit tests forRPClient
class.Please assist in resolving the branch creation issue or provide the necessary permissions to proceed.