Skip to content

Commit 90244b4

Browse files
committed
Added all code, unit tests, and a Github action to run the automated test workflow on push and on pull request events.
0 parents  commit 90244b4

File tree

8 files changed

+272
-0
lines changed

8 files changed

+272
-0
lines changed

.github/workflows/unittests.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Continuous Integration
2+
on: [push, pull_request]
3+
jobs:
4+
build:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v2
8+
- name: Set up Python
9+
uses: actions/setup-python@v2
10+
with:
11+
python-version: 3.10.0
12+
architecture: x64
13+
- name: Install dependencies
14+
run: pip install -r requirements.txt
15+
- name: Run Tests
16+
run: python -m pytest

.gitignore

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.nox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
*.py,cover
50+
.hypothesis/
51+
.pytest_cache/
52+
cover/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
.pybuilder/
76+
target/
77+
78+
# Jupyter Notebook
79+
.ipynb_checkpoints
80+
81+
# IPython
82+
profile_default/
83+
ipython_config.py
84+
85+
# pyenv
86+
# For a library or package, you might want to ignore these files since the code is
87+
# intended to run in multiple environments; otherwise, check them in:
88+
# .python-version
89+
90+
# pipenv
91+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94+
# install all needed dependencies.
95+
#Pipfile.lock
96+
97+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
98+
__pypackages__/
99+
100+
# Celery stuff
101+
celerybeat-schedule
102+
celerybeat.pid
103+
104+
# SageMath parsed files
105+
*.sage.py
106+
107+
# Environments
108+
.env
109+
.venv
110+
env/
111+
venv/
112+
ENV/
113+
env.bak/
114+
venv.bak/
115+
116+
# Spyder project settings
117+
.spyderproject
118+
.spyproject
119+
120+
# Rope project settings
121+
.ropeproject
122+
123+
# mkdocs documentation
124+
/site
125+
126+
# mypy
127+
.mypy_cache/
128+
.dmypy.json
129+
dmypy.json
130+
131+
# Pyre type checker
132+
.pyre/
133+
134+
# pytype static type analyzer
135+
.pytype/
136+
137+
# Cython debug symbols
138+
cython_debug/

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# BankAccount
2+
This is an educational public repository to illustrate the power of automated testing through Github Actions.
3+
4+
# Run locally
5+
1. Set up Python virtual environment.
6+
```
7+
python -m venv venv
8+
```
9+
2. Install required dependencies.
10+
```
11+
pip install -r requirements.txt
12+
```
13+
3. Run unit tests.
14+
```
15+
python -m pytest
16+
```
17+
4. Run the app.
18+
```
19+
python app.py
20+
```

app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from flask import Flask, jsonify, request
2+
3+
app = Flask(__name__)
4+
5+
balance = 0
6+
7+
@app.route('/')
8+
def index():
9+
return jsonify({'balance': balance})
10+
11+
@app.route('/deposit')
12+
def deposit():
13+
global balance
14+
amount = request.args.get('amount')
15+
balance = balance + int(amount)
16+
return jsonify({'balance': balance})
17+
18+
@app.route('/withdraw')
19+
def withdraw():
20+
global balance
21+
amount = request.args.get('amount')
22+
if(int(amount) > balance):
23+
return jsonify({'balance': balance})
24+
balance = balance - int(amount)
25+
return jsonify({'balance': balance})
26+
27+
if __name__ == '__main__':
28+
app.run(debug=True)

requirements.txt

526 Bytes
Binary file not shown.

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
3+
from app import app as flask_app
4+
5+
6+
@pytest.fixture
7+
def app():
8+
yield flask_app
9+
10+
11+
@pytest.fixture
12+
def client(app):
13+
return app.test_client()

tests/test_app.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import json
2+
3+
def test_balance(app, client):
4+
del app
5+
res = client.get('/')
6+
assert res.status_code == 200
7+
expected = {'balance': 0}
8+
assert expected == json.loads(res.get_data(as_text=True))
9+
10+
def test_deposit(app, client):
11+
del app
12+
res = client.get('/deposit?amount=500')
13+
assert res.status_code == 200
14+
expected = {'balance': 500}
15+
assert expected == json.loads(res.get_data(as_text=True))
16+
17+
def test_deposit_2(app, client):
18+
del app
19+
res = client.get('/deposit?amount=300')
20+
assert res.status_code == 200
21+
expected = {'balance': 800}
22+
assert expected == json.loads(res.get_data(as_text=True))
23+
24+
def test_withdraw_1(app, client):
25+
del app
26+
res = client.get('/withdraw?amount=1000')
27+
assert res.status_code == 200
28+
expected = {'balance': 800}
29+
assert expected == json.loads(res.get_data(as_text=True))
30+
31+
def test_withdraw_2(app, client):
32+
del app
33+
res = client.get('/withdraw?amount=100')
34+
assert res.status_code == 200
35+
expected = {'balance': 700}
36+
assert expected == json.loads(res.get_data(as_text=True))
37+
38+
def test_deposit_3(app, client):
39+
del app
40+
res = client.get('/deposit?amount=500')
41+
assert res.status_code == 200
42+
expected = {'balance': 1200}
43+
assert expected == json.loads(res.get_data(as_text=True))
44+
45+
def test_withdraw_3(app, client):
46+
del app
47+
res = client.get('/withdraw?amount=1000')
48+
assert res.status_code == 200
49+
expected = {'balance': 200}
50+
assert expected == json.loads(res.get_data(as_text=True))
51+
52+
def test_balance_2(app, client):
53+
del app
54+
res = client.get('/')
55+
assert res.status_code == 200
56+
expected = {'balance': 200}
57+
assert expected == json.loads(res.get_data(as_text=True))

0 commit comments

Comments
 (0)