Attempted relative import with no known parent package when doing automated testing

Viewed 80

My simplified folder structure is:

projectroot/
 __init__.py
 src/
   __init__.py
   util.py
 tests/
   __init__.py
   test_util.py

In util.py I have the following function:

def build_format_string(date: bool = True, time: bool = True) -> str:
    format_str = ""
    if date: 
        format_str += "%Y-%m-%d"
    if time:
        if format_str[-1] != " ":
            format_str += " "
        format_str += "%H:%M:%S"
    return format_str

I have written the corresponding test_build_format_string function inside test_util.py as follows:

from ..src.util import build_format_string
import pytest 

@pytest.mark.parametrize('date, time, expected', [(True, True, "%Y-%m-%d %H:%M:%S")])
def test_build_format_string(date, time, expected):
    assert type(date) == bool , f"date arg of build_format_string must be boolean, not {type(date)}!"
    assert type(time) == bool , f"time arg of build_format_string must be boolean, not {type(time)}!"
    assert build_format_string(date, time) == expected,  f"""Result of build_format_string when called with date={date} and time={time} 
                                                             must be {expected}; got {build_format_string(date, time)} instead."""

When running the automated test from command line as python -m pytest test_util.py or py.test test_util.py, I get the attempted relative import beyond top-level package error message, while when running the test_util.py in debug mode in my code editor, I get a similar attempted relative import with no known parent package error.

I have already read through a bunch of SO comments on this very frequent error but I am now even more confused than before. In many, I read that __init__.py should be placed in every folder and subfolder but this is exactly what I have here; still, relative importing doesn't work. But without importing the function(s) located in src.util, I can't have my automated tests to run. How can I get this to work?

1 Answers

You are running the test script from inside its directory - python has no way of knowing this is part of a package. Try to cd to projectroot and from there:

$ python -m pytest -m tests.test_util # note no py
Related