1 - Setting and getting code coverage
Switch to a new branch
Pull the latest from main
and create a new branch step1
git checkout main
git pull
git checkout -b 'step1'
Add a calculator backend
Let's continue by adding in our calculator logic. Create the file api/calculator.py
with the following contents:
class Calculator:
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(x, y):
if y == 0:
return 'Cannot divide by 0'
return x * 1.0 / y
We are defining a Calculator
class that can add
, subtract
, multiply
, and divide
. Next, we are going to create a simple Flask server to run our calculator app. Create a file api/app.py
from flask import (
Flask,
request,
)
from api.calculator import Calculator
app = Flask(__name__)
@app.route('/api/add', methods=['POST'])
def add():
return operation('add', 2)
@app.route('/api/subtract', methods=['POST'])
def subtract():
return operation('subtract', 2)
@app.route('/api/multiply', methods=['POST'])
def multiply():
return operation('multiply', 2)
@app.route('/api/divide', methods=['POST'])
def divide():
return operation('divide', 2)
def operation(method, num_factors):
factors = []
if num_factors == 2:
factors.append(float(request.json.get('x')))
factors.append(float(request.json.get('y')))
return str(getattr(Calculator, method)(*factors))
The server accepts POST
requests to the /api/add
, /api/subtract
, /api/multiply
, and /api/divide
endpoints. It expects to receive JSON
values x
and y
as data.
Run the server
You can start the server by running
flask --app api/app run
You can test if the server is running by hitting one of the above endpoints. Try it by running the command below from a new terminal.
curl -d '{"x": 1, "y": 2}' -H 'Content-Type: application/json' http://127.0.0.1:5000/api/add
You can see that the server is adding 1
and 2
together and returning 3.0
Add backend tests
Let's add some tests for our calculator. Create a new directory tests
in api
and add a blank __init__.py
file and a test_calculator.py
file.
mkdir api/tests
touch api/tests/__init__.py
touch api/tests/test_calculator.py
Add this to test_calculator.py
.
from ..calculator import Calculator
def test_add():
assert Calculator.add(1, 2) == 3.0
assert Calculator.add(1.0, 2.0) == 3.0
assert Calculator.add(0, 2.0) == 2.0
assert Calculator.add(2.0, 0) == 2.0
assert Calculator.add(-4, 2.0) == -2.0
def test_subtract():
assert Calculator.subtract(1, 2) == -1.0
assert Calculator.subtract(2, 1) == 1.0
assert Calculator.subtract(1.0, 2.0) == -1.0
assert Calculator.subtract(0, 2.0) == -2.0
assert Calculator.subtract(2.0, 0.0) == 2.0
assert Calculator.subtract(-4, 2.0) == -6.0
def test_multiply():
assert Calculator.multiply(1, 2) == 2.0
assert Calculator.multiply(1.0, 2.0) == 2.0
assert Calculator.multiply(0, 2.0) == 0.0
assert Calculator.multiply(2.0, 0.0) == 0.0
assert Calculator.multiply(-4, 2.0) == -8.0
def test_divide():
assert Calculator.divide(1, 2) == 0.5
assert Calculator.divide(1.0, 2.0) == 0.5
assert Calculator.divide(0, 2.0) == 0
assert Calculator.divide(-4, 2.0) == -2.0
Run the tests and collect code coverage
To run tests in a terminal:
pytest
However, we are more curious about the code coverage of our calculator
class. We can use the command
pytest --cov api/
to show us coverage results. Doing this should give you a report that looks like
Name Stmts Miss Cover
--------------------------------------------------
api/__init__.py 0 0 100%
api/app.py 22 22 0%
api/calculator.py 11 1 91%
api/tests/__init__.py 0 0 100%
api/tests/test_calculator.py 25 0 100%
--------------------------------------------------
TOTAL 58 23 61%
Notice that api/app.py
isn’t covered, as we haven’t tested the Flask application, but our api/calculator.py
file is missing tests on one line of code.
Commit and merge your changes
You can commit this code by running
git add .
git commit -m 'step1: add calculator backend and tests'
git push origin step1
Create a merge request on GitLab and merge the changes.
When opening merge requests, be sure to select your own repository as the target branch, or set your project's default target branch
Updated 4 months ago