Home > Net >  Pytest not able to run test where script A importing another script B in the same folder level as A
Pytest not able to run test where script A importing another script B in the same folder level as A

Time:01-12

I am trying to run the unit test using pytest in this project, here main_0.py is importing s3 file.

I am getting ModuleNotFoundError: no module named 's3'

Project Folder Structure

    some_project
    └───src
        ├───main
        │   └───lambda_function
        │       └───some
        │               main_0.py
        │               s3.py
        │
        └───test
            └───unittest
                └───lambda_function
                    └───some
                            test_main_0.py
                            test_s3.py

main_0.py

from s3 import PrintS3

def lambda_handler():
    obj = PrintS3()
    res = obj.print_txt()
    return res

s3.py

class PrintS3:
    def __init__(self) -> None:
        self.txt = "Hello"

    def print_txt(self):
        print(self.txt)
        return self.txt

test_main_0.py

import unittest

class TestSomeMain(unittest.TestCase):
    def test_main_0(self):
        from src.main.lambda_function.some.main_0 import lambda_handler
        res = lambda_handler()
        assert res == "Hello"

test_s3.py is empty.

I also tried adding an empty __init__.py file in both the dir but still the same error Project Folder Structure after adding __init__.py file

some_project
└───src
    ├───main
    │   └───lambda_function
    │       └───some
    │               main_0.py
    │               s3.py
    │               __init__.py
    │
    └───test
        └───unittest
            └───lambda_function
                └───some
                        test_main_0.py
                        test_s3.py
                        __init__.py

the command I am using to run pytest:

python -m pytest ./src/test

and I am inside some_project folder and also using main_0.py instead of main.py because to not get confused with main folder

Edit 2:

I am to run the test case successfully by adding sys.path in the test_main_0.py file but it is breaking linting and hinting in the code editor (vscode) it didn't broke the linting and hinting, both import statement works but is there any better way.

new test_main_0.py:

import unittest
import os
import sys

sys.path.append(os.path.abspath("./src/main/lambda_function/some/"))

class TestSomeMain(unittest.TestCase):
    def test_main_0(self):
        from src.main.lambda_function.some.main_0 import lambda_handler # this works
        from main_0 import lambda_handler # this also works but break linting and hinting in the code editor
        res = lambda_handler()
        assert res == "Hello"

CodePudding user response:

could you please try


    import os
    import sys
    sys.path.append(os.path.join(os.path.dirname(__file__), ".."))

    from some.s3 import PrintS3

    def lambda_handler():
        obj = PrintS3()
        res = obj.print_txt()
        return res

CodePudding user response:

I found a somewhat working solution.

added setUp() and tearDown() methods in the class for inserting and removing path in sys.path

path in sys.path is the location of the directory where the main_0.py and s3.py is located

import unittest
import os
import sys

class TestSomeMain(unittest.TestCase):
    def setUp(self) -> None:
        sys.path.insert(0, os.path.abspath("./src/main/lambda_function/some/"))
    
    def tearDown(self) -> None:
        sys.path.remove(os.path.abspath("./src/main/lambda_function/some/"))

    def test_main_0(self):
        from src.main.lambda_function.some.main_0 import lambda_handler
        res = lambda_handler()
        assert res == "Hello"

also update the test command in the terminal:

python -m pytest ./src/test/unittest/lambda_function/some --cov ./src/main/lambda_function/some --cov-report html
  • Related