Skip to content

Comments

Feature/testing improvements#422

Open
thomasc-adyen wants to merge 2 commits intomainfrom
feature/testing-improvements
Open

Feature/testing improvements#422
thomasc-adyen wants to merge 2 commits intomainfrom
feature/testing-improvements

Conversation

@thomasc-adyen
Copy link

Description
Migrates the project to use pytest and a more modernized testing infrastructure, and introduces integration tests using a localhost server that loads data from mock files.

- Replaced unittest.TestCase with pytest fixtures and native assertions
- Implemented test/conftest.py with shared adyen_instance and mock_client fixtures
- Renamed all test files to follow snake_case convention (test_*.py)
- Removed obsolete test/BaseTest.py
- Updated tox.ini and Makefile to use pytest as default test runner
- Fixed brittle HMAC tests and incorrect API method calls identified during migration
- Implemented session-scoped mock_server fixture in conftest.py
- Added dynamic mock file serving capability via X-Mock-File header
- Created test/test_http_backends.py to verify real network communication
- Validated all supported backends (requests, pycurl, urllib) against the wire
- Added timeout resiliency tests for each networking stack
@thomasc-adyen thomasc-adyen requested review from a team as code owners February 20, 2026 18:08
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
E Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

except:
response["received_body"] = post_data.decode('utf-8')

self.wfile.write(json.dumps(response).encode('utf-8'))

Check failure

Code scanning / SonarCloud

Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks High test

Change this code to not reflect unsanitized user-controlled data. See more on SonarQube Cloud
return None

# Try to find the file
if not os.path.exists(filename):

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High test

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
self.wfile.write(f"Mock file not found: {filename}".encode())
return True

with open(filename, 'rb') as f:

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High test

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @thomasc-adyen, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the project's testing capabilities by transitioning from the unittest framework to pytest. This migration not only modernizes the test suite but also introduces a robust integration testing setup. The new setup leverages a local mock server to simulate API responses from mock files, ensuring comprehensive and reliable testing of Adyen services. These changes aim to improve test maintainability, readability, and overall development efficiency.

