from yo_scottie_oh@lemmy.ml to python@programming.dev on 16 Apr 2024 18:08
https://lemmy.ml/post/14536670
Hello! I’m attempting to follow some tutorials on unit testing with Python. One of them is a video tutorial Unit Tests in Python on the Socratica channel. Everyone in the comments seems to be making out just fine, and I’m following the instructor’s directions to the letter, yet I get a different result. It’s driving me mad lol.
In the video, the instructor creates two text files, one called circles.py
in which she defines a function circle_area®
, and another called test_circles.py
in which she writes some unit tests. In my attempt to follow along, I’ve ended up with two files structured like so:
/home/yo_scottie_oh/Projects/PythonTutorials/Socratica/Circles ├── circles.py └── test_circles.py
circles.py
:
from math import pi def circle_area(r): return pi*(r**2) # Test function radii = [2, 0, -3, 2 + 5j, True, "radius"] message = "Area of circles with r = {radius} is {area}." for r in radii: A = circle_area(r) print(message.format(radius=r,area=A))
test_circles.py
:
import unittest from circles import circle_area from math import pi class TestCircleArea(unittest.TestCase): def test_area(self): # Test areas when radius >=0 self.assertAlmostEqual(circle_area(1),pi) self.assertAlmostEqual(circle_area(0),0) self.assertAlmostEqual(circle_area(2.1),pi*2.1**2)
Where I’m getting tripped up is at 4:32 in the video, the instructor says to run the unit tests by opening a shell, going to the directory that contains both the circles and test_circles modules, and issuing the following command: python -m unittest test_circles
.
Instructor’s result (it runs the unit test):
Ran 1 test in 0.000s OK
My result (it seems to execute circles.py
itself):
[yo_scottie_oh@nobara Circles]$ python -m unittest test_circles Area of circles with r = 2 is 12.566370614359172. Area of circles with r = 0 is 0.0. Area of circles with r = -3 is 28.274333882308138. Area of circles with r = (2+5j) is (-65.97344572538566+62.83185307179586j). Area of circles with r = True is 3.141592653589793. Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/lib64/python3.11/unittest/__main__.py", line 18, in <module> main(module=None) File "/usr/lib64/python3.11/unittest/main.py", line 101, in __init__ self.parseArgs(argv) File "/usr/lib64/python3.11/unittest/main.py", line 150, in parseArgs self.createTests() File "/usr/lib64/python3.11/unittest/main.py", line 161, in createTests self.test = self.testLoader.loadTestsFromNames(self.testNames, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/unittest/loader.py", line 232, in loadTestsFromNames suites = [self.loadTestsFromName(name, module) for name in names] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/unittest/loader.py", line 232, in <listcomp> suites = [self.loadTestsFromName(name, module) for name in names] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/unittest/loader.py", line 162, in loadTestsFromName module = __import__(module_name) ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/yo_scottie_oh/Projects/PythonTutorials/Socratica/Circles/test_circles.py", line 4, in <module> from circles import circle_area File "/home/yo_scottie_oh/Projects/PythonTutorials/Socratica/Circles/circles.py", line 14, in <module> A = circle_area(r) ^^^^^^^^^^^^^^ File "/home/yo_scottie_oh/Projects/PythonTutorials/Socratica/Circles/circles.py", line 6, in circle_area return pi*(r**2) ~^^~ TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int' [yo_scottie_oh@nobara Circles]$
I’ve been banging my head against the wall for hours now trying to figure out why when I execute the same command as the instructor, it appears to execute my Python scripts themselves instead of running the unit tests.
Other things I’ve tried:
I’ve read the Python documentation on unit testing. I tried adding this to the end of the test_circles.py document, but that did not change anything.
if __name__ == '__main__': unittest.main()
I’ve tried following this other written tutorial. After I create the text documents and organize them in the separate shapes and tests folders and run the command python -m unittest discover -v
, again I get a different result from the author.
Author’s result:
test_area (test_circle.TestCircle) ... ok test_circle_instance_of_shape (test_circle.TestCircle) ... ok test_create_circle_negative_radius (test_circle.TestCircle) ... ok test_area (test_square.TestSquare) ... ok test_create_square_negative_length (test_square.TestSquare) ... ok test_square_instance_of_shape (test_square.TestSquare) ... ok ---------------------------------------------------------------------- Ran 6 tests in 0.002s OK
My result:
[yo_scottie_oh@nobara test]$ python -m unittest discover -v test_circle (unittest.loader._FailedTest.test_circle) ... ERROR test_square (unittest.loader._FailedTest.test_square) ... ERROR ====================================================================== ERROR: test_circle (unittest.loader._FailedTest.test_circle) ---------------------------------------------------------------------- ImportError: Failed to import test module: test_circle Traceback (most recent call last): File "/usr/lib64/python3.11/unittest/loader.py", line 419, in _find_test_path module = self._get_module_from_name(name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/unittest/loader.py", line 362, in _get_module_from_name __import__(name) File "/home/yo_scottie_oh/Projects/PythonTutorials/PythonUnitTesting/test/test_circle.py", line 4, in <module> from shapes.circle import Circle ModuleNotFoundError: No module named 'shapes' ====================================================================== ERROR: test_square (unittest.loader._FailedTest.test_square) ---------------------------------------------------------------------- ImportError: Failed to import test module: test_square Traceback (most recent call last): File "/usr/lib64/python3.11/unittest/loader.py", line 419, in _find_test_path module = self._get_module_from_name(name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/unittest/loader.py", line 362, in _get_module_from_name __import__(name) File "/home/yo_scottie_oh/Projects/PythonTutorials/PythonUnitTesting/test/test_square.py", line 3, in <module> from shapes.square import Square ModuleNotFoundError: No module named 'shapes' ---------------------------------------------------------------------- Ran 2 tests in 0.000s FAILED (errors=2)
So yeah… this brings me to my question: What’s the obvious thing that everybody else gets that I’m missing? Is the tutorial outdated? Is it because the instructor is on Windows and I’m on Linux? Why won’t my unit tests run?
#python
threaded - newest
In the first one the tutorial expects you to just leave the function in circles.py, after you have create the separate unit test file.
On the second one, You are probably trying to run the tests while inside the “test” folder. You need to be in the project folder when running the
python -m unittest discover -v
Ah, gotcha. Rewatching the video, I see that I missed a vital clue at 2:20.
Yup, this was it.
Thank you so much!
When you
import circles
in the test file (even if you only selectcircles_area
) the circles file basically gets executed from top to bottom to run all definitions at the point of the import statement. This executes your for loop which fails, and the actual tests are never run. Just remove that loop in the circles module, and it should work.Yup, gotcha - this was it. Thank you!