Avoiding Filename Collisions

The utility of having __init__.py files in every test subdirectory of a project confused me for a long time. However, the difference between having these and not having these is simple. If you have __init__.py files in all of your test subdirectories, you can have the same test filename show up in multiple directories. If you don’t, you can’t. That’s it. That’s the effect on you.

Here’s an example. Directory a and b both have the file, test_foo.py. It doesn’t matter what these files have in them, but for this example, they look like this:

 def​ test_a():
 pass
 def​ test_b():
 pass

With a directory structure like this:

 dups
 ├── a
 │   └── test_foo.py
 └── b
  └── test_foo.py

These files don’t even have the same content, but it’s still mucked up. Running them individually will be fine, but running pytest from the dups directory won’t work:

 $ ​​cd​​ ​​/path/to/code/ch6/dups
 $ ​​pytest​​ ​​a
 ================== test session starts ==================
 collected 1 items
 
 a/test_foo.py .
 
 =============== 1 passed in 0.01 seconds ================
 $ ​​pytest​​ ​​b
 ================== test session starts ==================
 collected 1 items
 
 b/test_foo.py .
 
 =============== 1 passed in 0.01 seconds ================
 $ ​​pytest
 ================== test session starts ==================
 collected 1 items / 1 errors
 
 ======================== ERRORS =========================
 ____________ ERROR collecting b/test_foo.py _____________
 import file mismatch:
 imported module 'test_foo' has this __file__ attribute:
  /path/to/code/ch6/dups/a/test_foo.py
 which is not the same as the test file we want to collect:
  /path/to/code/ch6/dups/b/test_foo.py
 HINT: remove __pycache__ / .pyc files and/or use a unique basename
  for your test file modules
 !!!!!!!! Interrupted: 1 errors during collection !!!!!!!!
 ================ 1 error in 0.15 seconds ================

That error message doesn’t really make it clear what went wrong.

To fix this test, just add empty __init__.py files in the subdirectories. Here, the example directory dups_fixed is the same as dups, but with __init__.py files added:

 dups_fixed/
 ├── a
 │   ├── __init__.py
 │   └── test_foo.py
 └── b
  ├── __init__.py
  └── test_foo.py

Now, let’s try this again from the top level in dups_fixed:

 $ ​​cd​​ ​​/path/to/code/ch6/dups_fixed
 $ ​​pytest
 ================== test session starts ==================
 collected 2 items
 
 a/test_foo.py .
 b/test_foo.py .
 
 =============== 2 passed in 0.01 seconds ================

There, all better. You might say to yourself that you’ll never have duplicate filenames, so it doesn’t matter. That’s fine. But projects grow and test directories grow, and do you really want to wait until it happens to you before you fix it? I say just put those files in there as a habit and don’t worry about it again.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.100.237