1

I'm trying to run pytest on some functions I've written in Airflow. I'm using Python 3.8, btw.

The folder structure is

airflow
   -- dags
       -- includes
           -- common
               -- functions.py
   -- tests
       -- test_functions.py

I tried from includes.common.functions import functionA, functionB, but kept getting the error ModuleNotFoundError: No module named 'functions'.

If I try from dags.includes.common.functions import functionA, functionB, I get ModuleNotFoundError: No module named 'dags'.

I've tried python -m pytest tests in the airflow folder, same import error.

I'm not very familiar with importing modules, and would appreciate any help in how to solve this error.

Rayne
  • 14,247
  • 16
  • 42
  • 59

2 Answers2

1

You can use . to go one directory up to search for files. Use this import statement inside test_functions.py:

from ..dags.includes.common.functions import functionA, functionB

Also, every folder needs an empty __init.py__ file. Create them for the folders airflow, dags, includes, common and tests.

Joep
  • 788
  • 2
  • 8
  • 23
  • When I tried to run `pytest test_functions.py` in the `tests` folder, I get the error message `from ..dags.includes.common.functions import functionA, functionB ValueError: attempted relative import beyond top-level package` – Rayne Aug 03 '21 at 10:15
  • Could you try replacing `..` with a single `.` instead and share the results – Joep Aug 03 '21 at 11:37
  • I currently have empty `__init__.py` in `tests` and `common`, and I'm running `pytest test_functions.py` in the `tests` folder. With `..`, I get the `attempted relative import beyond top-level package` error. With `.`, I get `ModuleNotFoundError: No module named 'tests.dags'`. – Rayne Aug 04 '21 at 02:20
  • If I remove the `__init__.py` files, with both `..` and `.`, I get `ImportError: attempted relative import with no known parent package` – Rayne Aug 04 '21 at 02:23
  • Good that you mention `__init__.py`, please add it to every directory. – Joep Aug 04 '21 at 08:06
  • I should add `__init__.py` even in `includes` and `common` even though there are no `.py` files in them? – Rayne Aug 04 '21 at 15:27
  • Yes, you should. I believe they are used to mark mark directories. – Joep Aug 04 '21 at 18:45
  • I've added `__init__.py` to every subfolder, but still get a `attempted relative import beyond top-level package` with `..`. If this helps, I have `__name__=tests.test_functions | __package__=tests`. – Rayne Aug 05 '21 at 03:19
1

I added the following to my script, and was able to run pytest without the import errors.

import sys
sys.path.insert(0, '../dags/')

from includes.common.functions import functionA, functionB

I was also able to run it without any __init__.py in any of the folders.

This post helped me.

Rayne
  • 14,247
  • 16
  • 42
  • 59