-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sample code for the article on creating test with ChatGPT (#511)
* Sample code for the article on creating test with ChatGPT * Fix format issues * Fix format issues, round two * More fix attempts * More fixes * TR updates, first round * Fix linter issues * More linter issues * Update chatgpt-unit-tests-python/test_fizzbuzz_pytest.py Co-authored-by: Martin Breuss <[email protected]> --------- Co-authored-by: Martin Breuss <[email protected]> Co-authored-by: brendaweles <[email protected]> Co-authored-by: Geir Arne Hjelle <[email protected]>
- Loading branch information
1 parent
f5fd81e
commit 806f307
Showing
12 changed files
with
355 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Write Unit Tests for Your Python Code With ChatGPT | ||
|
||
This folder provides the code examples for the Real Python tutorial [Write Unit Tests for Your Python Code With ChatGPT](https://realpython.com/chatgpt-unit-tests-python/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from collections import Counter | ||
|
||
|
||
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: | ||
raise ValueError("Cannot divide by zero.") | ||
return x / y | ||
|
||
|
||
def mean(data): | ||
return sum(data) / len(data) | ||
|
||
|
||
def median(data): | ||
n = len(data) | ||
index = n // 2 | ||
if n % 2: | ||
return sorted(data)[index] | ||
return sum(sorted(data)[index - 1 : index + 1]) / 2 | ||
|
||
|
||
def mode(data): | ||
c = Counter(data) | ||
return [k for k, v in c.items() if v == c.most_common(1)[0][1]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
def fizzbuzz(number): | ||
if number % 15 == 0: | ||
return "fizz buzz" | ||
elif number % 3 == 0: | ||
return "fizz" | ||
elif number % 5 == 0: | ||
return "buzz" | ||
else: | ||
return number |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
def fizzbuzz(number): | ||
"""Solves the FizzBuzz problem. | ||
Return "fizz" for numbers divisible by 3, | ||
"buzz" for numbers divisible by 5, | ||
"fizz buzz" for numbers divisible by both, | ||
and the number itself otherwise. | ||
>>> fizzbuzz(3) | ||
'fizz' | ||
>>> fizzbuzz(5) | ||
'buzz' | ||
>>> fizzbuzz(15) | ||
'fizz buzz' | ||
>>> fizzbuzz(4) | ||
4 | ||
>>> fizzbuzz(30) | ||
'fizz buzz' | ||
>>> fizzbuzz(9) | ||
'fizz' | ||
>>> fizzbuzz(10) | ||
'buzz' | ||
""" | ||
|
||
if number % 15 == 0: | ||
return "fizz buzz" | ||
elif number % 3 == 0: | ||
return "fizz" | ||
elif number % 5 == 0: | ||
return "buzz" | ||
else: | ||
return number | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import pytest | ||
|
||
|
||
def in_interval(number: int, start: int, end: int) -> bool: | ||
return start <= number <= end | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"number, start, end, expected", | ||
[ | ||
(5, 1, 10, True), # Test case inside the interval | ||
(1, 1, 10, True), # Edge case: number equals start | ||
(10, 1, 10, True), # Edge case: number equals end | ||
(0, 1, 10, False), # Number below the interval | ||
(11, 1, 10, False), # Number above the interval | ||
(5, 5, 5, True), # Edge case: start equals end equals number | ||
(-1, -5, 5, True), # Test case with negative numbers | ||
(-6, -5, 5, False), # Number below the interval with negatives | ||
], | ||
) | ||
def test_in_interval(number, start, end, expected): | ||
assert in_interval(number, start, end) == expected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import pytest | ||
|
||
|
||
def is_prime(number: int) -> bool: | ||
if number <= 1: | ||
return False | ||
for i in range(2, int(number**0.5) + 1): | ||
if number % i == 0: | ||
return False | ||
return True | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"number, expected", | ||
[ | ||
(2, True), # Smallest prime | ||
(3, True), # Prime | ||
(4, False), # Composite (2*2) | ||
(5, True), # Prime | ||
(11, True), # Prime | ||
(12, False), # Composite (2*6) | ||
(13, True), # Prime | ||
(25, False), # Composite (5*5) | ||
(29, True), # Prime | ||
(1, False), # Not prime by definition | ||
(0, False), # Not prime | ||
(-1, False), # Negative number | ||
(-11, False), # Negative number | ||
], | ||
) | ||
def test_is_prime(number, expected): | ||
assert is_prime(number) == expected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import json | ||
|
||
|
||
class JSONReader: | ||
def __init__(self, filename): | ||
self.filename = filename | ||
|
||
def read(self): | ||
with open(self.filename, encoding="utf-8") as file: | ||
return json.load(file) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import unittest | ||
|
||
from calculations import add, divide, mean, median, mode, multiply, subtract | ||
|
||
|
||
class TestArithmeticOperations(unittest.TestCase): | ||
def test_add(self): | ||
self.assertEqual(add(10, 5), 15) | ||
self.assertEqual(add(-1, 1), 0) | ||
self.assertEqual(add(-1, -1), -2) | ||
|
||
def test_subtract(self): | ||
self.assertEqual(subtract(10, 5), 5) | ||
self.assertEqual(subtract(-1, 1), -2) | ||
self.assertEqual(subtract(-1, -1), 0) | ||
|
||
def test_multiply(self): | ||
self.assertEqual(multiply(10, 5), 50) | ||
self.assertEqual(multiply(-1, 1), -1) | ||
self.assertEqual(multiply(-1, -1), 1) | ||
|
||
def test_divide(self): | ||
self.assertEqual(divide(10, 5), 2) | ||
self.assertEqual(divide(-1, 1), -1) | ||
self.assertEqual(divide(-1, -1), 1) | ||
with self.assertRaises(ValueError): | ||
divide(10, 0) | ||
|
||
|
||
class TestStatisticalOperations(unittest.TestCase): | ||
def test_mean(self): | ||
self.assertEqual(mean([1, 2, 3, 4, 5]), 3) | ||
self.assertEqual(mean([1, 2, 3, 4, 5, 6]), 3.5) | ||
|
||
def test_median_odd(self): | ||
self.assertEqual(median([1, 3, 3, 6, 7, 8, 9]), 6) | ||
|
||
def test_median_even(self): | ||
self.assertEqual(median([1, 2, 3, 4, 5, 6, 8, 9]), 4.5) | ||
|
||
def test_median_unsorted(self): | ||
self.assertEqual(median([7, 1, 3, 3, 2, 6]), 3) | ||
|
||
def test_mode_single(self): | ||
self.assertEqual(mode([1, 2, 2, 3, 4, 4, 4, 5]), [4]) | ||
|
||
def test_mode_multiple(self): | ||
self.assertEqual(set(mode([1, 1, 2, 3, 4, 4, 5, 5])), {1, 4, 5}) | ||
|
||
|
||
def load_tests(loader, tests, pattern): | ||
suite = unittest.TestSuite() | ||
# suite.addTests(loader.loadTestsFromTestCase(TestArithmeticOperations)) | ||
suite.addTests(loader.loadTestsFromTestCase(TestStatisticalOperations)) | ||
return suite | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import pytest | ||
|
||
from fizzbuzz import fizzbuzz | ||
|
||
# def test_fizzbuzz_with_number_divisible_by_15(): | ||
# assert fizzbuzz(30) == "fizz buzz" | ||
|
||
|
||
# def test_fizzbuzz_with_number_divisible_by_3(): | ||
# assert fizzbuzz(9) == "fizz" | ||
|
||
|
||
# def test_fizzbuzz_with_number_divisible_by_5(): | ||
# assert fizzbuzz(10) == "buzz" | ||
|
||
|
||
# def test_fizzbuzz_with_number_not_divisible_by_3_or_5(): | ||
# assert fizzbuzz(4) == 4 | ||
|
||
|
||
# def test_fizzbuzz_with_zero(): | ||
# assert fizzbuzz(0) == "fizz buzz" | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"input,expected", | ||
[ | ||
(30, "fizz buzz"), # Divisible by 15 | ||
(9, "fizz"), # Divisible by 3 | ||
(10, "buzz"), # Divisible by 5 | ||
(4, 4), # Not divisible by 3 or 5 | ||
(0, "fizz buzz"), # Edge case: 0 (divisible by 15) | ||
(33, "fizz"), # Additional case: Divisible by 3 | ||
(55, "buzz"), # Additional case: Divisible by 5 | ||
(98, 98), # Additional case: Not divisible by 3 or 5 | ||
], | ||
) | ||
def test_fizzbuzz(input, expected): | ||
assert ( | ||
fizzbuzz(input) == expected | ||
), f"Expected {expected} for input {input}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import unittest | ||
|
||
from fizzbuzz import fizzbuzz | ||
|
||
|
||
class TestFizzBuzz(unittest.TestCase): | ||
def test_fizz(self): | ||
"""Test numbers divisible by 3 but not by 5""" | ||
self.assertEqual(fizzbuzz(3), "fizz") | ||
self.assertEqual(fizzbuzz(6), "fizz") | ||
self.assertNotEqual(fizzbuzz(15), "fizz") | ||
|
||
def test_buzz(self): | ||
"""Test numbers divisible by 5 but not by 3""" | ||
self.assertEqual(fizzbuzz(5), "buzz") | ||
self.assertEqual(fizzbuzz(10), "buzz") | ||
self.assertNotEqual(fizzbuzz(15), "buzz") | ||
|
||
def test_fizz_buzz(self): | ||
"""Test numbers divisible by both 3 and 5""" | ||
self.assertEqual(fizzbuzz(15), "fizz buzz") | ||
self.assertEqual(fizzbuzz(30), "fizz buzz") | ||
|
||
def test_neither(self): | ||
"""Test numbers not divisible by 3 or 5""" | ||
self.assertEqual(fizzbuzz(1), 1) | ||
self.assertEqual(fizzbuzz(2), 2) | ||
self.assertEqual(fizzbuzz(4), 4) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import json | ||
|
||
import pytest | ||
|
||
# Assuming JSONReader is defined in 'your_module.py' | ||
from readers import JSONReader | ||
|
||
|
||
@pytest.fixture | ||
def setup_json_file(tmp_path): | ||
# Create a temporary JSON file | ||
data = {"name": "John Doe", "age": 30} | ||
file_path = tmp_path / "test_data.json" | ||
with open(file_path, "w", encoding="utf-8") as file: | ||
json.dump(data, file) | ||
return file_path | ||
|
||
|
||
def test_read_json_correctly(setup_json_file): | ||
# Test that JSONReader reads the file correctly | ||
reader = JSONReader(setup_json_file) | ||
data = reader.read() | ||
assert data == { | ||
"name": "John Doe", | ||
"age": 30, | ||
}, "Should correctly read JSON content" | ||
|
||
|
||
def test_file_not_found(): | ||
# Test for handling of file not found exception | ||
reader = JSONReader("non_existent_file.json") | ||
with pytest.raises(FileNotFoundError): | ||
reader.read() | ||
|
||
|
||
# Additional tests can be added to cover more scenarios, | ||
# such as reading empty files, | ||
# files with invalid JSON content, etc. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import json | ||
import os | ||
import tempfile | ||
import unittest | ||
|
||
from readers import JSONReader | ||
|
||
|
||
class TestJSONReader(unittest.TestCase): | ||
def setUp(self): | ||
# Create a temporary file and write some JSON data to it | ||
self.temp_file, self.temp_file_path = tempfile.mkstemp(suffix=".json") | ||
self.test_data = {"name": "Test", "value": 123} | ||
with os.fdopen(self.temp_file, "w", encoding="utf-8") as file: | ||
json.dump(self.test_data, file) | ||
|
||
def tearDown(self): | ||
# Clean up by removing the temporary file | ||
os.remove(self.temp_file_path) | ||
|
||
def test_read_json(self): | ||
# Test reading the JSON data | ||
reader = JSONReader(self.temp_file_path) | ||
data = reader.read() | ||
self.assertEqual(data, self.test_data) | ||
|
||
def test_file_not_found(self): | ||
# Test file not found error handling | ||
reader = JSONReader("non_existent_file.json") | ||
with self.assertRaises(FileNotFoundError): | ||
_ = reader.read() | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |