Skip to content

Commit

Permalink
Add data source tests to CI for MSN and Yahoo (closes #59) (#84)
Browse files Browse the repository at this point in the history
* Use a dataclass to represent company info.

* Rename test modules for PyTest to see them.

Instead of `python3 run_all_tests.py`, just `pytest` should suffice now.

* Test data obtained from MSN Money.

* Add a test for Yahoo! Finance.

Also: Fix current price condition in MSN Money.

* Update CI recipe to only run `pytest`.

* Prune logic not required to run the tests with PyTest.

With UnitTest, adding the module to import paths was mandatory.

PyTest runs fine without that, as long as the logic is organized into a
package.
  • Loading branch information
kocielnik authored Jul 28, 2024
1 parent f4d4f3c commit 76f7585
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 33 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,4 @@ jobs:
pip install pytest==8.2.1
pip install -e .
- name: Test with pytest
run: |
python run_all_tests.py && pytest
run: pytest
6 changes: 4 additions & 2 deletions isthisstockgood/Active/MSNMoney.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import json
import isthisstockgood.RuleOneInvestingCalculations as RuleOne



class MSNMoney:
# This key appears to be fixed? So we can use it for now /shrug
_API_KEY = '0QfOX3Vn51YCzitbLaRkTTBadtWpgTN8NZLW0C1SEM'
Expand Down Expand Up @@ -78,7 +80,7 @@ def parse_annual_report_data(self, content):
most_recent_statement = annual_statements[max(annual_statements.keys())]
if not most_recent_statement:
return
self.total_debt = str(float(most_recent_statement.get('longTermDebt', 0)))
self.total_debt = float(most_recent_statement.get('longTermDebt', 0))
self.shares_outstanding = float(most_recent_statement.get('sharesOutstanding', 0))

key_metrics = data.get('analysis', {}).get('keyMetrics', {})
Expand All @@ -92,7 +94,7 @@ def parse_ratios_data(self, content):
return False

self.name = json_content.get('displayName', '')
self.industy = json_content.get('industry', '')
self.industry = json_content.get('industry', '')

# PE Ratios
self._parse_pe_ratios(yearly_data)
Expand Down
28 changes: 28 additions & 0 deletions isthisstockgood/CompanyInfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from dataclasses import dataclass


@dataclass
class CompanyInfo:
ticker_symbol: str
name: str
description: str
industry: str
current_price: float
average_volume: float
market_cap: float
shares_outstanding: int
pe_high: float
pe_low: float
roic: float
roic_averages: [float]
equity: float
equity_growth_rates: [float]
free_cash_flow: float
free_cash_flow_growth_rates: [float]
revenue: float
revenue_growth_rates: [float]
eps: float
eps_growth_rates: [float]
debt_equity_ratio: float
last_year_net_income: float
total_debt: float
18 changes: 0 additions & 18 deletions run_all_tests.py

This file was deleted.

Empty file removed tests/__init__.py
Empty file.
70 changes: 70 additions & 0 deletions tests/test_DataSources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from isthisstockgood.CompanyInfo import CompanyInfo
from isthisstockgood.DataFetcher import DataFetcher


def test_msn_money():
test_ticker = 'MSFT'
test_name = 'Microsoft Corp'

data = get_msn_money_data(test_ticker)

assert data.ticker_symbol == test_ticker
assert data.name == test_name
assert data.description != ''
assert data.industry != ''
assert data.current_price > 0.0
assert data.average_volume > 0
assert data.market_cap > 0.0
assert data.shares_outstanding > 0
assert data.pe_high > 0.0
assert data.pe_low > 0.0
assert data.roic != []
assert data.roic_averages != []
assert data.equity != []
assert data.equity_growth_rates != []
assert data.free_cash_flow != []
assert data.free_cash_flow_growth_rates != []
assert data.revenue != []
assert data.revenue_growth_rates != []
assert data.eps != []
assert data.eps_growth_rates != []
assert data.debt_equity_ratio > 0.0
assert data.last_year_net_income > 0.0
assert data.total_debt >= 0.0

def test_yahoo():
test_ticker = 'MSFT'
test_name = 'Microsoft Corp'

data = get_yahoo_data(test_ticker)

assert data.ticker_symbol == test_ticker
assert float(data.five_year_growth_rate) > 0.0

def get_msn_money_data(ticker):
data_fetcher = DataFetcher()
data_fetcher.ticker_symbol = ticker

# Make all network request asynchronously to build their portion of
# the json results.
data_fetcher.fetch_msn_money_data()

# Wait for each RPC result before proceeding.
for rpc in data_fetcher.rpcs:
rpc.result()

return CompanyInfo(**vars(data_fetcher.msn_money))

def get_yahoo_data(ticker):
data_fetcher = DataFetcher()
data_fetcher.ticker_symbol = ticker

# Make all network request asynchronously to build their portion of
# the json results.
data_fetcher.fetch_yahoo_finance_analysis()

# Wait for each RPC result before proceeding.
for rpc in data_fetcher.rpcs:
rpc.result()

return data_fetcher.yahoo_finance_analysis
5 changes: 0 additions & 5 deletions tests/MSNMoney.py → tests/test_MSNMoney.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
"""Tests for the MSNMoney.py functions."""


import os
import sys
import unittest

app_path = os.path.join(os.path.dirname(__file__), "..", 'isthisstockgood')
sys.path.append(app_path)

from isthisstockgood.Active.MSNMoney import MSNMoney

class MSNMoneyTest(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
"""Tests for the app/RuleOneInvestingCalculations.py functions."""


import os
import sys
import unittest

app_path = os.path.join(os.path.dirname(__file__), "..", 'isthisstockgood')
sys.path.append(app_path)

import RuleOneInvestingCalculations as RuleOne
import isthisstockgood.RuleOneInvestingCalculations as RuleOne

class RuleOneInvestingCalculationsTest(unittest.TestCase):

Expand Down

0 comments on commit 76f7585

Please sign in to comment.