<div dir="ltr">If you have all of your tests under a "tests" directory separate from your source code, you generally don't need <font face="monospace">__init__.py</font> files. <div>The pytest book goes into more detail about it in chapter 6 under the section "Avoiding Filename Collisions".</div><div>If you have two test files, or think you might someday, that are the same name in different subdirectories, then the __init__.py technique is useful to remove the collision.</div><div>These files are empty.</div><div><br></div><div>So, under simple cases, you don't need __init__.py files.</div><div>If you have them, they won't hurt, and might help.</div><div><br></div><div>Hope this helps.</div><div>- brian</div><div><br></div><div>- Brian</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 28, 2019 at 4:52 AM Marius Gedminas <<a href="mailto:marius@gedmin.as">marius@gedmin.as</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi!<br>
<br>
On Tue, Aug 27, 2019 at 09:45:27PM -0700, Tony Cappellini wrote:<br>
> I’m new to using PyTest. I’ve got a very simple python file, and a very simple<br>
> test file for it.<br>
...<br>
<br>
> I’ve been having a problem getting a unittest to be able to access the file<br>
> it’s trying to test. I’m sure that I don’t have the correct directory<br>
> configuration, but at the same time, I’m not sure what the correct directory<br>
> configuration should be though.<br>
<br>
You have the simplest possible case: one code file, one test file. You<br>
don't need a directory structure at this point, just the two files:<br>
<br>
mycode.py<br>
tests.py<br>
<br>
inside your tests.py you can do<br>
<br>
import mycode<br>
<br>
def test_my_stuff():<br>
assert mycode.stuff(42) == 25 # etc.<br>
<br>
and you should be able to run the tests with<br>
<br>
pytest tests.py<br>
<br>
If you don't want to keep repeating 'tests.py' on the command line,<br>
create a pytest.ini with<br>
<br>
[pytest]<br>
testpaths = tests.py<br>
<br>
and then you can run just<br>
<br>
pytest<br>
<br>
That's it!<br>
<br>
I use this structure for a few of my small Python projects, e.g.<br>
<a href="https://github.com/mgedmin/ghcloneall" rel="noreferrer" target="_blank">https://github.com/mgedmin/ghcloneall</a><br>
<br>
<br>
> Page 25 of “Python Testing with PyTest refers to __init__.py files in the same<br>
> directory as the test files themselves.<br>
> <br>
> Under Project Structure, This website <br>
> [1]<a href="https://automationpanda.com/2017/03/14/python-testing-101-pytest/" rel="noreferrer" target="_blank">https://automationpanda.com/2017/03/14/python-testing-101-pytest/</a><br>
> <br>
> states that __init__.py files should NOT be in the same directory as the test<br>
> files.<br>
<br>
I've no idea why that page makes this claim. I have my tests in a<br>
package in <a href="https://github.com/mgedmin/pyspacewar" rel="noreferrer" target="_blank">https://github.com/mgedmin/pyspacewar</a>, and pytest has no<br>
trouble with that structure.<br>
<br>
> __init__.py files have always been the biggest headache for me, as I’ve never<br>
> been able to find a clear reference as to what should or shouldn’t be in those<br>
> files.<br>
> Why is it that some are empty, while others have tons of imports?<br>
<br>
I assume you know what they're for? If not, see the Python Tutorial<br>
section on packages: <a href="https://docs.python.org/3/tutorial/modules.html#packages" rel="noreferrer" target="_blank">https://docs.python.org/3/tutorial/modules.html#packages</a><br>
<br>
As for the contents, the short answer is: if you're not sure, keep<br>
__init__.py files empty. But if you feel like you want to put some code<br>
in there, there likely won't be any harm.<br>
<br>
> I would appreciate if someone could provide a reference as to how a PyTest<br>
> project should be structured, where __init__ files should and shouldn’t be,<br>
> along with their contents (if any).<br>
<br>
There's more than one common source layout, and which is best is a<br>
matter of opinion.<br>
<br>
<br>
The one I'm used to has a 'src/' directory at the top, and puts all the<br>
tests as subpackages inside the actual code tree. Like, imagine if the<br>
example I gave before grew and grew and became too big for a single<br>
source file:<br>
<br>
mycode.py<br>
tests.py<br>
pytest.ini<br>
setup.py<br>
tox.ini<br>
<br>
I've added a setup.py because you probably want to be able to pip<br>
install the thing, and pull it any dependencies it has. I've added a<br>
tox.ini because tox is a wonderful tool for automating the tests -- it<br>
creates virtualenvs for you so you get all the code and test<br>
dependencies without polluting your global Python installation and<br>
interfering with other projects.<br>
<br>
(For completeness, here's what a setup.py looks:<br>
<br>
from setuptools import setup<br>
setup(<br>
name='mycode',<br>
version=...,<br>
author=...,<br>
license=...,<br>
url=...,<br>
description=...,<br>
long_description=...,<br>
py_modules=['mycode'],<br>
)<br>
<br>
and here's tox.ini:<br>
<br>
[tox]<br>
envlist = py37<br>
<br>
[testenv]<br>
deps = pytest<br>
commands = pytest {posargs}<br>
<br>
)<br>
<br>
So, at this point splitting the code into several modules will result in<br>
<br>
src/<br>
mycode/<br>
__init__.py # maybe empty, maybe not<br>
things.py<br>
more_things.py<br>
tests/<br>
__init__.py # empty file<br>
test_mycode.py<br>
test_things.py<br>
test_more_things.py<br>
pytest.ini<br>
setup.py<br>
tox.ini<br>
<br>
Here each code module has a corresponding test module, for my own<br>
convenience: when I want to find the unit tests for a function<br>
mycode.things.do_x(), I'll know to look in mycode.tests.test_things<br>
for test functions called test_do_x (with optional suffixes if there's<br>
more than one test).<br>
<br>
To make this work, pytest.ini changes from<br>
<br>
[pytest]<br>
testpaths = tests.py<br>
<br>
to<br>
<br>
[pytest]<br>
testpaths = src<br>
<br>
and you can't run 'pytest' without arguments any more (because ./src is<br>
not in PYTHONPATH -- this is the downside of using a top-level 'src'<br>
subdirectory), but you can run 'tox' without arguments. tox.ini is<br>
unchanged, setup.py changes from using<br>
<br>
from setuptools import setup<br>
setup(<br>
...<br>
py_modules='mycode',<br>
)<br>
<br>
to<br>
<br>
from setuptools import setup, find_packages<br>
setup(<br>
...<br>
packages=find_packages('src'),<br>
package_dir={'': 'src'},<br>
)<br>
<br>
Now, if you want to continue to write code like<br>
<br>
from mycode import stuff<br>
<br>
then mycode/__init__.py will have to define the 'stuff' function, or<br>
import and re-export it like this:<br>
<br>
# mycode/__init__.py<br>
from .things import stuff # reexport<br>
<br>
But if you're fine requiring that all users of mycode change their code<br>
to do<br>
<br>
from mycode.things import stuff<br>
<br>
then mycode/__init__.py can be an empty file.<br>
<br>
<br>
Hope that helped!<br>
<br>
Marius Gedminas<br>
-- <br>
/*<br>
* The lockdep graph lock isn't locked while we expect it to<br>
* be, we're confused now, bye!<br>
*/<br>
_______________________________________________<br>
testing-in-python mailing list<br>
<a href="mailto:testing-in-python@lists.idyll.org" target="_blank">testing-in-python@lists.idyll.org</a><br>
<a href="http://lists.idyll.org/listinfo/testing-in-python" rel="noreferrer" target="_blank">http://lists.idyll.org/listinfo/testing-in-python</a><br>
</blockquote></div>