You might have read a post from me once-or-twice where I've advocated using Python for quickly prototyping solutions, exploring data etc... But regardless of whether you're using it for building a quick prototype or create a larger application it is, as with all languages, best practice to write some unit tests. Like most languages there are a wide range of libraries for performing unit testing in Python but a great starting point (and maybe even a finishing point) is the unittest framework which comes as part of the standard library, providing unit testing and mocking capabilities. Of course once you then have your unit tests you can run them not only on your local development environment but also in your continuous integration environment. If you're a user of Visual Studio Code then there's pretty good integration thanks to the Python Extension provided by Microsoft. I'm a big fan of VSCode so that's what I'm using. There's a few conventions I tend to follow which make auto-discovery of tests a bit easier if you don't want to mess around with additional configuration settings. First name all test files as "*_test.py", you can use others but I tend to find this easier to follow and makes things clearer when there's a lot of files, the other part to this is using the name of the module as the prefix (e.g. a module called "demo.py" would have a test file of "demo_test.py"). The next is prefixing all test methods with "test_", this helps with auto_discovery but also helps me think about naming the method, such as "test_all_values_are_true". In VSCode you can can run all of your unit tests, simply open the command palette (SHIFT+CTRL+P on windows) and type in "Python run tests" to find the option.
The first time you do this you'll be walked through configuring your environment for tests, such as configuring the root folder, your test file naming convention etc... From there you can then run all (or some) of your tests.
For a quick walk-through I prepared a sample solution which looks as follows.
from math import ceil, sqrt from typing import Union, List def __check_is_prime(n:int): if n < 2: return False elif n == 2: return True if n % 2 == 0: return False for i in range(3, ceil(sqrt(n))+1, 2): if n % i == 0: return False return True def is_prime(n:Union[int, List[int]]): if type(n) is list: return [__check_is_prime(x) for x in n if type(x) is int] elif type(n) is int: return __check_is_prime(n) else: raise TypeError
There's some more that can be done to make this more python-esque but it serves the purpose. You can find the full code over on Github.
From this you can then run your tests as described above to run them all, or use the code-sense links to run individual tests or suites of tests.
Once up and running you can quickly see if you have any failed tests and re-run just the tests which have failed.
As with other features in VSCode if you get an error in the output then you can click the file location link to be taken straight to the line of code which failed, useful for larger projects.
If you're going to write tools and utilities in Python then backing them up with tests is always a great idea. Understanding what to test in Python as well is crucial as it's a duck-typed language, just because you intended for an integer to be passed to a method doesn't mean it actually will, even with type hints.