Issue with Python Module Import - python

I am encountering a weird import issue with Python module hoping to get some insight on.
I have the below following Folder Structure.
Folder Structure:
SomeProject
* Test/
* __init__.py
* TestModuleA.py
* TestModuleB.py
* TestModuleC.py
* __init__.py
* ModuleA.py
* ModuleB.py
* ModuleC.py
I was trying to run some of the test case with
python SomeProject/Test/TestModuleA.py
python SomeProject/Test/TestModuleB.py
python SomeProject/Test/TestModuleC.py
For some reason python SomeProject/Test/TestModuleA.py works fine, but python SomeProject/Test/TestModuleB.py came back with and error of ModuleNotFoundError: No module named 'SomeProject.ModuleB'.
I looked through the code, how ModuleA and ModuleB set up is pretty much the same, and how they are imported into TestModuleA and TestModuleB is same as well.
Also if I add from SomeProject.ModuleA import ModuleA from ModuleB it works fine.
I also tried running python -m unittest SomeProject/Test/TestModuleB.py and that seemed to work fine.
So I am wondering what's the discrepancy that could cause ModuleA and ModuleB to be different?
Test/__init__.py
name = 'Test'
Test/TestModuleA.py
from SomeProject.ModuleA import ModuleA
...
class TestModuleA(unittest.TestCase):
...
def suite():
"""Test Suite."""
# Create the Unit Test Suite
suite = unittest.TestSuite()
# Load a suite of all test cases contained in `testCaseClass`
test_module_a = unittest.defaultTestLoader.loadTestsFromTestCase(TestModuleA)
# Add the test suite
suite.addTest(test_module_a)
# Return the Test Suite
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Test/TestModuleB.py
from SomeProject.ModuleB import ModuleB
...
class TestModuleB(unittest.TestCase):
...
def suite():
...
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
Test/TestModuleC.py
from SomeProject.ModuleC import ModuleC
...
class TestModuleC(unittest.TestCase):
...
def suite():
...
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
__init__.py
# Blank
ModuleA.py
class ModuleA:
__init__(self):
...
...
ModuleB.py
class ModuleB:
__init__(self):
...
...
ModuleC.py
class ModuleC:
__init__(self):
...
...

Related

pytest name is not defined

I'm following this tutorial to setup pytest with my project. I create a new project with the following structure and code:
/src
/main.py
/tests
/test_pytest.py
main.py
def main():
# Bunch of stuff
print("End.")
# Entry point of the program
if (__name__ == '__main__'):
main()
test_pytest.py
import src.main as main
def test_main():
assert main.main() == 4
The unittest assertion will obviously fail but it doesn't matter. Visual Studio discovers this test but says the following:
NameError: name 'main' is not definedpytest(./tests/test_pytest.py::test_main)
I don't understand why I cannot name my unit test? It doesn't seem to matter what name I use.
Can you try:
from src import main
def test_main():
assert main.main() == 4

Running all unittest.TestCase imported using from .. import *

I have the following package:
tests.py
tests
__init__.py
test_module_a.py
test_module_b.py
In my tests.py file I do the following:
import unittest
from tests import *
if __name__ == "__main__":
unittest.main()
In my tests/__init__.py the following:
__all__ = ["test_module_a", "test_module_b"]
In my tests/test_module_a.py and tests/test_module_b.py files, I have the following:
import unittest
class TestMyModule(unittest.TestCase):
def test_something(self):
self.assertTrue(True)
When I run python tests.py, the submodules seem to be imported but my unittest.TestCase's are not run. Why? Thank.
Use a test loader and import explicitly every test case (to be more readable) :
import unittest
from test_module_a import TestMyModule1
from test_module_b import TestMyModule2
if __name__ == "__main__":
loader = unittest.TestLoader()
suite = unittest.TestSuite((loader.loadTestsFromTestCase(TestMyModule1),
loader.loadTestsFromTestCase(TestMyModule2),
)
)
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

Understanding python import system and project structuring

Suppose I have a project organized as follows:
ProjectRoot/
__init__.py
test.py
A/
__init__.py
a_test.py
B/
__init__.py
b_test.py
And suppose that a_test depends on b_test. So the source code is relatively simple:
#
# a_test.py
#
from B.b_test import b_test_class
class a_test_class:
def func(self):
print("a_test_class")
b_instance = b_test_class()
b_instance.func()
if __name__ == "__main__":
a_instance = a_test_class()
a_instance.func()
#
# b_test.py
#
class b_test_class:
def func(self):
print("b_test_class")
#
# test.py
#
from A.a_test import a_test_class
if __name__ == "__main__":
a_instance = a_test_class()
a_instance.func()
As long as I launch test.py script, everything works as intended. Python loads all modules without any troubles and executes them. Now the question comes: how do I launch a_test.py without having test.py? So, basically, what I want to achieve is to cd into projectRoot/A and execute a_test.py. This results in getting ImportError: No module named 'B'
Currently I've been able to create a project with following structure:
ProjectRoot/
customLibModuleA/
...
customLibModuleB/
...
mainApp.py
And what I want to be able to create is following:
ProjectRoot/
customLibModuleA/ #custom protocol implementation
...
customLibModuleB/ #custom logging functions
...
application1/ #server
...
application2/ #client
...
How do I expected to manage complex projects? Any good references to project structuring manuals and styleguides are welcome.
Here's my temporal solution since no one provided pythonic approach.
Folder structure looks like that:
ProjectRoot/
__init__.py
customLibModuleA/ #custom protocol implementation
__init__.py
...
customLibModuleB/ #custom logging functions
__init__.py
...
application1/ #server
__init__.py
__path_setup__.py
server.py
...
application2/ #client
__init__.py
__path_setup__.py
client.py
...
__path_setup__.py content is:
import sys
import os
os.sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
Application scripts have some setup code preceding imports (server.py):
#
#settings up the environment
#
if __name__ == "__main__":
exec(open("./__path_setup__.py").read())
#
# system and libraries imports
#
import customLibModuleA.whatever
...
Hight quality pythonic solution to this problem is still welcome.

Python unittest with TestLoader results in ModuleNotFoundError

i try to run a unittest with unittest.TestLoader and unittest.TextTestRunner but get an ModuleNotFoundError everytime i try to run the 'main' test file (here: test_all.py). I have the following file structure:
src.
test_all.py
dir1.
__init__.py
module1.py
submodule1.py
test_module1.py
dir2.
__init__.py
module2.py
submodule2.py
test_module2.py
dir3.
...
The test_all.py file looks like this:
# test_all.py
import os
import unittest
loader = unittest.TestLoader()
suite = loader.discover(os.getcwd())
runner = unittest.TextTestRunner()
runner.run(suite)
And finally the structure of the single testcases look like this:
# test_module1.py
import unittest
from module1 import Module1
class Module1TestCase(unittest.TestCase):
def setUp(self):
# do something
def test_something(self):
# test test
def tearDown(self):
# do something
if __name__ == '__main__':
unittest.main()
So, running the test_all.py always results in an ModuleNotFoundError referencing to the from module1 import Module1 inside the TestCase test_module1.py (and the same in the following TestCases). As far as i can tell there are no circular dependencies. Maybe adding the current Path to the PythonPath would work, but it really makes no sense to me: on the one hand i run the test_all.pyas main in the current directory and on the other the unittest.TestLoader.discover() already takes the current path.
PS: I know that putting all the TestCases in one folder is way better. But first i want to figure out why this is not working. Thanks!

How to create a pattern to filter out python test files

I have a bash script to execute my python tests and I would like to filter all test cases that have NOT_DONE in them
This is what I tried
python3 -m unittest discover -s ${FOLDER} -p 'test_((?!NOT_DONE).)*_ALL.py'
Input example :
test_word_NOT_DONE_more_words_alot_more_words_ALL.py <- This test shouldn't be executed
But this one should :
test_word_more_words_alot_more_words_ALL.py
Path Solution
Directory Structure
unittesting/
launcher.py
tests/
__init__.py
test_finished.py
test_NOT_DONE.py
folder/
__init__.py
test_finished2.py
test_NOT_DONE2.py
Inside each test file is print(__file__), nested under a TestCase method. Therefore, only if the module is imported and the test cases run, will it be executed.
Code:
import importlib
import os
import sys
import unittest
HOME = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, 'tests')
def check_file(file):
'''Check if file is test'''
return all((
'NOT_DONE' not in file,
file.endswith('.py'),
file != '__init__.py'
))
def find_paths(home=HOME):
'''Find all paths'''
os.chdir(HOME)
for root, dirs, files in os.walk('tests'):
for file in files:
if check_file(file):
if root != 'tests':
yield os.path.join(root[len('tests/'):], file)
else:
yield file
def normalize(path):
'''Normalize path to dotted name'''
path = os.path.splitext(path)[0]
unix = path.replace('/', '.')
return unix.replace('\\', '.')
def tests(paths=None):
'''Load and run tests'''
if paths is None:
paths = map(normalize, find_paths())
modules = (importlib.import_module(i) for i in paths)
suite = unittest.TestSuite()
loader = unittest.TestLoader()
for module in modules:
tests = loader.loadTestsFromModule(module)
suite.addTests(tests)
runner = unittest.TextTestRunner()
runner.run(suite)
if __name__ == '__main__':
tests()
As you can see, this gets unwieldly quickly, and very hard to manage. There's a simpler way. It runs, however.
$ python /home/alex/git/unittesting/launcher.py
tests/test_finished.pyc
.tests/folder/test_finished2.pyc
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Pythonic Solution
Inside each of my files that is not complete, I put the variable NOT_DONE = True, and each of my classes has a decorator skipif.
Directory Structure
unittesting/
launcher.py
tests/
__init__.py
test1.py
test2.py
folder/
__init__.py
test3.py
test4.py
In this example, test2 and test4 have NOT_DONE = True, while test1 and test3 have NOT_DONE = False.
An example file is as follows:
import unittest
NOT_DONE = False
# CASES
# -----
#unittest.skipIf(NOT_DONE, 'Reason')
class TestPrint(unittest.TestCase):
def test_print(self):
print(__file__)
if __name__ == '__main__':
unittest.main()
Now, to run I simply do:
$ python -m unittest discover tests
tests/test1.py
tests/folder/test3.py
.
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK (skipped=2)
Best Approach
Unfinished unittests should have a unittest.skipIf(True, 'Unfinished') line, so you get control not only at the module level, but also at the class or even method level. In the following example, I have one, finished unittest and one unfinished unittest. Running the example skips the first unittest, but runs the rest of the module.
import unittest
# CASES
# -----
#unittest.skipIf(True, 'Not Finished')
class TestPrint(unittest.TestCase):
def test_print(self):
print(__file__)
class TestPrinting(unittest.TestCase):
def test_print(self):
print(__file__)
if __name__ == '__main__':
unittest.main()

Categories