Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,38 @@ jobs:
run: ruff format --check .
continue-on-error: true

test:
test-offline:
needs: lint
runs-on: ubuntu-22.04
timeout-minutes: 10
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v5
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov pyright tox
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
- name: Type check with pyright (Python 3.12 only)
if: matrix.python-version == '3.12'
run: pyright
- name: Test offline (mocked/unit tests)
run: tox -e offline
- name: Coveralls Parallel
uses: coverallsapp/github-action@v2
with:
parallel: true
flag-name: offline-py${{ matrix.python-version }}

test-live:
needs: lint
runs-on: ubuntu-22.04
timeout-minutes: 40
Expand Down Expand Up @@ -63,17 +94,16 @@ jobs:
pip install pytest pytest-cov pyright tox
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
- name: Type check with pyright (Python 3.12 only)
if: matrix.python-version == '3.12'
run: pyright
- name: Test with tox
run: tox -e py
- name: Test live (network/testnet tests)
run: tox -e live
- name: Coveralls Parallel
uses: coverallsapp/github-action@v2
with:
parallel: true
flag-name: live-py${{ matrix.python-version }}

finish:
needs: test
needs: [test-offline, test-live]
if: ${{ always() }}
runs-on: ubuntu-latest
timeout-minutes: 5
Expand Down
10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@ lint.ignore = ["F722","F841","F821","E402","E501","E902","E713","E741","E714", "
timeout = 90
timeout_method = "thread"
asyncio_default_fixture_loop_scope = "function"

markers = [
"live: requires network access to Binance",
"spot: mark a test as part of the spot tests",
"futures: mark a test as part of the futures tests",
"margin: mark a test as part of the margin tests",
"portfolio: mark a test as part of the portfolio tests",
"gift_card: mark a test as part of the gift card tests",
"options: mark a test as part of the options tests",
]
44 changes: 27 additions & 17 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
testnet = os.getenv("TEST_TESTNET", "true").lower() == "true"
api_key = "u4L8MG2DbshTfTzkx2Xm7NfsHHigvafxeC29HrExEmah1P8JhxXkoOu6KntLICUc"
api_secret = "hBZEqhZUUS6YZkk7AIckjJ3iLjrgEFr5CRtFPp5gjzkrHKKC9DAv4OH25PlT6yq5"
testnet = True # only for spot now
demo = True # spot and swap
testnet = True # only for spot now
demo = True # spot and swap
futures_api_key = "HjhMFvuF1veWQVdUbLIy7TiCYe9fj4W6sEukmddD8TM9kPVRHMK6nS2SdV5mwE5u"
futures_api_secret = "Suu9pWcO9zbvVuc6cSQsVuiiw2DmmA8DgHrUfePF9s2RtaHa0zxK3eAF4MfIk7Pd"

Expand Down Expand Up @@ -58,9 +58,7 @@ def liveClient():

@pytest.fixture(scope="function")
def futuresClient():
return Client(
futures_api_key, futures_api_secret, {"proxies": proxies}, demo=demo
)
return Client(futures_api_key, futures_api_secret, {"proxies": proxies}, demo=demo)


@pytest_asyncio.fixture(scope="function")
Expand Down Expand Up @@ -91,12 +89,14 @@ async def liveClientAsync():
finally:
await client.close_connection()


@pytest.fixture(scope="function")
def manager():
return ThreadedWebsocketManager(
api_key="test_key", api_secret="test_secret", https_proxy=proxy, testnet=True
)


@pytest.fixture(autouse=True, scope="function")
def event_loop():
"""Create new event loop for each test"""
Expand All @@ -111,7 +111,9 @@ def event_loop():
for task in pending:
task.cancel()
if pending:
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
loop.run_until_complete(
asyncio.gather(*pending, return_exceptions=True)
)
except Exception:
pass # Ignore cleanup errors
finally:
Expand Down Expand Up @@ -157,6 +159,10 @@ def pytest_configure(config):
config.addinivalue_line(
"markers", "gift_card: mark a test as part of the gift card tests"
)
config.addinivalue_line(
"markers", "options: mark a test as part of the options tests"
)
config.addinivalue_line("markers", "live: requires network access to Binance")


def pytest_collection_modifyitems(config, items):
Expand All @@ -178,36 +184,40 @@ def pytest_collection_modifyitems(config, items):
item.add_marker(skip_gift_card)


def call_method_and_assert_uri_contains(client, method_name, expected_string, *args, **kwargs):
def call_method_and_assert_uri_contains(
client, method_name, expected_string, *args, **kwargs
):
"""
Helper function to test that a client method calls the expected URI.

Args:
client: The client instance to test
method_name: Name of the method to call (as string)
expected_string: String that should be present in the URI
*args, **kwargs: Arguments to pass to the client method

Returns:
The result of the method call
"""
from unittest.mock import patch
with patch.object(client, '_request', wraps=client._request) as mock_request:

with patch.object(client, "_request", wraps=client._request) as mock_request:
# Get the method from the client and call it
method = getattr(client, method_name)
result = method(*args, **kwargs)

# Assert that _request was called
mock_request.assert_called_once()

# Get the arguments passed to _request
args_passed, kwargs_passed = mock_request.call_args

# The second argument is the URI
uri = args_passed[1]

# Assert that the URL contains the expected string
assert expected_string in uri, f"Expected '{expected_string}' in URL, but got: {uri}"

assert expected_string in uri, (
f"Expected '{expected_string}' in URL, but got: {uri}"
)

return result
Loading
Loading