Highlights

  • Testing Framework Migration: Migrated the entire test suite from unittest to pytest, adopting a more modern and flexible testing framework.
  • Enhanced Integration Testing: Introduced a new integration testing infrastructure that utilizes a localhost server to load data from mock files, enabling more realistic and isolated API testing.
  • Test File Restructuring: Refactored test files, removing old unittest based files and adding new pytest compatible test modules for various Adyen services.
  • Build Process Updates: Updated Makefile and tox.ini to reflect the new pytest commands for running tests and generating coverage reports.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Makefile
    • Updated the 'tests' command to use 'pytest' instead of 'python -m unittest discover'.
    • Modified the 'coverage' command to use 'pytest --cov=Adyen' for coverage reporting.
  • test/BalancePlatformTest.py
    • Removed the unittest based test file for Balance Platform API.
  • test/BaseTest.py
    • Removed the unittest based base test utility class.
  • test/BinLookupTest.py
    • Removed the unittest based test file for Bin Lookup API.
  • test/CapitalTest.py
    • Removed the unittest based test file for Capital API.
  • test/CheckoutTest.py
    • Removed the unittest based test file for Checkout API.
  • test/CheckoutUtilityTest.py
    • Removed the unittest based test file for Checkout Utility API.
  • test/ClientTest.py
    • Removed the unittest based test file for Adyen Client.
  • test/DataProtectionTest.py
    • Removed the unittest based test file for Data Protection API.
  • test/DetermineEndpointTest.py
    • Removed the unittest based test file for endpoint determination.
  • test/DisputesTest.py
    • Removed the unittest based test file for Disputes API.
  • test/HttpClientTest.py
    • Removed the unittest based test file for HTTP Client.
  • test/LegalEntityManagementTest.py
    • Removed the unittest based test file for Legal Entity Management API.
  • test/ManagementTest.py
    • Removed the unittest based test file for Management API.
  • test/ModificationTest.py
    • Removed the unittest based test file for Payment Modification API.
  • test/PaymentTest.py
    • Removed the unittest based test file for Payment API.
  • test/PosMobileTest.py
    • Removed the unittest based test file for POS Mobile API.
  • test/RecurringTest.py
    • Removed the unittest based test file for Recurring API.
  • test/SessionAuthenticationTest.py
    • Removed the unittest based test file for Session Authentication API.
  • test/StoredValueTest.py
    • Removed the unittest based test file for Stored Value API.
  • test/TerminalTest.py
    • Removed the unittest based test file for Terminal API.
  • test/ThirdPartyPayoutTest.py
    • Removed the unittest based test file for Third Party Payout API.
  • test/TransfersTest.py
    • Removed the unittest based test file for Transfers API.
  • test/UtilTest.py
    • Removed the unittest based test file for utility functions.
  • test/conftest.py
    • Added pytest configuration file with fixtures for mock server and Adyen client setup.
  • test/methodNamesTests/checkoutTest.py
    • Removed the unittest based test file for Checkout method names.
  • test/methodNamesTests/test_checkout_methods.py
    • Added pytest tests to verify the structure of Checkout API methods.
  • test/test_balance_platform.py
    • Added pytest tests for Balance Platform API functionalities.
  • test/test_bin_lookup.py
    • Added pytest tests for Bin Lookup API functionalities.
  • test/test_capital.py
    • Added pytest tests for Capital API functionalities.
  • test/test_checkout.py
    • Added pytest tests for Checkout API functionalities.
  • test/test_checkout_utility.py
    • Added pytest tests for Checkout Utility API functionalities.
  • test/test_client.py
    • Added pytest tests for Adyen client initialization and credential handling.
  • test/test_data_protection.py
    • Added pytest tests for Data Protection API functionalities.
  • test/test_determine_endpoint.py
    • Added pytest tests for API endpoint determination logic.
  • test/test_disputes.py
    • Added pytest tests for Disputes API functionalities.
  • test/test_http_backends.py
    • Added pytest tests to validate HTTP backend communication and mock server integration.
  • test/test_http_client.py
    • Added pytest tests to verify HTTP client user-agent headers.
  • test/test_legal_entity_management.py
    • Added pytest tests for Legal Entity Management API functionalities.
  • test/test_management.py
    • Added pytest tests for Management API functionalities.
  • test/test_modification.py
    • Added pytest tests for Payment Modification API functionalities.
  • test/test_payment.py
    • Added pytest tests for Payment API functionalities.
  • test/test_pos_mobile.py
    • Added pytest tests for POS Mobile API functionalities.
  • test/test_recurring.py
    • Added pytest tests for Recurring API functionalities.
  • test/test_session_authentication.py
    • Added pytest tests for Session Authentication API functionalities.
  • test/test_stored_value.py
    • Added pytest tests for Stored Value API functionalities.
  • test/test_terminal.py
    • Added pytest tests for Terminal API functionalities.
  • test/test_third_party_payout.py
    • Added pytest tests for Third Party Payout API functionalities.
  • test/test_transfers.py
    • Added pytest tests for Transfers API functionalities.
  • test/test_util.py
    • Added pytest tests for utility functions, including HMAC validation.
  • tox.ini
    • Updated dependencies to include pytest and pytest-mock.
    • Changed the test command to execute pytest.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and well-executed migration of the test suite from unittest to pytest. The introduction of pytest features like fixtures (in conftest.py) and parameterized tests modernizes the testing infrastructure and improves maintainability. The new integration tests using a localhost server are a great addition for verifying the behavior of different HTTP backends.

I've found a couple of areas for improvement in the new test files, mainly related to test structure and efficiency. My comments are detailed below. Overall, this is an excellent improvement to the project's testing capabilities.

Comment on lines +62 to +76
"""Verifies that timeouts are handled (using a non-responsive endpoint if possible)."""
# This is a bit harder with http.server as it is single-threaded and handles one request at a time.
# But we can verify that the timeout parameter is at least passed correctly.
ady = Adyen.Adyen()
ady.client.http_timeout = 0.001
ady.client.http_force = "requests"
ady.client._init_http_client()

# We expect a timeout error from the backend
with pytest.raises(Exception):
ady.client.http_client.request(
"GET",
f"{mock_server}/slow-endpoint",
xapikey="TEST_XAPI_KEY"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This timeout test logic appears to be misplaced within the test_backend_with_real_mock_file function and will run as part of it. It should be extracted into its own separate test function to ensure proper test isolation and clarity. Additionally, the test is hardcoded for the 'requests' backend. It would be more robust to parameterize it to cover all supported HTTP backends ('requests', 'pycurl', 'urllib'), similar to test_backend_communication.

Comment on lines +126 to +129
with open(filename) as data_file:
data = json.load(data_file)
with open(filename) as st:
strjson = st.read()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This implementation opens and reads the same file twice, which is inefficient. The file content can be read once into a string, and then parsed as JSON. This avoids redundant I/O operations.

            with open(filename, 'r') as data_file:
                strjson = data_file.read()
            data = json.loads(strjson)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant