Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SystemError: Parent module '' not loaded, cannot perform relative import #67

Open
evandrocoan opened this issue Dec 4, 2017 · 18 comments

Comments

@evandrocoan
Copy link
Contributor

evandrocoan commented Dec 4, 2017

I had imported another test file, in one (main) test file like this:

from .text_extraction_unit_tests import PrefixStrippingViewUnitTests
wrap_plus_module = sys.modules["Wrap Plus.wrap_plus"]

def run_unit_tests(unit_tests_to_run=[]):
    runner = unittest.TextTestRunner()

    classes = \
    [
        PrefixStrippingViewUnitTests,
        SemanticLineWrapUnitTests,
        LineBalancingUnitTests,
    ]

    if len( unit_tests_to_run ) < 1:
        # Comment all the tests names on this list, to run all Unit Tests
        unit_tests_to_run = \
        [
            # "test_semantic_line_wrap_line_starting_with_comment",
            # "test_split_lines_with_trailing_new_line",
            # "test_split_lines_without_trailing_new_line",
            # "test_balance_characters_between_line_wraps_with_trailing_new_line",
            # "test_balance_characters_between_line_wraps_without_trailing_new_line",
            # "test_balance_characters_between_line_wraps_ending_with_long_word",
        ]

    runner.run( suite( classes, unit_tests_to_run ) )

def suite(classes, unit_tests_to_run):
    """
        Problem with sys.argv[1] when unittest module is in a script
        https://stackoverflow.com/questions/2812218/problem-with-sys-argv1-when-unittest-module

        Is there a way to loop through and execute all of the functions in a Python class?
        https://stackoverflow.com/questions/2597827/is-there-a-way-to-loop-through-and-execute

        looping over all member variables of a class in python
        https://stackoverflow.com/questions/1398022/looping-over-all-member-variables-of-a-class
    """
    suite = unittest.TestSuite()
    unit_tests_to_run_count = len( unit_tests_to_run )

    for _class in classes:
        _object = _class()

        for function_name in dir( _object ):

            if function_name.lower().startswith( "test" ):

                if unit_tests_to_run_count > 0 \
                        and function_name not in unit_tests_to_run:

                    continue

                suite.addTest( _class( function_name ) )

    return suite

Using this I can run the unit tests by my loader file inside the file Wrap Plus.wrap_plus:

def run_tests():
    """
        How do I unload (reload) a Python module?
        https://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module
    """
    print( "\n\n" )
    sublime_plugin.reload_plugin( "Wrap Plus.tests.text_extraction_unit_tests" )
    sublime_plugin.reload_plugin( "Wrap Plus.tests.semantic_linefeed_unit_tests" )
    sublime_plugin.reload_plugin( "Wrap Plus.tests.semantic_linefeed_manual_tests" )

    from .tests import semantic_linefeed_unit_tests

    # Comment all the tests names on this list, to run all Unit Tests
    unit_tests_to_run = \
    [
        # "test_semantic_line_wrap_ending_with_comma_list",
        # "test_is_command_separated_list_5_items",
        # "test_is_command_separated_list_4_items",
        # "test_is_command_separated_list_3_items",
        # "test_is_command_separated_list_2_items",
    ]

    semantic_linefeed_unit_tests.run_unit_tests( unit_tests_to_run )

def plugin_loaded():
    """
        Running single test from unittest.TestCase via command line
        https://stackoverflow.com/questions/15971735/running-single-test-from-unittest-testcase
    """
    run_tests()

And it successfully run I reload the Wrap Plus.wrap_plus file:

reloading plugin Wrap Plus.tests.text_extraction_unit_tests
reloading plugin Wrap Plus.tests.semantic_linefeed_unit_tests
reloading plugin Wrap Plus.tests.semantic_linefeed_manual_tests
...................................................
----------------------------------------------------------------------
Ran 51 tests in 0.601s

OK
reloading plugin Wrap Plus.wrap_plus

But when I use the UnitTesting command UnitTesting: Test Current Package, I got this error:

