From 6c8253a4f57571d210cca60c41da86c5d03cafe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20LONLAS?= Date: Wed, 27 Dec 2017 02:41:11 -0800 Subject: [PATCH] Add more unittest (#241) --- freqtrade/persistence.py | 2 +- freqtrade/tests/test_main.py | 25 ++++++++ freqtrade/tests/test_persistence.py | 98 ++++++++++++++++++++++++++++- 3 files changed, 123 insertions(+), 2 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 9825299b7..d50c9acb4 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -104,7 +104,7 @@ class Trade(_DECL_BASE): self.close(order['rate']) else: raise ValueError('Unknown order type: {}'.format(order['type'])) - Trade.session.flush() + cleanup() def close(self, rate: float) -> None: """ diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 7c06936c0..037d6f836 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -4,6 +4,7 @@ from unittest.mock import MagicMock import pytest import requests +import logging from sqlalchemy import create_engine from freqtrade import DependencyException, OperationalException @@ -216,6 +217,30 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker): assert trade.close_date is not None +def test_handle_trade_experimental(default_conf, ticker, limit_buy_order, mocker, caplog): + default_conf.update({'experimental': {'use_sell_signal': True}}) + mocker.patch.dict('freqtrade.main._CONF', default_conf) + + mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True) + mocker.patch.multiple('freqtrade.rpc', init=MagicMock(), send_msg=MagicMock()) + mocker.patch.multiple('freqtrade.main.exchange', + validate_pairs=MagicMock(), + get_ticker=ticker, + buy=MagicMock(return_value='mocked_limit_buy')) + mocker.patch('freqtrade.main.min_roi_reached', return_value=True) + + init(default_conf, create_engine('sqlite://')) + create_trade(0.001) + + trade = Trade.query.first() + trade.is_open = True + + mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: False) + value_returned = handle_trade(trade) + assert ('freqtrade', logging.DEBUG, 'Checking sell_signal ...') in caplog.record_tuples + assert value_returned is False + + def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mocker): mocker.patch.dict('freqtrade.main._CONF', default_conf) mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True) diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index f91a8efd0..c2e2c13ea 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,8 +1,91 @@ # pragma pylint: disable=missing-docstring import pytest +import os from freqtrade.exchange import Exchanges -from freqtrade.persistence import Trade +from freqtrade.persistence import init, Trade + + +def test_init_create_session(default_conf, mocker): + mocker.patch.dict('freqtrade.persistence._CONF', default_conf) + + # Check if init create a session + init(default_conf) + assert hasattr(Trade, 'session') + assert type(Trade.session).__name__ is 'Session' + + +def test_init_dry_run_db(default_conf, mocker): + default_conf.update({'dry_run_db': True}) + mocker.patch.dict('freqtrade.persistence._CONF', default_conf) + + # First, protect the existing 'tradesv3.dry_run.sqlite' (Do not delete user data) + dry_run_db = 'tradesv3.dry_run.sqlite' + dry_run_db_swp = dry_run_db + '.swp' + + if os.path.isfile(dry_run_db): + os.rename(dry_run_db, dry_run_db_swp) + + # Check if the new tradesv3.dry_run.sqlite was created + init(default_conf) + assert os.path.isfile(dry_run_db) is True + + # Delete the file made for this unitest and rollback to the previous + # tradesv3.dry_run.sqlite file + + # 1. Delete file from the test + if os.path.isfile(dry_run_db): + os.remove(dry_run_db) + + # 2. Rollback to the initial file + if os.path.isfile(dry_run_db_swp): + os.rename(dry_run_db_swp, dry_run_db) + + +def test_init_dry_run_without_db(default_conf, mocker): + default_conf.update({'dry_run_db': False}) + mocker.patch.dict('freqtrade.persistence._CONF', default_conf) + + # First, protect the existing 'tradesv3.dry_run.sqlite' (Do not delete user data) + dry_run_db = 'tradesv3.dry_run.sqlite' + dry_run_db_swp = dry_run_db + '.swp' + + if os.path.isfile(dry_run_db): + os.rename(dry_run_db, dry_run_db_swp) + + # Check if the new tradesv3.dry_run.sqlite was created + init(default_conf) + assert os.path.isfile(dry_run_db) is False + + # Rollback to the initial 'tradesv3.dry_run.sqlite' file + if os.path.isfile(dry_run_db_swp): + os.rename(dry_run_db_swp, dry_run_db) + + +def test_init_prod_db(default_conf, mocker): + default_conf.update({'dry_run': False}) + mocker.patch.dict('freqtrade.persistence._CONF', default_conf) + + # First, protect the existing 'tradesv3.sqlite' (Do not delete user data) + prod_db = 'tradesv3.sqlite' + prod_db_swp = prod_db + '.swp' + + if os.path.isfile(prod_db): + os.rename(prod_db, prod_db_swp) + + # Check if the new tradesv3.sqlite was created + init(default_conf) + assert os.path.isfile(prod_db) is True + + # Delete the file made for this unitest and rollback to the previous tradesv3.sqlite file + + # 1. Delete file from the test + if os.path.isfile(prod_db): + os.remove(prod_db) + + # Rollback to the initial 'tradesv3.sqlite' file + if os.path.isfile(prod_db_swp): + os.rename(prod_db_swp, prod_db) def test_update_with_bittrex(limit_buy_order, limit_sell_order): @@ -81,6 +164,19 @@ def test_calc_open_close_trade_price(limit_buy_order, limit_sell_order): assert trade.calc_profit_percent() == 0.06201057 +def test_calc_close_trade_price_exception(limit_buy_order): + trade = Trade( + pair='BTC_ETH', + stake_amount=0.001, + fee=0.0025, + exchange=Exchanges.BITTREX, + ) + + trade.open_order_id = 'something' + trade.update(limit_buy_order) + assert trade.calc_close_trade_price() == 0.0 + + def test_update_open_order(limit_buy_order): trade = Trade( pair='BTC_ETH',