I am learning unittest of python.
I learned that I can run a test, test_code, by
python -m unittest test_code
from command line.
Now I would like to run unittest in python script.
I learned "runpy.run_module()" corresponds with "python -m".
However I could not understand how to give arguments to unittest
in the way of "runpy.run_module()".
That is,
runpy.run_module(unittest) # where should I put 'test_code'?
Can I run unittest with test_code with runpy.run_module() in the python script?
Thank you very much.
Here are some ways to do it:
import unittest
import tests # where my unit tests are at
import tests_copy # where my unit tests are at
# make a collection of TestCases
suit = unittest.TestSuite()
# add all testcases in tests module
suit.addTest(unittest.defaultTestLoader.loadTestsFromName('tests'))
# add testcase tester1 from module tests_copy
suit.addTest(unittest.defaultTestLoader.loadTestsFromName('tests_copy.tester1'))
# add all testcases in tests module
suit.addTest(unittest.defaultTestLoader.loadTestsFromModule(tests))
# add testcase tester1 from module tests_copy
suit.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(tests.tester1))
# run the tests
runner = unittest.TextTestRunner()
runner.run(suit)
Read the docs
Related
In the default behaviour giving the command python setup.py test will execute the unit tests associated with a module. This default behaviour can be made to work simply by providing a list of test-suite modules.
The alternative (but now obsolete) Nose test runner has a comparable feature - you can just provide the string nose.collector which gives the test command the ability to auto-discover the tests associated with the project.
But what if I'm using pytest? There doesn't seem to be a documented pattern to run tests from the setup.py file. Is this a behaviour supported by the pytest library?
I personally have not done this. But I'd recommend checking out some legit python projects on github to see how they have done this.
E.g. requests:
#!/usr/bin/env python
import sys
from setuptools import setup
from setuptools.command.test import test as TestCommand
class PyTest(TestCommand):
user_options = [('pytest-args=', 'a', "Arguments to pass into py.test")]
def initialize_options(self):
TestCommand.initialize_options(self)
self.pytest_args = []
def finalize_options(self):
TestCommand.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
import pytest
errno = pytest.main(self.pytest_args)
sys.exit(errno)
setup(
# pass all the required/desired args
cmdclass={'test': PyTest}
)
You can even pass args to pytest runner python setup.py test --pytest-args='-vvv'
Also checkout the docs: https://docs.pytest.org/en/latest/goodpractices.html#integrating-with-setuptools-python-setup-py-test-pytest-runner (thanks to #jonrsharpe for the link)
I wrote a python script to do all my tests automatically for me, and generate a HTML report. I discovered discover for unittests the other day which lets me run all the unittests in a given directory without explicitly naming them, and I'd really like to be able to do my doctests the same way, rather than having to import each module explicitly.
I found some info on how to do this at https://docs.python.org/2/library/doctest.html but didn't really get it. Could you please help me with using discover with my doctests?
Python test discovery with doctests, coverage and parallelism is related, but still doesn't answer my question.
coverage_module
import coverage
import doctest
import unittest
import os
# import test_module
import my_module
cov = coverage.Coverage()
cov.start()
# running doctest by explicity naming the module
doctest.testmod(my_module)
# running unittests by just specifying the folder to look into
testLoad = unittest.TestLoader()
testSuite = testLoad.discover(start_dir=os.getcwd())
runner = unittest.TextTestRunner()
runner.run(testSuite)
cov.stop()
cov.save()
cov.html_report()
print "tests completed"
test_module
import unittest
import doctest
from my_module import My_Class
class My_Class_Tests(unittest.TestCase):
def setUp(self):
# setup variables
def test_1(self):
# test code
# The bit that should load up the doctests? What's loader, tests, and ignore though?
# Is this in the right place?
def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocTestSuite(module_with_doctests))
return tests
if __name__ == '__main__':
unittest.main()
Lets figure out what's happening there
1) unittest.discovery
It has no clue of doctests as doctests is a different framework.
So unittest isn't supposed to discover doctests out of the box.
That means you'll need to glue them together by hand
2) doctest
It's essentially a separate framework although it has some glueing classes to convert doctests into unittest-like TestCases.
https://docs.python.org/2.7/library/doctest.html#doctest.DocTestSuite
3) discover
Didn't get what discover you mean, I suppose it's
python -m unittest discover
If not and you're talking about https://pypi.python.org/pypi/discover then just forget about it - it's a backport for earlier versions of python
4) what to do
either scatter a lot of load_tests hooks across your code as described here https://docs.python.org/2.7/library/doctest.html#unittest-api or code a method to collect all the modules your have in one place and convert them into a DocTestSuite[s] https://docs.python.org/2.7/library/doctest.html#doctest.DocTestSuite
But honestly neither approach makes any sense nowadays as it boils down to:
$ py.test --doctest-modules
or
$ nosetests --with-doctest
Of course coverage and lots of bells & whistles are also supplied by these frameworks and you may keep sticking to unittest.TestCase, and you won't even need to create a coverage_module so I would dig into one of them rather then trying to come up with your own solution
I am writing python selenium tests
if __name__ == "__main__":
unittest.main()
This is my main.py file, I import the tests from a different folder
from tests.AuthorTest import AuthorTest
When I run main.py it gives me a message
python main.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
for some reason, when I pull the code from git hub I can edit and change existing files but when I add new tests to main.py, it still says Ran 0 tests. Im guessing the main isn't importing it correctly? Been having this problem for a while and I can't seem to fix it.
Appreciate any and all help!
All test functions when using unittest modules should begin with test in your test file.
"A testcase is created by subclassing unittest.TestCase. The three individual tests are defined with methods whose names start with the letters test. This naming convention informs the test runner about which methods represent tests."
From http://docs.python.org/2/library/unittest.html
class TestSequenceFunctions(unittest.TestCase):
def choice(self):
self.assertTrue(False)
will not show any result but when def choice(self) is renamed to def testchoice(self), unittest now will show that one of the tests failed.
In testsuite/__init__.py, I write this:
import unittest
def suite():
from my_module.testsuite import (
shell_command,
shell_command_on_jinja,
workflow
)
suite = unittest.TestSuite()
suite.addTest(shell_command.suite())
suite.addTest(shell_command_on_jinja.suite())
suite.addTest(workflow.suite())
return suite
In terminal, I can execute the test suite like this:
python3 -m unittest testsuite.suite
However, I don't know how to config the test for Pycharm/InteliJ. I add a configuration under Python's test and set Test to Function, Script to my_module/testsuite/__init__.py, and Function to suiteand then run it. But it doesn't work. Does anyone have ideas about this? Thanks!
It seems that PyCharm doesn't support this now. Please check the following thread.
http://forum.jetbrains.com/thread/PyCharm-1116
I'm struggling to know where to start with unittest, having read the dive-into-python tutorial and looked at http://pyunit.sourceforge.net/.
I've got a piece of analysis software (call it 'prog.exe') which uses python for its input decks. I've started writing a python module which I'm going to import from that input deck to provide some useful functionality. So, running one of these analyses will go like this:
prog.exe inputdeck.py
where inputdeck.py contains:
from mymodule import mystuff
So how do I set up and run tests on mymodule? Should the above be in a system call in a setUp method of the test, or what?
Ok - solution:
Don't use unittest.main() as that's the command line tool. Instead call the appropriate unittest methods directly as follows:
From the command line run:
prog.exe mytests.py
where mytests.py contains:
import unittest
# ... code to run the analysis which we'll use for the tests ...
# ... test definitions ...
suite = unittest.TestLoader().loadTestsFromTestCase(test_cases)
unittest.TextTestRunner().run(suite)
See example at http://docs.python.org/release/2.6.7/library/unittest.html#unittest.TextTestRunner
Pyunit is a little bit outdated (2001), it is now completely included in python core distribution (http://docs.python.org/library/unittest.html). You should start read this documentation, especially the basic example part.
To test your module you'll have to create a file, let's call it mymodule_test.py and put in it something like this :
import unittest
from mymodule import mystuff
class MyTestCase(unittest.TestCase):
def test_01a(self):
""" test mystuff"""
self.failUnless(mystuff.do_the_right_stuff())
if __name__ == '__main__':
unittest.main()
and run it with python mymodule_test.py