frank.hsueh
frank.hsueh

Reputation: 311

python - unittest - ImportError: Start directory is not importable

I'm following python unittest to make some test and use discover function to pack tests to a suite. However when I try to run the test with unittest, I get this error:

Traceback (most recent call last):
   File "D:/Project/run_tests.py", line 12, in <module>
     suite2 = unittest.defaultTestLoader.discover(dir2, pattern='test*.py')
   File "C:\Python\Python36-32\lib\unittest\loader.py", line 338, in discover
     raise ImportError('Start directory is not importable: %r' % start_dir)
ImportError: Start directory is not importable: 'D:\\Project\\dir2'

This is how the run_tests.py looks like:

import unittest

if __name__ == "__main__":

    dir1 = "./test1"
    suite1 = unittest.defaultTestLoader.discover(dir1, pattern='test*.py')
    runner1 = unittest.TextTestRunner()
    runner1.run(suite1)


    dir2 = "./tes2"
    suite2 = unittest.defaultTestLoader.discover(dir2, pattern='test*.py')
    runner2 = unittest.TextTestRunner()
    runner2.run(suite2)

Upvotes: 31

Views: 36322

Answers (5)

Babar-Baig
Babar-Baig

Reputation: 779

It seems many different issues can produce this error message. If using PyCharm, be sure to check the top-right of the IDE for any errors flagged, and resolve them first.
My project directory structure is:

root
|- src
|-- __init__.py  # empty
|-- py1.py
|- tests
|-- test_py1.py

I then successfully ran the following command from the root directory:

$ python -m unittest discover -s tests

Out of curiosity, I also ran the following more descriptive command:

$ python -m unittest discover -s tests -t src

Expected it to work as well, but it failed with error:

ImportError: Start directory is not importable: '...\\root\\tests'

Upvotes: -1

Andr&#233; M&#252;ller
Andr&#233; M&#252;ller

Reputation: 117

That issue always occurs to me regularly in my python projects using PyCharm/IntelliJ. So I needed to combine both hints above in order to get it running on my platform (usually Linux). So I got it up and running with the following steps:

  1. Create an empty __init__.py in my unit testing directory.
  2. Refer to the origin of the symbolically linked directory such that PyCharm is just working on the native directory.
  3. Mark the unit testing directory as Test Sources Root in PyCharm.
  4. Mark the referenced Python codes used by the unit tests as Sources Root

When referring to a symbolically linked directory the following error occurred when trying to run the unit tests:

    Traceback (most recent call last):
      File "/home/z003yb2k/.IntelliJIdea2019.2/config/plugins/python/helpers/pycharm/_jb_unittest_runner.py", line 35, in 
        main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner, buffer=not JB_DISABLE_BUFFERING)
      File "/usr/lib/python3.7/unittest/main.py", line 100, in __init__
        self.parseArgs(argv)
      File "/usr/lib/python3.7/unittest/main.py", line 124, in parseArgs
        self._do_discovery(argv[2:])
      File "/usr/lib/python3.7/unittest/main.py", line 244, in _do_discovery
        self.createTests(from_discovery=True, Loader=Loader)
      File "/usr/lib/python3.7/unittest/main.py", line 154, in createTests
        self.test = loader.discover(self.start, self.pattern, self.top)
      File "/usr/lib/python3.7/unittest/loader.py", line 349, in discover
        tests = list(self._find_tests(start_dir, pattern))
      File "/usr/lib/python3.7/unittest/loader.py", line 387, in _find_tests
        name = self._get_name_from_path(start_dir)
      File "/usr/lib/python3.7/unittest/loader.py", line 371, in _get_name_from_path
        assert not _relpath.startswith('..'), "Path must be within the project"
    AssertionError: Path must be within the project

Upvotes: 2

joh-mue
joh-mue

Reputation: 1716

I had a very similar problem testing on CI Pipeline. In my case there was a level of indirection folder/topleveldirectory/tests

so I added -s to my unittest command:

python -m unittest discover -s folder/topleveldirectory/tests

Upvotes: 4

Douglas Liu
Douglas Liu

Reputation: 1702

Had a very similar error, but no symlink involves.

This is my directory layout.

- project root
  - foo
  - bar
  - test

foo and bar are considered top level packages, where test is all the test cases live.

When running unittest in intellij, I used the following parameters:

  • Target: Script path set to the test folder
  • Working directoy is the project root.

This setup gave me the Start directory is not importable error.

I traced the source in unittest.loader.py and realize it checks the test folder for __init__.py. So the solution is to add a __init__.py in my test folder. Hope this helps someone.

-- edit --

I'm on python 3.6, mac osx

Upvotes: 35

James Bradbury
James Bradbury

Reputation: 1768

There's a similar question with a helpful answer here.

However, this can happen if you're using an IDE like PyCharm in Linux and opening files in a soft-linked directory. It seems the editor which is running the tests gets confused about the two paths to the same module and says one doesn't exist. Putting it all in one location without any softlinks fixed this for me.

Upvotes: 3

Related Questions