Skip to content

Commit b660f6b

Browse files
authored
Rework intro and Python testing content (#255)
* Rework intro slides of Chapter 5: Testing and CI * Revamp functions used in the Python test demo, and their corresponding tests * Rework unittest content and tests. Add mock testing to the demo * Rework tox and coverage * Refer to Git exercise in the intro to testing * Cut unnecessary things
1 parent 2cdc2d7 commit b660f6b

File tree

10 files changed

+260
-227
lines changed

10 files changed

+260
-227
lines changed

05_testing_and_ci/examples/python_testing/mean_data.csv

Lines changed: 0 additions & 2 deletions
This file was deleted.

05_testing_and_ci/examples/python_testing/operations.py

Lines changed: 97 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,109 @@
22
A set of mathematical operations.
33
"""
44

5-
6-
def find_max(data):
7-
"""
8-
Find maximum of all elements of a given list
9-
10-
Parameters
11-
----------
12-
data : list
13-
List of data. Elements are numbers
14-
15-
Returns
16-
-------
17-
find_max : float
18-
Maximum of list
19-
"""
20-
# Check that the input list has numbers
21-
for n in data:
22-
assert type(n) == int or type(n) == float
23-
24-
max_num = data[0] # Assume the first number is the maximum
25-
for n in data:
26-
if n > max_num:
27-
max_num = n
28-
29-
return max_num
30-
31-
32-
def find_mean(data):
33-
"""
34-
Find mean of all elements of a given list
35-
36-
Parameters
37-
----------
38-
data : list
39-
List of data. Elements are numbers
40-
41-
Returns
42-
-------
43-
float : float
44-
Mean of list
45-
"""
46-
# Check that the input list has numbers
47-
for n in data:
48-
assert type(n) == int or type(n) == float
49-
50-
return sum(data) / len(data)
5+
class MathOperations:
6+
7+
def __init__(self, data):
8+
self._data = data
9+
10+
def reorder_data(self):
11+
"""
12+
Reorder data in ascending order
13+
"""
14+
self._data.sort()
15+
16+
def find_max(self):
17+
"""
18+
Find maximum of all elements of a given list
19+
Parameters
20+
----------
21+
data : list
22+
List of data. Elements are numbers
23+
24+
Returns
25+
-------
26+
find_max : float
27+
Maximum of list
28+
"""
29+
# Check that the input list has numbers
30+
for n in self._data:
31+
assert type(n) == int or type(n) == float
32+
33+
max_num = self._data[0] # Assume the first number is the maximum
34+
for n in self._data:
35+
if n > max_num:
36+
max_num = n
37+
38+
return max_num
39+
40+
def find_median(self):
41+
"""
42+
Find median of all elements of a given list
43+
44+
Parameters
45+
----------
46+
data : list
47+
List of data. Elements are numbers
48+
49+
Returns
50+
-------
51+
float : float
52+
Median of list
53+
"""
54+
# Check that the input list has numbers
55+
for n in self._data:
56+
assert type(n) == int or type(n) == float
57+
58+
# Sort the data to find the median
59+
sorted_data = sorted(self._data)
60+
n = len(sorted_data)
61+
62+
# If odd number of elements, return the middle one
63+
if n % 2 == 1:
64+
return sorted_data[n // 2]
65+
# If even number of elements, return the average of the two middle ones
66+
else:
67+
mid1 = sorted_data[n // 2 - 1]
68+
mid2 = sorted_data[n // 2]
69+
return (mid1 + mid2) / 2
70+
71+
def find_mean(self):
72+
"""
73+
Find mean of all elements of a given list
74+
75+
Parameters
76+
----------
77+
data : list
78+
List of data. Elements are numbers
79+
80+
Returns
81+
-------
82+
float : float
83+
Mean of list
84+
"""
85+
# Check that the input list has numbers
86+
for n in self._data:
87+
assert type(n) == int or type(n) == float
88+
89+
total = sum(self._data)
90+
count = len(self._data)
91+
mean = total / count
92+
return mean
5193

5294

5395
def main():
54-
data = [5, 3, 14, 27, 4, 9]
96+
data = [5, 3, 14, 27, 4, 9, 53]
97+
98+
math_ops = MathOperations(data)
5599

56-
maximum = find_max(data)
100+
maximum = math_ops.find_max()
57101
print("Maximum of {} is {}".format(data, maximum))
58102

59-
mean = find_mean(data)
60-
print("Average of {} is {}".format(data, mean))
103+
median = math_ops.find_median()
104+
print("Median of {} is {}".format(data, median))
105+
106+
mean = math_ops.find_mean()
107+
print("Mean of {} is {}".format(data, mean))
61108

62109

63110
if __name__ == "__main__":
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1,17,18,32,43,167,209

05_testing_and_ci/examples/python_testing/test_operations.py

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,91 @@
22
Tests for mathematical operations functions.
33
"""
44

5-
from operations import find_max, find_mean
5+
from operations import MathOperations
66
import pytest
77
import csv
88

99

10+
@pytest.fixture
11+
def math_operations():
12+
"""
13+
Fixture for MathOperations class
14+
"""
15+
data = [43, 32, 167, 18, 1, 209, 17]
16+
return MathOperations(data)
17+
1018
# Unit test
11-
def test_find_max():
19+
def test_find_max(math_operations):
1220
"""
1321
Test operations.find_max
1422
"""
15-
# Fixture
16-
data = [43, 32, 167, 18, 1, 209]
17-
1823
# Expected result
1924
expected_max = 209
2025

2126
# Actual result
22-
actual_max = find_max(data)
27+
actual_max = math_operations.find_max()
2328

2429
# Test
2530
assert actual_max == expected_max
2631

32+
# Unit test
33+
def test_reorder_data(math_operations):
34+
"""
35+
Test operations.reorder_data
36+
"""
37+
# Expected result
38+
expected_data = [1, 17, 18, 32, 43, 167, 209]
39+
40+
# Actual result
41+
math_operations.reorder_data()
42+
actual_data = math_operations._data
43+
44+
# Test
45+
assert actual_data == expected_data
2746

2847
# Unit test
29-
def test_find_mean():
48+
def test_find_mean(math_operations):
3049
"""
3150
Test operations.find_mean
3251
"""
33-
# Fixture
34-
data = [43, 32, 167, 18, 1, 209]
35-
3652
# Expected result
37-
expected_mean = 78.33
38-
# expected_mean = pytest.approx(78.33, abs=0.01)
39-
53+
expected_mean = 69.57
54+
4055
# Actual result
41-
actual_mean = find_mean(data)
42-
56+
actual_mean = math_operations.find_mean()
57+
4358
# Test
4459
assert actual_mean == expected_mean
4560

46-
4761
# Integration test
48-
def test_mean_of_max():
49-
"""
50-
Test operations.find_max and operations.find_mean
62+
def test_find_median(math_operations):
5163
"""
52-
# Fixture
53-
data1 = [43, 32, 167, 18, 1, 209]
54-
data2 = [3, 13, 33, 23, 498]
55-
64+
Test operations.find_median
65+
"""
5666
# Expected result
57-
expected_mean_of_max = 353.5
58-
59-
maximum1 = find_max(data1)
60-
maximum2 = find_max(data2)
61-
67+
expected_median = 32
68+
6269
# Actual result
63-
actual_mean_of_max = find_mean([maximum1, maximum2])
70+
actual_median = math_operations.find_median()
6471

6572
# Test
66-
assert actual_mean_of_max == expected_mean_of_max
73+
assert actual_median == expected_median
6774

6875

6976
# Regression test
70-
def test_regression_mean():
77+
def test_reg_reorder_data(math_operations):
7178
"""
72-
Test operations.find_mean on a previously generated dataset
79+
Test operations.reorder_data with data from CSV file
7380
"""
74-
with open("mean_data.csv") as f:
81+
with open("reordered_data.csv") as f:
7582
rows = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC)
76-
# Fixture
77-
data = next(rows)
78-
79-
# Expected result
80-
reference_mean = next(rows)
83+
84+
for row in rows:
85+
expected_reordered_data = row
8186

8287
# Actual result
83-
actual_mean = find_mean(data)
84-
85-
expected_mean = pytest.approx(reference_mean[0], abs=0.01)
86-
88+
math_operations.reorder_data()
89+
actual_reordered_data = math_operations._data
90+
8791
# Test
88-
assert actual_mean == expected_mean
92+
assert actual_reordered_data == expected_reordered_data

0 commit comments

Comments
 (0)