unittest.main() to run all test modules in a package - python

I have several test modules saved in \tests. I then load them in the main class prior to running the main program by specifying
from tests.ClassTests1 import *
from tests.ClassTests2 import *
...
unittest.main()
Is there any way to instruct unittest.main() to run all the files in \tests without going through endless repetition of importing them as above? E.g. I tried from tests import * and it does not work.
EDIT: I am after the programmatic discovery not the discover via the command-line.
Many thanks!

Thanks goes to John Gordon for his links. Here's what made it work for me:
from tests.ClassTests1 import *
# Run test cases first
suite = unittest.TestLoader().discover('tests', pattern='ClassTests*.py')
result = unittest.TextTestRunner(verbosity=2).run(suite)
However, I still need to import at least one test module, and I'm not sure if I'm doing this right as it discovers the entire test hierarchy of tests.

From https://docs.python.org/2/library/unittest.html, section 25.3.3. Test Discovery:
Unittest supports simple test discovery. In order to be compatible with test discovery, all of the test files must be modules or packages importable from the top-level directory of the project (this means that their filenames must be valid identifiers).
Test discovery is implemented in TestLoader.discover(), but can also be used from the command line. The basic command-line usage is:
cd project_directory
python -m unittest discover

Related

pytest cannot locate dynamically created module

I have a directory structure like what follows:
package_root/lib/package_name/foo.py
in foo.py I have a function that creates a file (bar.py) that contains a function (f). foo.py also has a function that then imports bar and runs bar.f().
When I state, within foo.py "import bar", it works, and I have access to bar.f and it runs just fine.
However, this is not the case when running pytest. We run pytest from package_root and it cannot find the module bar when it attempts to import it. This is because (I believe) when running pytest, it creates bar.py in /package_root which contains no init.py file. Since our tests run automatically for our cicd pipeline, I need it to be able to properly import when running pytest from package_root. Any suggestions?
As far as I comprehend from your question is that you are facing imports issue in your pipeline(Correct me if am wrong). In pytest, normally your framework should contain the pytest.ini/tox.ini along with all the test scripts. Please refer link(http://doc.pytest.org/en/latest/customize.html).
Create a file pytest.ini/tox.ini in your framework design from where you are running your code(in your case in the package_root/ directory).
#pytest.ini
[pytest]
python_paths = . lib/<package-name>/

Python unittest does not run tests

I made a small project called demo, with a single test in it
import unittest
class Test(unittest.TestCase):
def testName1(self):
self.assertEqual(5+9, 14)
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
However, from command line
ThinkPad-T520:~/workspacep/demo$ python -m unittest
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Why doesn't this work? In general, how can I run all unit tests from command line with a single line?
The structure of the directory is
demo
tests
demo_test1.py __init__.py
There are three gotcha's that I know of:
Your tests in your TestCases need to be named test_*
Your test files need to be named: test*.py (by default, you can change it with the -p flag when running the tests). e.g. test_demo1.py
Your tests folder needs to have an __init__.py file in it, or else it won't be considered a valid location to import from.
So, for #1, you need to rename the test to test_name_1. And for #2, there's two options:
A - Restructure your files like this:
demo
tests
__init__.py
test_demo1.py
Then run python -m unittest and it should find the test cases.
B - Just run it like: python -m unittest discover -p *test.py
I fought with the same exact problem a while ago and I solved it by using test discovery command.
python -m unittest discover -s .
You can pass in your test file pattern as well and a whole other options https://docs.python.org/2/library/unittest.html#test-discovery
You need to pass in a list of modules.
For example, if your test file is foo.py, then you can run python -m unittest foo.
For me (running tests from IntelliJ IDEA) I had to remove the class' 'Run configuration'. Earlier on I had wrongly imported the unittest as _pytest.unittest and ran the test class. Of course that didn't work.
I corrected the module import, but the 'run configuration' was still there, causing it to run as a Python script and not as 'Python tests'.
I had a similar issue and figured out that I had to run python3 -m unittest instead as I had forgotten python defaults to Python 2 on my system

Python Travis-CI: Importing main code in test code

I am writing a simple package in python. In the root directory, my structure currently is,
my_package
init.py
main_code.py
tests
init.py
test_main_code.py
I want to import all functions from main_code.py in test_main_code.py. To achieve this, I did
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + '\..' + '\my_package')
from main_code import *
This runs smoothly on my system. But when I push the code to github and tests are run on travis-ci, all tests fail and return NameError. It says given function name not defined. How do I make sure that tests run on travis-ci as well ?
Paths could be different if you run the test somewhere else, so I wouldn't trust any import related to a particular location.
In any case, I always try to run the tests from the root of the project.
Then, you can simply try:
from my_package.main_code import *

How to run all tests with one shell command?

Suppose I've got a few modules with test cases derived from unittest.TestCase. All those modules reside in one package test:
test/
test_case1.py
test_case2.py
test_case3.py
I'd like to run all tests in all modules in test with one shell command. In order to do it I've added a new module test_all.py, which creates a TestSuite with all the test cases, and main:
def make_suite():
... # add test cases explicitly one by one
if __name__ == "__main__":
suite = make_suite()
unittest.TextTestRunner().run(suite)
Now I wonder if there is a way to run all the test cases in test without making a TestSuite
Starting in Python 2.7, you can do something like this:
python -m unittest discover <test_directory>
Of course, all your test directories must contain an __init__.py file.
You can also use a tool like nose to run your tests.
See also:
How do I run all Python unit tests in a directory?
for f in ./test/test_case*.py; do python $f; done

Python - organising code and test suite

I am very new to python, coming from a php background and cant figure out the best way to organise my code.
Currently I am working through the project euler exercises to learn python. I would like to have a directory for my solution to the problem and a directory that mirrors this for tests.
So ideally:
Problem
App
main.py
Tests
maintTest.py
Using php this is very easy as i can just require_once the correct file, or amend the include_path.
How can this be achieved in python? Obviously this is a very simplistic example - therefore some advice on how this is approached on a larger scale would also be extremely grateful.
This depends on which test runner you want to use.
pytest
I recently learned to like pytest.
It has a section about how to organize the code.
If you can not import your main into the code then you can use the tricks below.
unittest
When I use unittest I do it like this:
with import main
Problem
App
main.py
Tests
test_main.py
test_main.py
import sys
import os
import unittest
sys.path.append(os.path.join(os.path.dirname(__file__), 'App'))
import main
# do the tests
if __name__ == '__main__':
unittest.run()
or with import App.main
Problem
App
__init__.py
main.py
Tests
test.py
test_main.py
test.py
import sys
import os
import unittest
sys.path.append(os.path.dirname(__file__))
test_main.py
from test import *
import App.main
# do the tests
if __name__ == '__main__':
unittest.run()
I have always loved nosetests, so here is my solution:
Problem
App
__init__.py
main.py
Tests
__init__.py
tests.py
Then, open the command prompt, CD to /path/to/Problem and type:
nosetests Tests
it will automatically recognize and run the tests. However, read this:
Any python source file, directory or package that matches the
testMatch regular expression (by default: (?:^|[b_.-])[Tt]est) will be
collected as a test (or source for collection of tests).
[...]
Within a test directory or package, any python source file matching testMatch will be examined for test cases. Within a test module, functions and classes whose names match testMatch and TestCase subclasses with any name will be loaded and executed as tests.
This basically means that your tests (both your files and function/methods/classes) have to begin with the "test" or "Test" word.
More on Nosetests usage here: Basic Usage.

Categories