semantic_linefeed_unit_tests (unittest.loader.ModuleImportFailure) ... ERROR
test_double_quotes_wrappting (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_double_quotes_wrappting_without_leading_whitespace (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_comment (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_wrappting (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_wrappting_without_leading_whitespace (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok

======================================================================
ERROR: semantic_linefeed_unit_tests (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./python3.3/unittest/case.py", line 384, in _executeTestPart
  File "./python3.3/unittest/loader.py", line 32, in testFailure
ImportError: Failed to import test module: semantic_linefeed_unit_tests
Traceback (most recent call last):
  File "./python3.3/unittest/loader.py", line 261, in _find_tests
  File "./python3.3/unittest/loader.py", line 239, in _get_module_from_name
  File "D:\SublimeText\Data\Packages\Wrap Plus\tests\semantic_linefeed_unit_tests.py", line 11, in <module>
    from .text_extraction_unit_tests import PrefixStrippingViewUnitTests
SystemError: Parent module '' not loaded, cannot perform relative import


----------------------------------------------------------------------
Ran 6 tests in 0.544s

FAILED (errors=1)

UnitTesting: Done.
@evandrocoan
Copy link
Contributor Author

evandrocoan commented Dec 4, 2017

Changing the initial import structure from:

from .text_extraction_unit_tests import PrefixStrippingViewUnitTests
wrap_plus_module = sys.modules["Wrap Plus.wrap_plus"]

def run_unit_tests(unit_tests_to_run=[]):
    runner = unittest.TextTestRunner()

    classes = \
    [
        PrefixStrippingViewUnitTests,
        SemanticLineWrapUnitTests,
        LineBalancingUnitTests,
    ]
    ...

to:

wrap_plus_module = sys.modules["Wrap Plus.wrap_plus"]

def run_unit_tests(unit_tests_to_run=[]):
    runner = unittest.TextTestRunner()

    classes = \
    [
        sys.modules["Wrap Plus.tests.text_extraction_unit_tests"].PrefixStrippingViewUnitTests,
        SemanticLineWrapUnitTests,
        LineBalancingUnitTests,
    ]
    ...

Seems to solved the problem. Now all the Unit Tests ran with success:

...
text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok

----------------------------------------------------------------------
Ran 51 tests in 0.939s

OK

UnitTesting: Done.

evandrocoan referenced this issue in evandrocoan/WrapPlus Dec 4, 2017
SystemError: Parent module '' not loaded, cannot perform relative import
https://github.com/randy3k/UnitTesting/issues/67
evandrocoan referenced this issue in evandrocoan/ClearCursorsCarets Dec 6, 2017
issue:
SystemError: Parent module '' not loaded, cannot perform relative import
https://github.com/randy3k/UnitTesting/issues/67
@evandrocoan
Copy link
Contributor Author

I am not sure why, but I tried this fix on another package, and it did not worked. Then I searched and found this other solution by changing this:

class ClearCursorsCaretsLastSelectionUnitTests(sys.modules["ClearCursorsCarets.tests.utilities"].BasicSublimeTextViewTestCase):

To this:

import os
import sys
import importlib

CURRENT_DIRECTORY    = os.path.dirname( os.path.dirname( os.path.realpath( __file__ ) ) )
CURRENT_PACKAGE_NAME = os.path.basename( CURRENT_DIRECTORY ).rsplit('.', 1)[0]

utilities = importlib.import_module( CURRENT_PACKAGE_NAME + ".tests.utilities" )


class ClearCursorsCaretsLastSelectionUnitTests(utilities.BasicSublimeTextViewTestCase):

    def test_1_selections_at_first_word(self):
        pass

@randy3k
Copy link
Member

randy3k commented Dec 6, 2017

I am not sure what you want to achieve. You need to make sure that the tests are organized such as they could be discovered by discover.

@evandrocoan
Copy link
Contributor Author

evandrocoan commented Dec 6, 2017

They are being discovered, the error was the importing of helper functions/classes from helper files.

I had created an utilities.py to put common functions/classes through all my tests files on my package, but when was calling the UnitTesting package to run the tests, it could not import the functions from the utilities files. For example, given the following file structure:

$ tree
.
├── clear_cursors_carets.py
├── tests
│   ├── __init__.py
│   ├── clear_cursors_carets_first_selection_unit_tests.py
│   ├── clear_cursors_carets_last_selection_unit_tests.py
│   ├── unit_tests_runner.py
│   └── utilities.py
└── unittesting.json

On the file utitiles.py, I had the following class BasicSublimeTextViewTestCase extending unittest.TestCase:

import unittest
import textwrap

import sublime
import sublime_plugin


def wrap_text(text):
    return textwrap.dedent( text ).strip( " " ).strip( "\n" )


class BasicSublimeTextViewTestCase(unittest.TestCase):

    @classmethod
    def setUp(self):
        self.maxDiff = None

        # Create a new Sublime Text view to perform the Unit Tests
        self.view = sublime.active_window().new_file()
        self.view.set_syntax_file( "Packages/Text/Plain text.tmLanguage" )

        # make sure we have a window to work with
        settings = sublime.load_settings("Preferences.sublime-settings")
        settings.set("close_windows_when_empty", False)

    def tearDown(self):
        if self.view:
            self.view.set_scratch(True)
            self.view.window().focus_view(self.view)
            self.view.window().run_command("close_file")

    def setText(self, string, start_point=0):
        self.view.run_command("append", {"characters": wrap_text( string ) })

        selections = self.view.sel()
        selections.clear()
        selections.add( sublime.Region( start_point, start_point ) )

    def create_test_text(self, start_point):
        """
            1. (0, 4),
            2. (5, 9),
            3. (10, 14),
            4. (16, 20),
            5. (21, 25),
            6. (26, 30),
        """
        self.setText( """\
                word
                word
                word

                word
                word
                word""", start_point )


Then on my test files clear_cursors_carets_last_selection_unit_tests.py and clear_cursors_carets_first_selection_unit_tests.py, I would import the utilities module, so I can use it:

import sublime
import sublime_plugin

import os
import sys
import importlib

CURRENT_DIRECTORY    = os.path.dirname( os.path.dirname( os.path.realpath( __file__ ) ) )
CURRENT_PACKAGE_NAME = os.path.basename( CURRENT_DIRECTORY ).rsplit('.', 1)[0]

utilities = importlib.import_module( CURRENT_PACKAGE_NAME + ".tests.utilities" )


class ClearCursorsCaretsFirstSelectionUnitTests(utilities.BasicSublimeTextViewTestCase):

    def test_1_selections_at_first_word(self):
        self.create_test_text(0)
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "single_selection_first" )

        region = self.view.sel()[0]
        self.assertEqual( sublime.Region(0, 4), region )

    def test_2_selections_at_first_word(self):
        self.create_test_text(0)
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "single_selection_first" )

        region = self.view.sel()[0]
        self.assertEqual( sublime.Region(0, 4), region )

    def test_3_selections_at_first_word(self):
        self.create_test_text(0)
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "find_under_expand" )
        self.view.window().run_command( "single_selection_first" )

        region = self.view.sel()[0]
        self.assertEqual( sublime.Region(0, 4), region )



This was how I made it work. On the my first attempt, I was just trying to import utilities.py file on my test files clear_cursors_carets_first_selection_unit_tests.py and clear_cursors_carets_last_selection_unit_tests.py with:

from .utilities import BasicSublimeTextViewTestCase

But this was failing with:

SystemError: Parent module '' not loaded, cannot perform relative import

When I called the UnitTesting command UnitTesting: Test Current Package on a project file like clear_cursors_carets_last_selection_unit_tests.py.

But it was not falling when I used my own runner I already have setup. In addition to the UnitTesting package to run tests, I also had make my own runner on the file unit_tests_runner.py, so I can run individual Unit Tests and to be independent of the UnitTesting package to run tests.

import sys
import unittest

def run_unit_tests(unit_tests_to_run=[]):
    runner = unittest.TextTestRunner()

    classes = \
    [
        sys.modules["ClearCursorsCarets.tests.clear_cursors_carets_first_selection_unit_tests"].ClearCursorsCaretsFirstSelectionUnitTests,
        sys.modules["ClearCursorsCarets.tests.clear_cursors_carets_last_selection_unit_tests"].ClearCursorsCaretsLastSelectionUnitTests,
    ]

    if len( unit_tests_to_run ) < 1:

        # Comment all the tests names on this list, to run all Unit Tests
        unit_tests_to_run = \
        [
            # "test_semantic_line_wrap_line_starting_with_comment",
        ]

    runner.run( suite( classes, unit_tests_to_run ) )


def suite(classes, unit_tests_to_run):
    """
        Problem with sys.argv[1] when unittest module is in a script
        https://stackoverflow.com/questions/2812218/problem-with-sys-argv1-when-unittest-module-is-in-a-script

        Is there a way to loop through and execute all of the functions in a Python class?
        https://stackoverflow.com/questions/2597827/is-there-a-way-to-loop-through-and-execute-all-of-the-functions

        looping over all member variables of a class in python
        https://stackoverflow.com/questions/1398022/looping-over-all-member-variables-of-a-class-in-python
    """
    suite = unittest.TestSuite()
    unit_tests_to_run_count = len( unit_tests_to_run )

    for _class in classes:
        _object = _class()

        for function_name in dir( _object ):

            if function_name.lower().startswith( "test" ):

                if unit_tests_to_run_count > 0 \
                        and function_name not in unit_tests_to_run:

                    continue

                suite.addTest( _class( function_name ) )

    return suite


Then I can call this runner from my main application using this:

def run_tests():
    """
        How do I unload (reload) a Python module?
        https://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module
    """
    print( "\n\n" )
    sublime_plugin.reload_plugin( "ClearCursorsCarets.tests.unit_tests_runner" )
    sublime_plugin.reload_plugin( "ClearCursorsCarets.tests.utilities" )
    sublime_plugin.reload_plugin( "ClearCursorsCarets.tests.clear_cursors_carets_first_selection_unit_tests" )
    sublime_plugin.reload_plugin( "ClearCursorsCarets.tests.clear_cursors_carets_last_selection_unit_tests" )

    from .tests import unit_tests_runner

    # Comment all the tests names on this list, to run all Unit Tests
    unit_tests_to_run = \
    [
        # "test_2_selections_at_last_word",
        # "test_last_selection_with_6_selections_plus_redundant_expand_at_last_word",
    ]

    unit_tests_runner.run_unit_tests( unit_tests_to_run )


def plugin_loaded():
    """
        Running single test from unittest.TestCase via command line
        https://stackoverflow.com/questions/15971735/running-single-test-from-unittest-testcase-via-command-line
    """
    pass
    run_tests()

On the beginning I was only using my runner to run Unit Tests, but @ehuss asked to use the UnitTesting package to run the tests on a pull request to his repository, then since then I started adding it as compatible with the runners I was already using.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

Are you sure that the test cases are discoverable? AKAIK, unittest discover only search files named as test*.py.

EDIT: I saw that you have changed the pattern for discovery.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

I checked out your master branch: https://github.com/evandrocoan/Sublime-Wrap-Plus/tree/master and UnitTesting was working properly.

test_balance_characters_between_line_wraps_commented_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_ending_with_long_word (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_starting_with_comment (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_with_big_multi_line_balancing (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_with_comment_indentation_balance (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_with_long_subsequent_indentation (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_with_trailing_new_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_balance_characters_between_line_wraps_without_trailing_new_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_calculate_lines_count_with_maximum_lines_indent (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_calculate_lines_count_with_minimum_lines_indent (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_calculate_lines_count_with_only_one_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_split_lines_with_long_subsequent_indentation (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_split_lines_with_trailing_new_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_split_lines_with_very_long_line_and_word (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_split_lines_without_trailing_new_line (semantic_linefeed_unit_tests.LineBalancingUnitTests) ... ok
test_is_command_separated_list_2_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_3_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_4_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_5_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_lowerbound_with_1_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_lowerbound_with_2_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_lowerbound_with_3_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_lowerbound_with_trailing_1_space (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_lowerbound_with_trailing_2_space (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_upperbound_2_by_4_trailing_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_upperbound_with_1_by_5_trailing_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_upperbound_with_2_by_5_trailing_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_is_command_separated_list_upperbound_with_4_middle_items (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_ending_with_comma_list (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_ending_with_trailling_comma_on_list (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_long_word (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_simple_sentence (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_simple_sentence_with_dual_comma (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_simple_sentence_with_dual_comma_with_3_items_minimum (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_simple_sentence_with_single_comma (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_0_items_list (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_3_items_list (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_79_characters (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_80_characters (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_81_characters (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_81_characters_on_list_flushing (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_comma_list_on_the_end (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_comma_list_on_the_middle (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_initial_indentation (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_long_word_at_comma_list_end (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_semantic_line_wrap_with_numeric_comma_list_on_the_end (semantic_linefeed_unit_tests.SemanticLineWrapUnitTests) ... ok
test_double_quotes_wrappting (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_double_quotes_wrappting_without_leading_whitespace (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_comment (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_wrappting (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok
test_triple_quotes_wrappting_without_leading_whitespace (text_extraction_unit_tests.PrefixStrippingViewUnitTests) ... ok

----------------------------------------------------------------------
Ran 51 tests in 0.169s

OK

UnitTesting: Done.

EDIT: I just realized that you were talking about a different package.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

I checked out https://github.com/evandrocoan/ClearCursorsCarets
and UnitTesting was also working.

................
----------------------------------------------------------------------
Ran 16 tests in 0.133s

OK

UnitTesting: Done.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

I see what's going on now. You were trying to use relative import from .utilities import BasicSublimeTextViewTestCase. However, the tests was not imported as module so relative import is not possible. (You gave too much information so I missed it).

You could move the files into a folder with __init__.py. In this way, the tests will be imported as a module. Check https://github.com/divmain/GitSavvy/tree/master/tests/test_git as an example.

@evandrocoan
Copy link
Contributor Author

But I am doing this already have then in a folder with __init__.py and if I use from . import utilities I got this error:

image

However, If I do:

CURRENT_DIRECTORY    = os.path.dirname( os.path.dirname( os.path.realpath( __file__ ) ) )
CURRENT_PACKAGE_NAME = os.path.basename( CURRENT_DIRECTORY ).rsplit('.', 1)[0]

utilities = importlib.import_module( CURRENT_PACKAGE_NAME + ".tests.utilities" )

It does work:

image

This is my unittesting.json file:

{
    "tests_dir" : "tests",
    "pattern" : "*unit_tests.py",
    "async": false,
    "deferred": false,
    "verbosity": 1,
    "capture_console": true,
    "output": null
}

The differences I see from that example is the unittesting.json which is almost empty:

{
    "deferred": true,
    "capture_console": true
}

And that the tests which does relative import are inside a folder called tests_git with a __init__.py and everything starts with the name test_. On my project I set the "pattern" : "*unit_tests.py", so I expect the test files to end with unit_tests.py.

Am I required to move everything to another folder inside the tests folder with a __init__.py, then the relative import will start working? But I wonder why I need to create another folder inside the tests folder for the from . import BasicSublimeTextViewTestCase to work.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

Unittesting only imports directories under tests as modules, so you have to put it under /tests/testsomrthingelse/. In fact, the top level __init__.py is never used.

@randy3k
Copy link
Member

randy3k commented Dec 7, 2017

I may look into the possibility to import tests as a module.

Edit: it seems that it requires quite some work based on the unittest’s discover function. I don’t expect to see it soon.

evandrocoan referenced this issue in evandrocoan/RememberCommandPaletteInput Dec 27, 2017
issue:
SystemError: Parent module '' not loaded, cannot perform relative import
https://github.com/randy3k/UnitTesting/issues/67
evandrocoan referenced this issue in evandrocoan/ClearCursorsCarets Dec 27, 2017
issue:
SystemError: Parent module '' not loaded, cannot perform relative import
https://github.com/randy3k/UnitTesting/issues/67
evandrocoan added a commit to evandrocoan/debugtools that referenced this issue Jan 28, 2018
SublimeText/UnitTesting#67
SystemError: Parent module '' not loaded, cannot perform relative import
evandrocoan added a commit to evandrocoan/debugtools that referenced this issue Jan 28, 2018
SublimeText/UnitTesting#67
SystemError: Parent module '' not loaded, cannot perform relative import
@Thom1729
Copy link
Member

Hopefully this can be fixed as part of #155.

@Thom1729 Thom1729 reopened this Jan 16, 2019
@randy3k
Copy link
Member

randy3k commented Jan 16, 2019

I am not sure how easy or how hard it would be done. It seems that unittest.discover doesn't try to import the starting directory as a module.

@Thom1729
Copy link
Member

Yeah, the default implementation of discover is a bit screwy. It patches sys.path and does other weird stuff. For UnitTesting, we can guarantee that tests will always be inside a package that is already loaded or loadable (with some caveats around dependencies). This should let us use a simpler approach that behaves more predictably.

@randy3k
Copy link
Member

randy3k commented Jan 16, 2019

If we specify start_dir = 'PATH TO PACKAGE' rather than start_dir = 'PATH TO PACKAGE/tests', it should theoretically import tests module as a package if a __init__.py is found. But then it will run into a danger that for example a file testsomething.py under PACKAGE/src/ may be wrongly classified as a test file.

@Thom1729
Copy link
Member

Could we just pass start_dir='PATH TO PACKAGE/tests', top_level_dir='PATH TO PACKAGE'? I haven't tried it out, and my understanding of the overcomplicated default loader logic is incomplete, but it seems like this may be what it's for.

@randy3k
Copy link
Member

randy3k commented Jan 16, 2019

It would work only if there is a __init__.py under tests so it will break a lot of current users of UnitTesting.

@randy3k
Copy link
Member

randy3k commented Dec 5, 2019

Hopefully the next update will handle it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants