From 53b4c3722e46c5b6d00584fb0dd04c657cce9be3 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sat, 30 Sep 2017 20:38:19 +0300 Subject: [PATCH 01/11] convert asserts to pytest style --- freqtrade/tests/test_analyze.py | 16 +++++------ freqtrade/tests/test_main.py | 40 +++++++++++++-------------- freqtrade/tests/test_persistence.py | 8 +++--- freqtrade/tests/test_telegram.py | 42 ++++++++++++++--------------- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index d463ba560..74e945da2 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -24,28 +24,28 @@ class TestAnalyze(unittest.TestCase): self.result = parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00')) def test_1_dataframe_has_correct_columns(self): - self.assertEqual(self.result.columns.tolist(), - ['close', 'high', 'low', 'open', 'date', 'volume']) + assert self.result.columns.tolist() == \ + ['close', 'high', 'low', 'open', 'date', 'volume'] def test_2_orders_by_date(self): - self.assertEqual(self.result['date'].tolist(), + assert self.result['date'].tolist() == \ ['2017-08-30T10:34:00', '2017-08-30T10:37:00', '2017-08-30T10:40:00', - '2017-08-30T10:42:00']) + '2017-08-30T10:42:00'] def test_3_populates_buy_trend(self): dataframe = populate_buy_trend(populate_indicators(self.result)) - self.assertTrue('buy' in dataframe.columns) - self.assertTrue('buy_price' in dataframe.columns) + assert 'buy' in dataframe.columns + assert 'buy_price' in dataframe.columns def test_4_returns_latest_buy_signal(self): buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - self.assertEqual(get_buy_signal('BTC-ETH'), True) + assert get_buy_signal('BTC-ETH') == True buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - self.assertEqual(get_buy_signal('BTC-ETH'), False) + assert get_buy_signal('BTC-ETH') == False if __name__ == '__main__': diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index fc8d40c84..73bb153de 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -62,15 +62,15 @@ class TestMain(unittest.TestCase): trade = create_trade(15.0, exchange.Exchange.BITTREX) Trade.session.add(trade) Trade.session.flush() - self.assertIsNotNone(trade) - self.assertEqual(trade.open_rate, 0.072661) - self.assertEqual(trade.pair, pair) - self.assertEqual(trade.exchange, exchange.Exchange.BITTREX) - self.assertEqual(trade.amount, 206.43811673387373) - self.assertEqual(trade.stake_amount, 15.0) - self.assertEqual(trade.is_open, True) - self.assertIsNotNone(trade.open_date) - self.assertEqual(whitelist, self.conf['bittrex']['pair_whitelist']) + assert trade is not None + assert trade.open_rate == 0.072661 + assert trade.pair == pair + assert trade.exchange == exchange.Exchange.BITTREX + assert trade.amount == 206.43811673387373 + assert trade.stake_amount == 15.0 + assert trade.is_open == True + assert trade.open_date is not None + assert whitelist == self.conf['bittrex']['pair_whitelist'] buy_signal.assert_has_calls( [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] @@ -87,36 +87,36 @@ class TestMain(unittest.TestCase): }), buy=MagicMock(return_value='mocked_order_id')): trade = Trade.query.filter(Trade.is_open.is_(True)).first() - self.assertTrue(trade) + assert trade handle_trade(trade) - self.assertEqual(trade.close_rate, 0.17256061) - self.assertEqual(trade.close_profit, 137.4872490056564) - self.assertIsNotNone(trade.close_date) - self.assertEqual(trade.open_order_id, 'dry_run') + assert trade.close_rate == 0.17256061 + assert trade.close_profit == 137.4872490056564 + assert trade.close_date is not None + assert trade.open_order_id == 'dry_run' def test_3_close_trade(self): with patch.dict('freqtrade.main._CONF', self.conf): trade = Trade.query.filter(Trade.is_open.is_(True)).first() - self.assertTrue(trade) + assert trade # Simulate that there is no open order trade.open_order_id = None closed = close_trade_if_fulfilled(trade) - self.assertTrue(closed) - self.assertEqual(trade.is_open, False) + assert closed + assert trade.is_open == False def test_balance_fully_ask_side(self): with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): - self.assertEqual(get_target_bid({'ask': 20, 'last': 10}), 20) + assert get_target_bid({'ask': 20, 'last': 10}) == 20 def test_balance_fully_last_side(self): with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - self.assertEqual(get_target_bid({'ask': 20, 'last': 10}), 10) + assert get_target_bid({'ask': 20, 'last': 10}) == 10 def test_balance_when_last_bigger_than_ask(self): with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - self.assertEqual(get_target_bid({'ask': 5, 'last': 10}), 5) + assert get_target_bid({'ask': 5, 'last': 10}) == 5 @classmethod def setUpClass(cls): diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 4fd320b93..5b7c94989 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -18,10 +18,10 @@ class TestTrade(unittest.TestCase): ) profit = trade.exec_sell_order(1.00, 10.00) api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) - self.assertEqual(profit, 100.0) - self.assertEqual(trade.close_rate, 1.0) - self.assertEqual(trade.close_profit, profit) - self.assertIsNotNone(trade.close_date) + assert profit == 100.0 + assert trade.close_rate == 1.0 + assert trade.close_profit == profit + assert trade.close_date is not None if __name__ == '__main__': diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index af96a3045..f86090d35 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -63,13 +63,13 @@ class TestTelegram(unittest.TestCase): # Create some test data trade = create_trade(15.0, exchange.Exchange.BITTREX) - self.assertTrue(trade) + assert trade Trade.session.add(trade) Trade.session.flush() _status(bot=MagicBot(), update=self.update) - self.assertEqual(msg_mock.call_count, 2) - self.assertIn('[BTC_ETH]', msg_mock.call_args_list[-1][0][0]) + assert msg_mock.call_count == 2 + assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] def test_2_profit_handle(self): with patch.dict('freqtrade.main._CONF', self.conf): @@ -87,7 +87,7 @@ class TestTelegram(unittest.TestCase): # Create some test data trade = create_trade(15.0, exchange.Exchange.BITTREX) - self.assertTrue(trade) + assert trade trade.close_rate = 0.07256061 trade.close_profit = 100.00 trade.close_date = datetime.utcnow() @@ -97,8 +97,8 @@ class TestTelegram(unittest.TestCase): Trade.session.flush() _profit(bot=MagicBot(), update=self.update) - self.assertEqual(msg_mock.call_count, 2) - self.assertIn('(100.00%)', msg_mock.call_args_list[-1][0][0]) + assert msg_mock.call_count == 2 + assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] def test_3_forcesell_handle(self): with patch.dict('freqtrade.main._CONF', self.conf): @@ -116,16 +116,16 @@ class TestTelegram(unittest.TestCase): # Create some test data trade = create_trade(15.0, exchange.Exchange.BITTREX) - self.assertTrue(trade) + assert trade Trade.session.add(trade) Trade.session.flush() self.update.message.text = '/forcesell 1' _forcesell(bot=MagicBot(), update=self.update) - self.assertEqual(msg_mock.call_count, 2) - self.assertIn('Selling [BTC/ETH]', msg_mock.call_args_list[-1][0][0]) - self.assertIn('0.072561', msg_mock.call_args_list[-1][0][0]) + assert msg_mock.call_count == 2 + assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] + assert '0.072561' in msg_mock.call_args_list[-1][0][0] def test_4_performance_handle(self): with patch.dict('freqtrade.main._CONF', self.conf): @@ -143,7 +143,7 @@ class TestTelegram(unittest.TestCase): # Create some test data trade = create_trade(15.0, exchange.Exchange.BITTREX) - self.assertTrue(trade) + assert trade trade.close_rate = 0.07256061 trade.close_profit = 100.00 trade.close_date = datetime.utcnow() @@ -153,9 +153,9 @@ class TestTelegram(unittest.TestCase): Trade.session.flush() _performance(bot=MagicBot(), update=self.update) - self.assertEqual(msg_mock.call_count, 2) - self.assertIn('Performance', msg_mock.call_args_list[-1][0][0]) - self.assertIn('BTC_ETH 100.00%', msg_mock.call_args_list[-1][0][0]) + assert msg_mock.call_count == 2 + assert 'Performance' in msg_mock.call_args_list[-1][0][0] + assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] def test_5_start_handle(self): with patch.dict('freqtrade.main._CONF', self.conf): @@ -164,10 +164,10 @@ class TestTelegram(unittest.TestCase): init(self.conf, 'sqlite://') update_state(State.STOPPED) - self.assertEqual(get_state(), State.STOPPED) + assert get_state() == State.STOPPED _start(bot=MagicBot(), update=self.update) - self.assertEqual(get_state(), State.RUNNING) - self.assertEqual(msg_mock.call_count, 0) + assert get_state() == State.RUNNING + assert msg_mock.call_count == 0 def test_6_stop_handle(self): with patch.dict('freqtrade.main._CONF', self.conf): @@ -176,11 +176,11 @@ class TestTelegram(unittest.TestCase): init(self.conf, 'sqlite://') update_state(State.RUNNING) - self.assertEqual(get_state(), State.RUNNING) + assert get_state() == State.RUNNING _stop(bot=MagicBot(), update=self.update) - self.assertEqual(get_state(), State.STOPPED) - self.assertEqual(msg_mock.call_count, 1) - self.assertIn('Stopping trader', msg_mock.call_args_list[0][0][0]) + assert get_state() == State.STOPPED + assert msg_mock.call_count == 1 + assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] def setUp(self): self.update = Update(0) From 06ad311aa3e64bfe76967e3bdd050f1856d19a19 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 11:02:47 +0300 Subject: [PATCH 02/11] remove Test classes and use pytest fixtures --- freqtrade/tests/test_analyze.py | 52 +++--- freqtrade/tests/test_backtesting.py | 81 ++++---- freqtrade/tests/test_main.py | 139 +++++++------- freqtrade/tests/test_persistence.py | 38 ++-- freqtrade/tests/test_telegram.py | 280 ++++++++++++++-------------- 5 files changed, 288 insertions(+), 302 deletions(-) diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index 74e945da2..3f3c1610a 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -1,7 +1,7 @@ # pragma pylint: disable=missing-docstring -import unittest from unittest.mock import patch +import pytest import arrow from pandas import DataFrame @@ -19,34 +19,30 @@ RESULT_BITTREX = { ] } -class TestAnalyze(unittest.TestCase): - def setUp(self): - self.result = parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00')) +@pytest.fixture +def result(): + return parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00')) - def test_1_dataframe_has_correct_columns(self): - assert self.result.columns.tolist() == \ - ['close', 'high', 'low', 'open', 'date', 'volume'] +def test_1_dataframe_has_correct_columns(result): + assert result.columns.tolist() == \ + ['close', 'high', 'low', 'open', 'date', 'volume'] - def test_2_orders_by_date(self): - assert self.result['date'].tolist() == \ - ['2017-08-30T10:34:00', - '2017-08-30T10:37:00', - '2017-08-30T10:40:00', - '2017-08-30T10:42:00'] +def test_2_orders_by_date(result): + assert result['date'].tolist() == \ + ['2017-08-30T10:34:00', + '2017-08-30T10:37:00', + '2017-08-30T10:40:00', + '2017-08-30T10:42:00'] - def test_3_populates_buy_trend(self): - dataframe = populate_buy_trend(populate_indicators(self.result)) - assert 'buy' in dataframe.columns - assert 'buy_price' in dataframe.columns +def test_3_populates_buy_trend(result): + dataframe = populate_buy_trend(populate_indicators(result)) + assert 'buy' in dataframe.columns + assert 'buy_price' in dataframe.columns - def test_4_returns_latest_buy_signal(self): - buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == True - buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == False - - -if __name__ == '__main__': - unittest.main() +def test_4_returns_latest_buy_signal(): + buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) + with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): + assert get_buy_signal('BTC-ETH') == True + buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) + with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): + assert get_buy_signal('BTC-ETH') == False diff --git a/freqtrade/tests/test_backtesting.py b/freqtrade/tests/test_backtesting.py index ff8f8a039..fe69104ff 100644 --- a/freqtrade/tests/test_backtesting.py +++ b/freqtrade/tests/test_backtesting.py @@ -2,9 +2,9 @@ import json import logging import os -import unittest from unittest.mock import patch +import pytest import arrow from pandas import DataFrame @@ -12,6 +12,7 @@ from freqtrade.analyze import analyze_ticker from freqtrade.main import should_sell from freqtrade.persistence import Trade +logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot def print_results(results): print('Made {} buys. Average profit {:.2f}%. Total profit was {:.3f}. Average duration {:.1f} mins.'.format( @@ -21,9 +22,14 @@ def print_results(results): results.duration.mean()*5 )) -class TestMain(unittest.TestCase): - pairs = ['btc-neo', 'btc-eth', 'btc-omg', 'btc-edg', 'btc-pay', 'btc-pivx', 'btc-qtum', 'btc-mtl', 'btc-etc', 'btc-ltc'] - conf = { +@pytest.fixture +def pairs(): + return ['btc-neo', 'btc-eth', 'btc-omg', 'btc-edg', 'btc-pay', + 'btc-pivx', 'btc-qtum', 'btc-mtl', 'btc-etc', 'btc-ltc'] + +@pytest.fixture +def conf(): + return { "minimal_roi": { "60": 0.0, "40": 0.01, @@ -33,43 +39,40 @@ class TestMain(unittest.TestCase): "stoploss": -0.40 } - @classmethod - def setUpClass(cls): - logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot - @unittest.skipIf(not os.environ.get('BACKTEST', False), "slow, should be run manually") - def test_backtest(self): - trades = [] - with patch.dict('freqtrade.main._CONF', self.conf): - for pair in self.pairs: - with open('testdata/'+pair+'.json') as data_file: - data = json.load(data_file) +@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set") +def test_backtest(conf, pairs): + trades = [] + with patch.dict('freqtrade.main._CONF', conf): + for pair in pairs: + with open('tests/testdata/'+pair+'.json') as data_file: + data = json.load(data_file) - with patch('freqtrade.analyze.get_ticker', return_value=data): - with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')): - ticker = analyze_ticker(pair) - # for each buy point - for index, row in ticker[ticker.buy == 1].iterrows(): - trade = Trade( - open_rate=row['close'], - open_date=arrow.get(row['date']).datetime, - amount=1, - ) - # calculate win/lose forwards from buy point - for index2, row2 in ticker[index:].iterrows(): - if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): - current_profit = (row2['close'] - trade.open_rate) / trade.open_rate + with patch('freqtrade.analyze.get_ticker', return_value=data): + with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')): + ticker = analyze_ticker(pair) + # for each buy point + for index, row in ticker[ticker.buy == 1].iterrows(): + trade = Trade( + open_rate=row['close'], + open_date=arrow.get(row['date']).datetime, + amount=1, + ) + # calculate win/lose forwards from buy point + for index2, row2 in ticker[index:].iterrows(): + if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): + current_profit = (row2['close'] - trade.open_rate) / trade.open_rate - trades.append((pair, current_profit, index2 - index)) - break - - labels = ['currency', 'profit', 'duration'] - results = DataFrame.from_records(trades, columns=labels) + trades.append((pair, current_profit, index2 - index)) + break + + labels = ['currency', 'profit', 'duration'] + results = DataFrame.from_records(trades, columns=labels) - print('====================== BACKTESTING REPORT ================================') + print('====================== BACKTESTING REPORT ================================') - for pair in self.pairs: - print('For currency {}:'.format(pair)) - print_results(results[results.currency == pair]) - print('TOTAL OVER ALL TRADES:') - print_results(results) + for pair in pairs: + print('For currency {}:'.format(pair)) + print_results(results[results.currency == pair]) + print('TOTAL OVER ALL TRADES:') + print_results(results) diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 73bb153de..bb075aee0 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -1,7 +1,7 @@ -import unittest +import copy from unittest.mock import patch, MagicMock, call -import copy +import pytest from jsonschema import validate from freqtrade import exchange @@ -11,8 +11,9 @@ from freqtrade.misc import CONF_SCHEMA from freqtrade.persistence import Trade -class TestMain(unittest.TestCase): - conf = { +@pytest.fixture +def conf(): + configuration = { "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, @@ -42,86 +43,80 @@ class TestMain(unittest.TestCase): "chat_id": "chat_id" } } + validate(configuration, CONF_SCHEMA) + return configuration - def test_1_create_trade(self): - with patch.dict('freqtrade.main._CONF', self.conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: - with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - # Save state of current whitelist - whitelist = copy.deepcopy(self.conf['bittrex']['pair_whitelist']) - - init(self.conf, 'sqlite://') - for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: - trade = create_trade(15.0, exchange.Exchange.BITTREX) - Trade.session.add(trade) - Trade.session.flush() - assert trade is not None - assert trade.open_rate == 0.072661 - assert trade.pair == pair - assert trade.exchange == exchange.Exchange.BITTREX - assert trade.amount == 206.43811673387373 - assert trade.stake_amount == 15.0 - assert trade.is_open == True - assert trade.open_date is not None - assert whitelist == self.conf['bittrex']['pair_whitelist'] - - buy_signal.assert_has_calls( - [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] - ) - - def test_2_handle_trade(self): - with patch.dict('freqtrade.main._CONF', self.conf): +def test_1_create_trade(conf): + with patch.dict('freqtrade.main._CONF', conf): + with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): with patch.multiple('freqtrade.main.exchange', get_ticker=MagicMock(return_value={ - 'bid': 0.17256061, - 'ask': 0.172661, - 'last': 0.17256061 + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 }), buy=MagicMock(return_value='mocked_order_id')): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade - handle_trade(trade) - assert trade.close_rate == 0.17256061 - assert trade.close_profit == 137.4872490056564 - assert trade.close_date is not None - assert trade.open_order_id == 'dry_run' + # Save state of current whitelist + whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist']) - def test_3_close_trade(self): - with patch.dict('freqtrade.main._CONF', self.conf): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade + init(conf, 'sqlite://') + for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: + trade = create_trade(15.0, exchange.Exchange.BITTREX) + Trade.session.add(trade) + Trade.session.flush() + assert trade is not None + assert trade.open_rate == 0.072661 + assert trade.pair == pair + assert trade.exchange == exchange.Exchange.BITTREX + assert trade.amount == 206.43811673387373 + assert trade.stake_amount == 15.0 + assert trade.is_open == True + assert trade.open_date is not None + assert whitelist == conf['bittrex']['pair_whitelist'] - # Simulate that there is no open order - trade.open_order_id = None + buy_signal.assert_has_calls( + [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] + ) - closed = close_trade_if_fulfilled(trade) - assert closed - assert trade.is_open == False +def test_2_handle_trade(conf): + with patch.dict('freqtrade.main._CONF', conf): + with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): + with patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.17256061, + 'ask': 0.172661, + 'last': 0.17256061 + }), + buy=MagicMock(return_value='mocked_order_id')): + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade + handle_trade(trade) + assert trade.close_rate == 0.17256061 + assert trade.close_profit == 137.4872490056564 + assert trade.close_date is not None + assert trade.open_order_id == 'dry_run' - def test_balance_fully_ask_side(self): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 20 +def test_3_close_trade(conf): + with patch.dict('freqtrade.main._CONF', conf): + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade - def test_balance_fully_last_side(self): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 10 + # Simulate that there is no open order + trade.open_order_id = None - def test_balance_when_last_bigger_than_ask(self): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 5, 'last': 10}) == 5 + closed = close_trade_if_fulfilled(trade) + assert closed + assert trade.is_open == False - @classmethod - def setUpClass(cls): - validate(cls.conf, CONF_SCHEMA) +def test_balance_fully_ask_side(): + with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): + assert get_target_bid({'ask': 20, 'last': 10}) == 20 +def test_balance_fully_last_side(): + with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): + assert get_target_bid({'ask': 20, 'last': 10}) == 10 -if __name__ == '__main__': - unittest.main() +def test_balance_when_last_bigger_than_ask(): + with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): + assert get_target_bid({'ask': 5, 'last': 10}) == 5 diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 5b7c94989..eed6c1203 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,28 +1,22 @@ -import unittest from unittest.mock import patch from freqtrade.exchange import Exchange from freqtrade.persistence import Trade -class TestTrade(unittest.TestCase): - def test_1_exec_sell_order(self): - with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: - trade = Trade( - pair='BTC_ETH', - stake_amount=1.00, - open_rate=0.50, - amount=10.00, - exchange=Exchange.BITTREX, - open_order_id='mocked' - ) - profit = trade.exec_sell_order(1.00, 10.00) - api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) - assert profit == 100.0 - assert trade.close_rate == 1.0 - assert trade.close_profit == profit - assert trade.close_date is not None - - -if __name__ == '__main__': - unittest.main() +def test_1_exec_sell_order(): + with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: + trade = Trade( + pair='BTC_ETH', + stake_amount=1.00, + open_rate=0.50, + amount=10.00, + exchange=Exchange.BITTREX, + open_order_id='mocked' + ) + profit = trade.exec_sell_order(1.00, 10.00) + api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) + assert profit == 100.0 + assert trade.close_rate == 1.0 + assert trade.close_profit == profit + assert trade.close_date is not None diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index f86090d35..efc89ea25 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -1,7 +1,7 @@ -import unittest from datetime import datetime from unittest.mock import patch, MagicMock +import pytest from jsonschema import validate from telegram import Bot, Update, Message, Chat @@ -12,13 +12,9 @@ from freqtrade.persistence import Trade from freqtrade.rpc.telegram import _status, _profit, _forcesell, _performance, _start, _stop -class MagicBot(MagicMock, Bot): - pass - - -class TestTelegram(unittest.TestCase): - - conf = { +@pytest.fixture +def conf(): + configuration = { "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, @@ -46,150 +42,152 @@ class TestTelegram(unittest.TestCase): }, "initial_state": "running" } + validate(configuration, CONF_SCHEMA) + return configuration - def test_1_status_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(self.conf, 'sqlite://') +@pytest.fixture +def update(): + _update = Update(0) + _update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0)) + return _update - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() - _status(bot=MagicBot(), update=self.update) - assert msg_mock.call_count == 2 - assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] +class MagicBot(MagicMock, Bot): + pass - def test_2_profit_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(self.conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() - - _profit(bot=MagicBot(), update=self.update) - assert msg_mock.call_count == 2 - assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] - - def test_3_forcesell_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(self.conf, 'sqlite://') - - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() - - self.update.message.text = '/forcesell 1' - _forcesell(bot=MagicBot(), update=self.update) - - assert msg_mock.call_count == 2 - assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] - assert '0.072561' in msg_mock.call_args_list[-1][0][0] - - def test_4_performance_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(self.conf, 'sqlite://') - - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() - - _performance(bot=MagicBot(), update=self.update) - assert msg_mock.call_count == 2 - assert 'Performance' in msg_mock.call_args_list[-1][0][0] - assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] - - def test_5_start_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): +def test_1_status_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - init(self.conf, 'sqlite://') + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + with patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')): + init(conf, 'sqlite://') - update_state(State.STOPPED) - assert get_state() == State.STOPPED - _start(bot=MagicBot(), update=self.update) - assert get_state() == State.RUNNING - assert msg_mock.call_count == 0 + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() - def test_6_stop_handle(self): - with patch.dict('freqtrade.main._CONF', self.conf): + _status(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] + +def test_2_profit_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): - init(self.conf, 'sqlite://') + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + with patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')): + init(conf, 'sqlite://') - update_state(State.RUNNING) - assert get_state() == State.RUNNING - _stop(bot=MagicBot(), update=self.update) - assert get_state() == State.STOPPED - assert msg_mock.call_count == 1 - assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() - def setUp(self): - self.update = Update(0) - self.update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0)) + _profit(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] - @classmethod - def setUpClass(cls): - validate(cls.conf, CONF_SCHEMA) +def test_3_forcesell_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): + msg_mock = MagicMock() + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + with patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')): + init(conf, 'sqlite://') + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() + + update.message.text = '/forcesell 1' + _forcesell(bot=MagicBot(), update=update) + + assert msg_mock.call_count == 2 + assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] + assert '0.072561' in msg_mock.call_args_list[-1][0][0] + +def test_4_performance_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): + msg_mock = MagicMock() + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + with patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')): + init(conf, 'sqlite://') + + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() + + _performance(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert 'Performance' in msg_mock.call_args_list[-1][0][0] + assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] + +def test_5_start_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + msg_mock = MagicMock() + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + init(conf, 'sqlite://') + + update_state(State.STOPPED) + assert get_state() == State.STOPPED + _start(bot=MagicBot(), update=update) + assert get_state() == State.RUNNING + assert msg_mock.call_count == 0 + +def test_6_stop_handle(conf, update): + with patch.dict('freqtrade.main._CONF', conf): + msg_mock = MagicMock() + with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): + init(conf, 'sqlite://') + + update_state(State.RUNNING) + assert get_state() == State.RUNNING + _stop(bot=MagicBot(), update=update) + assert get_state() == State.STOPPED + assert msg_mock.call_count == 1 + assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] -if __name__ == '__main__': - unittest.main() From 9cca42e371ef2ca3d9f1c3b22a6135a2a14a697c Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 11:06:40 +0300 Subject: [PATCH 03/11] add pytest to requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index c6a1e399b..2cfc05081 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ scikit-learn==0.19.0 scipy==0.19.1 jsonschema==2.6.0 TA-Lib==0.4.10 +pytest==3.2.2 # Required for plotting data #matplotlib==2.0.2 From 616d5b61cc854b126f1398fc91ecb83a491e76dc Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 11:11:20 +0300 Subject: [PATCH 04/11] remove numbers from test method names --- freqtrade/tests/test_analyze.py | 8 ++++---- freqtrade/tests/test_main.py | 6 +++--- freqtrade/tests/test_persistence.py | 2 +- freqtrade/tests/test_telegram.py | 13 ++++++------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index 3f3c1610a..413390a31 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -23,23 +23,23 @@ RESULT_BITTREX = { def result(): return parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00')) -def test_1_dataframe_has_correct_columns(result): +def test_dataframe_has_correct_columns(result): assert result.columns.tolist() == \ ['close', 'high', 'low', 'open', 'date', 'volume'] -def test_2_orders_by_date(result): +def test_orders_by_date(result): assert result['date'].tolist() == \ ['2017-08-30T10:34:00', '2017-08-30T10:37:00', '2017-08-30T10:40:00', '2017-08-30T10:42:00'] -def test_3_populates_buy_trend(result): +def test_populates_buy_trend(result): dataframe = populate_buy_trend(populate_indicators(result)) assert 'buy' in dataframe.columns assert 'buy_price' in dataframe.columns -def test_4_returns_latest_buy_signal(): +def test_returns_latest_buy_signal(): buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): assert get_buy_signal('BTC-ETH') == True diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index bb075aee0..7e2b41932 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -46,7 +46,7 @@ def conf(): validate(configuration, CONF_SCHEMA) return configuration -def test_1_create_trade(conf): +def test_create_trade(conf): with patch.dict('freqtrade.main._CONF', conf): with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): @@ -79,7 +79,7 @@ def test_1_create_trade(conf): [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] ) -def test_2_handle_trade(conf): +def test_handle_trade(conf): with patch.dict('freqtrade.main._CONF', conf): with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): with patch.multiple('freqtrade.main.exchange', @@ -97,7 +97,7 @@ def test_2_handle_trade(conf): assert trade.close_date is not None assert trade.open_order_id == 'dry_run' -def test_3_close_trade(conf): +def test_close_trade(conf): with patch.dict('freqtrade.main._CONF', conf): trade = Trade.query.filter(Trade.is_open.is_(True)).first() assert trade diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index eed6c1203..19ff4df10 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -4,7 +4,7 @@ from freqtrade.exchange import Exchange from freqtrade.persistence import Trade -def test_1_exec_sell_order(): +def test_exec_sell_order(): with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: trade = Trade( pair='BTC_ETH', diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index efc89ea25..ef7b76868 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -56,7 +56,7 @@ class MagicBot(MagicMock, Bot): pass -def test_1_status_handle(conf, update): +def test_status_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() @@ -80,7 +80,7 @@ def test_1_status_handle(conf, update): assert msg_mock.call_count == 2 assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] -def test_2_profit_handle(conf, update): +def test_profit_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() @@ -109,7 +109,7 @@ def test_2_profit_handle(conf, update): assert msg_mock.call_count == 2 assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] -def test_3_forcesell_handle(conf, update): +def test_forcesell_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() @@ -136,7 +136,7 @@ def test_3_forcesell_handle(conf, update): assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] assert '0.072561' in msg_mock.call_args_list[-1][0][0] -def test_4_performance_handle(conf, update): +def test_performance_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): msg_mock = MagicMock() @@ -166,7 +166,7 @@ def test_4_performance_handle(conf, update): assert 'Performance' in msg_mock.call_args_list[-1][0][0] assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] -def test_5_start_handle(conf, update): +def test_start_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): msg_mock = MagicMock() with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): @@ -178,7 +178,7 @@ def test_5_start_handle(conf, update): assert get_state() == State.RUNNING assert msg_mock.call_count == 0 -def test_6_stop_handle(conf, update): +def test_stop_handle(conf, update): with patch.dict('freqtrade.main._CONF', conf): msg_mock = MagicMock() with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): @@ -190,4 +190,3 @@ def test_6_stop_handle(conf, update): assert get_state() == State.STOPPED assert msg_mock.call_count == 1 assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] - From add6c875d6316d7d5c3019eb30ea09b427021b1a Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 15:24:27 +0300 Subject: [PATCH 05/11] add pytest-mock to requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 2cfc05081..0d360c10b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,7 @@ scipy==0.19.1 jsonschema==2.6.0 TA-Lib==0.4.10 pytest==3.2.2 +pytest-mock==1.6.3 # Required for plotting data #matplotlib==2.0.2 From ff145b630608c025f956a63fa9a42988fab22ec4 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 15:25:10 +0300 Subject: [PATCH 06/11] use mocker for mocking to get rid of deep nesting --- freqtrade/tests/test_analyze.py | 13 +- freqtrade/tests/test_backtesting.py | 43 +++-- freqtrade/tests/test_main.py | 132 +++++++-------- freqtrade/tests/test_persistence.py | 34 ++-- freqtrade/tests/test_telegram.py | 238 ++++++++++++++-------------- 5 files changed, 228 insertions(+), 232 deletions(-) diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index 413390a31..48c46822f 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -1,6 +1,4 @@ # pragma pylint: disable=missing-docstring -from unittest.mock import patch - import pytest import arrow from pandas import DataFrame @@ -39,10 +37,11 @@ def test_populates_buy_trend(result): assert 'buy' in dataframe.columns assert 'buy_price' in dataframe.columns -def test_returns_latest_buy_signal(): +def test_returns_latest_buy_signal(mocker): buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == True + mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) + assert get_buy_signal('BTC-ETH') == True + buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) - with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): - assert get_buy_signal('BTC-ETH') == False + mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) + assert get_buy_signal('BTC-ETH') == False diff --git a/freqtrade/tests/test_backtesting.py b/freqtrade/tests/test_backtesting.py index fe69104ff..dcb572157 100644 --- a/freqtrade/tests/test_backtesting.py +++ b/freqtrade/tests/test_backtesting.py @@ -2,7 +2,6 @@ import json import logging import os -from unittest.mock import patch import pytest import arrow @@ -41,30 +40,30 @@ def conf(): @pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set") -def test_backtest(conf, pairs): +def test_backtest(conf, pairs, mocker): trades = [] - with patch.dict('freqtrade.main._CONF', conf): - for pair in pairs: - with open('tests/testdata/'+pair+'.json') as data_file: - data = json.load(data_file) + mocker.patch.dict('freqtrade.main._CONF', conf) + for pair in pairs: + with open('tests/testdata/'+pair+'.json') as data_file: + data = json.load(data_file) - with patch('freqtrade.analyze.get_ticker', return_value=data): - with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')): - ticker = analyze_ticker(pair) - # for each buy point - for index, row in ticker[ticker.buy == 1].iterrows(): - trade = Trade( - open_rate=row['close'], - open_date=arrow.get(row['date']).datetime, - amount=1, - ) - # calculate win/lose forwards from buy point - for index2, row2 in ticker[index:].iterrows(): - if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): - current_profit = (row2['close'] - trade.open_rate) / trade.open_rate + mocker.patch('freqtrade.analyze.get_ticker', return_value=data) + mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')) + ticker = analyze_ticker(pair) + # for each buy point + for index, row in ticker[ticker.buy == 1].iterrows(): + trade = Trade( + open_rate=row['close'], + open_date=arrow.get(row['date']).datetime, + amount=1, + ) + # calculate win/lose forwards from buy point + for index2, row2 in ticker[index:].iterrows(): + if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): + current_profit = (row2['close'] - trade.open_rate) / trade.open_rate - trades.append((pair, current_profit, index2 - index)) - break + trades.append((pair, current_profit, index2 - index)) + break labels = ['currency', 'profit', 'duration'] results = DataFrame.from_records(trades, columns=labels) diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 7e2b41932..8c881c9c8 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -1,5 +1,5 @@ import copy -from unittest.mock import patch, MagicMock, call +from unittest.mock import MagicMock, call import pytest from jsonschema import validate @@ -46,77 +46,77 @@ def conf(): validate(configuration, CONF_SCHEMA) return configuration -def test_create_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: - with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - # Save state of current whitelist - whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist']) +def test_create_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + buy_signal = mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + # Save state of current whitelist + whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist']) - init(conf, 'sqlite://') - for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: - trade = create_trade(15.0, exchange.Exchange.BITTREX) - Trade.session.add(trade) - Trade.session.flush() - assert trade is not None - assert trade.open_rate == 0.072661 - assert trade.pair == pair - assert trade.exchange == exchange.Exchange.BITTREX - assert trade.amount == 206.43811673387373 - assert trade.stake_amount == 15.0 - assert trade.is_open == True - assert trade.open_date is not None - assert whitelist == conf['bittrex']['pair_whitelist'] + init(conf, 'sqlite://') + for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']: + trade = create_trade(15.0, exchange.Exchange.BITTREX) + Trade.session.add(trade) + Trade.session.flush() + assert trade is not None + assert trade.open_rate == 0.072661 + assert trade.pair == pair + assert trade.exchange == exchange.Exchange.BITTREX + assert trade.amount == 206.43811673387373 + assert trade.stake_amount == 15.0 + assert trade.is_open == True + assert trade.open_date is not None + assert whitelist == conf['bittrex']['pair_whitelist'] - buy_signal.assert_has_calls( - [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] - ) + buy_signal.assert_has_calls( + [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')] + ) -def test_handle_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.17256061, - 'ask': 0.172661, - 'last': 0.17256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade - handle_trade(trade) - assert trade.close_rate == 0.17256061 - assert trade.close_profit == 137.4872490056564 - assert trade.close_date is not None - assert trade.open_order_id == 'dry_run' +def test_handle_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.17256061, + 'ask': 0.172661, + 'last': 0.17256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade + handle_trade(trade) + assert trade.close_rate == 0.17256061 + assert trade.close_profit == 137.4872490056564 + assert trade.close_date is not None + assert trade.open_order_id == 'dry_run' -def test_close_trade(conf): - with patch.dict('freqtrade.main._CONF', conf): - trade = Trade.query.filter(Trade.is_open.is_(True)).first() - assert trade +def test_close_trade(conf, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + trade = Trade.query.filter(Trade.is_open.is_(True)).first() + assert trade - # Simulate that there is no open order - trade.open_order_id = None + # Simulate that there is no open order + trade.open_order_id = None - closed = close_trade_if_fulfilled(trade) - assert closed - assert trade.is_open == False + closed = close_trade_if_fulfilled(trade) + assert closed + assert trade.is_open == False -def test_balance_fully_ask_side(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 20 +def test_balance_fully_ask_side(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}) + assert get_target_bid({'ask': 20, 'last': 10}) == 20 -def test_balance_fully_last_side(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 20, 'last': 10}) == 10 +def test_balance_fully_last_side(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}) + assert get_target_bid({'ask': 20, 'last': 10}) == 10 -def test_balance_when_last_bigger_than_ask(): - with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): - assert get_target_bid({'ask': 5, 'last': 10}) == 5 +def test_balance_when_last_bigger_than_ask(mocker): + mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}) + assert get_target_bid({'ask': 5, 'last': 10}) == 5 diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 19ff4df10..6015fe858 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,22 +1,20 @@ -from unittest.mock import patch - from freqtrade.exchange import Exchange from freqtrade.persistence import Trade -def test_exec_sell_order(): - with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: - trade = Trade( - pair='BTC_ETH', - stake_amount=1.00, - open_rate=0.50, - amount=10.00, - exchange=Exchange.BITTREX, - open_order_id='mocked' - ) - profit = trade.exec_sell_order(1.00, 10.00) - api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) - assert profit == 100.0 - assert trade.close_rate == 1.0 - assert trade.close_profit == profit - assert trade.close_date is not None +def test_exec_sell_order(mocker): + api_mock = mocker.patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') + trade = Trade( + pair='BTC_ETH', + stake_amount=1.00, + open_rate=0.50, + amount=10.00, + exchange=Exchange.BITTREX, + open_order_id='mocked' + ) + profit = trade.exec_sell_order(1.00, 10.00) + api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) + assert profit == 100.0 + assert trade.close_rate == 1.0 + assert trade.close_profit == profit + assert trade.close_date is not None diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index ef7b76868..c054b8994 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -1,5 +1,5 @@ from datetime import datetime -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock import pytest from jsonschema import validate @@ -56,137 +56,137 @@ class MagicBot(MagicMock, Bot): pass -def test_status_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_status_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() - _status(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] + _status(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] -def test_profit_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_profit_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() - _profit(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] + _profit(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert '(100.00%)' in msg_mock.call_args_list[-1][0][0] -def test_forcesell_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_forcesell_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + Trade.session.add(trade) + Trade.session.flush() - update.message.text = '/forcesell 1' - _forcesell(bot=MagicBot(), update=update) + update.message.text = '/forcesell 1' + _forcesell(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] - assert '0.072561' in msg_mock.call_args_list[-1][0][0] + assert msg_mock.call_count == 2 + assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] + assert '0.072561' in msg_mock.call_args_list[-1][0][0] -def test_performance_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - with patch.multiple('freqtrade.main.exchange', - get_ticker=MagicMock(return_value={ - 'bid': 0.07256061, - 'ask': 0.072661, - 'last': 0.07256061 - }), - buy=MagicMock(return_value='mocked_order_id')): - init(conf, 'sqlite://') +def test_performance_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + mocker.patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + mocker.patch.multiple('freqtrade.main.exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.07256061, + 'ask': 0.072661, + 'last': 0.07256061 + }), + buy=MagicMock(return_value='mocked_order_id')) + init(conf, 'sqlite://') - # Create some test data - trade = create_trade(15.0, exchange.Exchange.BITTREX) - assert trade - trade.close_rate = 0.07256061 - trade.close_profit = 100.00 - trade.close_date = datetime.utcnow() - trade.open_order_id = None - trade.is_open = False - Trade.session.add(trade) - Trade.session.flush() + # Create some test data + trade = create_trade(15.0, exchange.Exchange.BITTREX) + assert trade + trade.close_rate = 0.07256061 + trade.close_profit = 100.00 + trade.close_date = datetime.utcnow() + trade.open_order_id = None + trade.is_open = False + Trade.session.add(trade) + Trade.session.flush() - _performance(bot=MagicBot(), update=update) - assert msg_mock.call_count == 2 - assert 'Performance' in msg_mock.call_args_list[-1][0][0] - assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] + _performance(bot=MagicBot(), update=update) + assert msg_mock.call_count == 2 + assert 'Performance' in msg_mock.call_args_list[-1][0][0] + assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0] -def test_start_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - init(conf, 'sqlite://') +def test_start_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + init(conf, 'sqlite://') - update_state(State.STOPPED) - assert get_state() == State.STOPPED - _start(bot=MagicBot(), update=update) - assert get_state() == State.RUNNING - assert msg_mock.call_count == 0 + update_state(State.STOPPED) + assert get_state() == State.STOPPED + _start(bot=MagicBot(), update=update) + assert get_state() == State.RUNNING + assert msg_mock.call_count == 0 -def test_stop_handle(conf, update): - with patch.dict('freqtrade.main._CONF', conf): - msg_mock = MagicMock() - with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock): - init(conf, 'sqlite://') +def test_stop_handle(conf, update, mocker): + mocker.patch.dict('freqtrade.main._CONF', conf) + msg_mock = MagicMock() + mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock) + init(conf, 'sqlite://') - update_state(State.RUNNING) - assert get_state() == State.RUNNING - _stop(bot=MagicBot(), update=update) - assert get_state() == State.STOPPED - assert msg_mock.call_count == 1 - assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] + update_state(State.RUNNING) + assert get_state() == State.RUNNING + _stop(bot=MagicBot(), update=update) + assert get_state() == State.STOPPED + assert msg_mock.call_count == 1 + assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] From 5551c9ec3bc0d22a8967adffcd35950cfa7c83da Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 15:40:40 +0300 Subject: [PATCH 07/11] add pragmas to disable pylint warnings for missing docstrings in test files --- freqtrade/tests/test_main.py | 1 + freqtrade/tests/test_persistence.py | 2 +- freqtrade/tests/test_telegram.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 8c881c9c8..38f60af43 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -1,3 +1,4 @@ +# pragma pylint: disable=missing-docstring import copy from unittest.mock import MagicMock, call diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 6015fe858..376825c72 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -1,7 +1,7 @@ +# pragma pylint: disable=missing-docstring from freqtrade.exchange import Exchange from freqtrade.persistence import Trade - def test_exec_sell_order(mocker): api_mock = mocker.patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') trade = Trade( diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py index c054b8994..cb67c8c79 100644 --- a/freqtrade/tests/test_telegram.py +++ b/freqtrade/tests/test_telegram.py @@ -1,3 +1,4 @@ +# pragma pylint: disable=missing-docstring from datetime import datetime from unittest.mock import MagicMock From 5537f0bf5b436016d582b7029940392ecadc1201 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 15:45:21 +0300 Subject: [PATCH 08/11] simplify unnecessary == True and == False assertions --- freqtrade/tests/test_analyze.py | 4 ++-- freqtrade/tests/test_main.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/tests/test_analyze.py b/freqtrade/tests/test_analyze.py index 48c46822f..e716eb3ad 100644 --- a/freqtrade/tests/test_analyze.py +++ b/freqtrade/tests/test_analyze.py @@ -40,8 +40,8 @@ def test_populates_buy_trend(result): def test_returns_latest_buy_signal(mocker): buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) - assert get_buy_signal('BTC-ETH') == True + assert get_buy_signal('BTC-ETH') buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) mocker.patch('freqtrade.analyze.analyze_ticker', return_value=buydf) - assert get_buy_signal('BTC-ETH') == False + assert not get_buy_signal('BTC-ETH') diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 38f60af43..eb87de1e3 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -72,7 +72,7 @@ def test_create_trade(conf, mocker): assert trade.exchange == exchange.Exchange.BITTREX assert trade.amount == 206.43811673387373 assert trade.stake_amount == 15.0 - assert trade.is_open == True + assert trade.is_open assert trade.open_date is not None assert whitelist == conf['bittrex']['pair_whitelist'] @@ -108,7 +108,7 @@ def test_close_trade(conf, mocker): closed = close_trade_if_fulfilled(trade) assert closed - assert trade.is_open == False + assert not trade.is_open def test_balance_fully_ask_side(mocker): mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}) From 17e8bbacc3ee72b3bd51f58afe288aacd88ee149 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 16:17:27 +0300 Subject: [PATCH 09/11] add pytest-mock to setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2d8d40990..2cd551cb2 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup(name='freqtrade', packages=['freqtrade'], scripts=['bin/freqtrade'], setup_requires=['pytest-runner'], - tests_require=['pytest'], + tests_require=['pytest', 'pytest-mock'], install_requires=[ 'python-bittrex==0.1.3', 'SQLAlchemy==1.1.13', From 02673b94dd875d626c9b4c7818dd51fe70046f35 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 17:04:38 +0300 Subject: [PATCH 10/11] use explicit package name for pytest running --- setup.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 6a53971b3..669531eec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,4 @@ [aliases] -test=pytest +test=pytest --pyargs freqtrade + From ea62c49c3a77e1d5237463d579ae1ecb51005354 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 1 Oct 2017 17:19:14 +0300 Subject: [PATCH 11/11] fix passing parameters to pytest --- setup.cfg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 669531eec..c5d8a376a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,5 @@ [aliases] -test=pytest --pyargs freqtrade - +test=pytest +[tool:pytest] +addopts = --pyargs freqtrade