The best solution in my opinion is to use the unittest command line interface which will add the directory to the sys.path so you don't have to (done in the TestLoader class).
For example for a directory structure like this:
new_project
βββ antigravity.py
βββ test_antigravity.py
You can just run:
$ cd new_project
$ python -m unittest test_antigravity
For a directory structure like yours:
new_project
βββ antigravity
β βββ __init__.py # make it a package
β βββ antigravity.py
βββ test
βββ __init__.py # also make test a package
βββ test_antigravity.py
And in the test modules inside the test package, you can import the antigravity package and its modules as usual:
# import the package
import antigravity
# import the antigravity module
from antigravity import antigravity
# or an object inside the antigravity module
from antigravity.antigravity import my_object
Running a single test module:
To run a single test module, in this case test_antigravity.py:
$ cd new_project
$ python -m unittest test.test_antigravity
Just reference the test module the same way you import it.
Running a single test case or test method:
Also you can run a single TestCase or a single test method:
$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method
Running all tests:
You can also use test discovery which will discover and run all the tests for you, they must be modules or packages named test*.py (can be changed with the -p, --pattern flag):
$ cd new_project
$ python -m unittest discover
$ # Also works without discover for Python 3
$ # as suggested by @Burrito in the comments
$ python -m unittest
This will run all the test*.py modules inside the test package.
Here you can find the updated official documentation of discovery.
The best solution in my opinion is to use the unittest command line interface which will add the directory to the sys.path so you don't have to (done in the TestLoader class).
For example for a directory structure like this:
new_project
βββ antigravity.py
βββ test_antigravity.py
You can just run:
$ cd new_project
$ python -m unittest test_antigravity
For a directory structure like yours:
new_project
βββ antigravity
β βββ __init__.py # make it a package
β βββ antigravity.py
βββ test
βββ __init__.py # also make test a package
βββ test_antigravity.py
And in the test modules inside the test package, you can import the antigravity package and its modules as usual:
# import the package
import antigravity
# import the antigravity module
from antigravity import antigravity
# or an object inside the antigravity module
from antigravity.antigravity import my_object
Running a single test module:
To run a single test module, in this case test_antigravity.py:
$ cd new_project
$ python -m unittest test.test_antigravity
Just reference the test module the same way you import it.
Running a single test case or test method:
Also you can run a single TestCase or a single test method:
$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method
Running all tests:
You can also use test discovery which will discover and run all the tests for you, they must be modules or packages named test*.py (can be changed with the -p, --pattern flag):
$ cd new_project
$ python -m unittest discover
$ # Also works without discover for Python 3
$ # as suggested by @Burrito in the comments
$ python -m unittest
This will run all the test*.py modules inside the test package.
Here you can find the updated official documentation of discovery.
I've had the same problem for a long time. What I recently chose is the following directory structure:
project_path
βββ Makefile
βββ src
β βββ script_1.py
β βββ script_2.py
β βββ script_3.py
βββ tests
βββ __init__.py
βββ test_script_1.py
βββ test_script_2.py
βββ test_script_3.py
and in the __init__.py script of the test folder, I write the following:
import os
import sys
PROJECT_PATH = os.getcwd()
SOURCE_PATH = os.path.join(
PROJECT_PATH,"src"
)
sys.path.append(SOURCE_PATH)
Super important for sharing the project is the Makefile, because it enforces running the scripts properly. Here is the command that I put in the Makefile:
run_tests:
python -m unittest discover .
The Makefile is important not just because of the command it runs but also because of where it runs it from. If you would cd in tests and do python -m unittest discover ., it wouldn't work because the init script in unit_tests calls os.getcwd(), which would then point to the incorrect absolute path (that would be appended to sys.path and you would be missing your source folder). The scripts would run since discover finds all the tests, but they wouldn't run properly. So the Makefile is there to avoid having to remember this issue.
I really like this approach because I don't have to touch my src folder, my unit tests or my environment variables and everything runs smoothly.
What is the best project structure for a Python application? - Stack Overflow
Arguments against separating `test` from `src` in a python package?
Need Help Structuring a Python Project with src and test directories
How to generate unit tests for Python using src and test folder structure (preferable with PyCharm integration)? - Stack Overflow
Doesn't too much matter. Whatever makes you happy will work. There aren't a lot of silly rules because Python projects can be simple.
/scriptsor/binfor that kind of command-line interface stuff/testsfor your tests/libfor your C-language libraries/docfor most documentation/apidocfor the Epydoc-generated API docs.
And the top-level directory can contain README's, Config's and whatnot.
The hard choice is whether or not to use a /src tree. Python doesn't have a distinction between /src, /lib, and /bin like Java or C has.
Since a top-level /src directory is seen by some as meaningless, your top-level directory can be the top-level architecture of your application.
/foo/bar/baz
I recommend putting all of this under the "name-of-my-product" directory. So, if you're writing an application named quux, the directory that contains all this stuff is named /quux.
Another project's PYTHONPATH, then, can include /path/to/quux/foo to reuse the QUUX.foo module.
In my case, since I use Komodo Edit, my IDE cuft is a single .KPF file. I actually put that in the top-level /quux directory, and omit adding it to SVN.
According to Jean-Paul Calderone's Filesystem structure of a Python project:
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
The Python Packaging Authority recommends separating the test directory from the src (source code) directory in a Python application:
https://packaging.python.org/en/latest/tutorials/packaging-projects/#creating-the-package-files
Personally, I have always preferred this approach of keeping tests outside the package rather than mixing them with the source code (tests in package).
However, in the interest of expanding my perspective and learning something new, I am open to exploring alternative viewpoints. What are the main arguments for including tests within the package itself?
Image taken from https://blog.ionelmc.ro/2014/05/25/python-packaging/I have several questions that relate to Python Packaging and project structure specifically...
I am going through Clean Code in Python and have been trying to implement a better structure in my own project but have been running into some issues separating tests and source files in python and have begun to second guess my overall structure.
My current structure is as follows
βββ pitches β βββ __init__.py β βββ src β β βββ __init__.py β β βββ error_dist.py β β βββ obvious_zones.py β β βββ pitch.py β β βββ pitch_zone_enums.py β β βββ zone.py β β βββ zones.py β βββ test β βββ __init__.py β βββ error_dist_test.py β βββ obvious_zones_test.py β βββ pitch_test.py β βββ test_config.py β βββ zone_test.py β βββ zones_test.py
Question 1: In /src I have certain files import other ones - for example, zones.py has from zone import Zone and my linter throws an error saying that it is unable to import zone, but when I run the actual zones.py file there is no error.
When I compare my code to ch02 examples from Clean Code in Python, I notice that no python file in the src folder actually imports sibling python files... (i.e. he does not have zones.py importing an object from zone.py)
Is my structure incorrect or is it fine to import sibling files? If so, why is my python linter indicating an unable to import error but my program runs successfully?
Question 2 I am unable to import files from src in my test folder. E.g. when I try and import obvious_zones in obvious_zones_test.py I do get a linter error AND when I run the obvious_zones_test.py file I get the error ModuleNotFoundError: No module named 'obvious_zone'
TLDR: Am I packaging and structuring my project correctly? How am I supposed to import from src directory into tests folder directory?
I pulled the code from Clean Code in Python onto my local and I actually get an error when I try to run his test individually. However, when I use the make test command everything works... Is anyone able to explain what is happening?
Link to the code I am talking about:
https://github.com/PacktPublishing/Clean-Code-in-Python-Second-Edition/tree/main/book/src/ch02
I can post images but for some reason `make test` works, but trying to run unittests individually fails because of import issues... Can anybody explain what is going on?