In python 2.6, I've been reading through the unittest documentation. But I still haven't found this answer.
What function does pyton -m unittest execute?
For example, how would I modify this code such that just executing python -m unittest would detect it and run the test?
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# make sure the shuffled sequence does not lose any elements
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
self.assertRaises(ValueError, random.sample, self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
EDIT:
Note this is just a example, I'm actually trying to get it to detect and run multiple tests as a suite, here is my starting point - but python -m unittest doesn't detect it nor does python -m unittest discovery work with it. I have to call python discovery.py to execute it.
discovery.py:
import os
import unittest
def makeSuite():
"""Function stores all the modules to be tested"""
modules_to_test = []
test_dir = os.listdir('.')
for test in test_dir:
if test.startswith('test') and test.endswith('.py'):
modules_to_test.append(test.rstrip('.py'))
all_tests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
module.testvars = ["variables you want to pass through"]
all_tests.addTest(unittest.findTestCases(module))
return all_tests
if __name__ == '__main__':
unittest.main(defaultTest='makeSuite')
python -m something executes the module something as a script. i.e. from python --help:
-m mod : run library module as a script (terminates option list)
The unittest module can be run as a script -- And the arguments that you pass to it determine which files it tests. The commandline interface is also documented in the language reference.
Related
Is there a way to write (or run) a set of Python unittest tests so that there is no output except when there is a test failure?
For example, if tests/mytests.py contains some unittest tests, then running python3 test/mytests.py will only output to stdout (or stderr) if there is a test failure.
Yes there is. I was able to combine the techniques in the answers to these two questions to get it to work:
Python, unittest: Can one make the TestRunner completely quiet?
argparse and unittest python
You can uncomment the test_should_fail() test to verify what happens when a test fails.
# mymodule.py
def myfunc():
return True
import unittest
import os
class TestMyFunc(unittest.TestCase):
def test_myfunc(self):
self.assertEqual(myfunc(), True)
# def test_should_fail(self):
# self.assertEqual(True, False)
if __name__ == '__main__':
alltests = unittest.TestLoader().loadTestsFromTestCase(TestMyFunc)
runner = unittest.TextTestRunner(stream=open(os.devnull, 'w'))
result = runner.run(alltests)
if len(result.failures) or len(result.errors):
print('There were failures or errors.')
*I want to my test case in single methods with a customized result.
Inside test.py file, the code is like this:
class TestStringMethods(unittest.TestCase):
def test_isupper1(self):
self.assertTrue('FOO'.isupper())
def test_isupper2(self):
self.assertTrue('FOO'.isupper())
if __name__ == '__main__':
runner=unittest.TextTestRunner(verbosity=2,resultclass=myResultclass)
unittest.main(testRunner=runner)
However, if I run in command mode like
python -m unittest test.TestStringMethods.test_isupper1
My test result does not include with myResultclass (inherits from unittest.TextTestResult). unittest uses default resultclass. how can I parameter myResultclass from command lines.
I somehow understand if it run in command line, it will not run IF, because it run in python -m, if I remove if __name__ == '__main__', python will give me error.
Any suggestion?
I have a class that stores a function and a method that tries to run the function in parallel using the multiprocessing module. I'm testing the class with the nose module and the nose.main() function hangs (nothing happens, no output is displayed, the kernel must be manually told to stop and restart) when run. My directory looks like:
Parent/
test.py
Code/
__init__.py
code.py
tests/
test_code.py
code.py contains:
import multiprocessing as mp
import numpy as np
import itertools
def target(): pass
def target_star(args): return target(*args)
class FuncWrapper():
def __init__(self, fun):
self.fun = fun
def run(self, X):
try:
arg_list_objects = []
arg_list_inputs = []
for i in range(len(X)):
arg_list_objects.append(self.fun.im_self)
arg_list_inputs.append(X[i])
target.__code__ = self.fun.im_func.__code__
pool = mp.Pool(processes=mp.cpu_count()-1)
F = np.array(pool.map(target_star, itertools.izip(arg_list_objects, arg_list_inputs))).reshape(X.shape)
pool.close()
pool.join()
except:
F = self.fun(X)
return F
Most of the code in the try: block is used to make the pool.map function work with class methods.
test_code.py contains:
import numpy as np
from unittest import TestCase
import unittest
from Code.code import FuncWrapper
class TestCode(TestCase):
def f(self, x):
return x
def test_FuncWrapper(self):
x = np.random.uniform(0, 1, (50, 1))
return FuncWrapper(self.f).run(x)
if __name__ == '__main__':
unittest.main()
test.py contains:
import nose
nose.main()
When I run test_code.py from the Parent folder, it successfully performs the test but when test.py is run, nothing happens. How should I use the nose.main function so that it doesn't hang, or is there another function in the nose module that would work here?
I'm using Ubuntu 14.04 LTS 64-bit with the Enthought Python distribution (Python 2.7.11 64-bit) and their Canopy IDE.
I cannot figure out how to run single unit tests from within a python script and collect the results.
Scenario: I have a battery of tests that check various methods producing various statistical distributions of different objects. The tests sometimes fail, as they should given that I am basically checking for particular kinds of randomness. I would like to run the tests repeatedly from a script or even from the interpreter and collect results for further analysis.
Suppose I have a module myTest.py with:
class myTest(unittest.TestCase):
def setup(self):
...building objects, etc....
def testTest1(self):
..........
def testTest2(self):
..........
Basically I need to:
run the setup method
run testTest1 (say), 100 times
collect the failures
return the failures
The closest I got to was (using code from a similar question):
from unittest import TextTestRunner, TestSuite
runner = TextTestRunner(verbosity = 2)
tests = ['testTest1']
suite = unittest.TestSuite(map(myTest, tests))
runner.run(suite)
But this does not work, because:
runner.run(suite) does not run the setup method
and
I cannot catch the exception it throws when testTest1 fails
you simply need to add the test that you want to run multiple times to the suite.
Here is a complete code example. You can also see this code running in an interactive Python console to prove that it does actually work.
import unittest
import random
class NullWriter(object):
def write(*_, **__):
pass
def flush(*_, **__):
pass
SETUP_COUNTER = 0
class MyTestCase(unittest.TestCase):
def setUp(self):
global SETUP_COUNTER
SETUP_COUNTER += 1
def test_one(self):
self.assertTrue(random.random() > 0.3)
def test_two(self):
# We just want to make sure this isn't run
self.assertTrue(False, "This should not have been run")
def suite():
tests = []
for _ in range(100):
tests.append('test_one')
return unittest.TestSuite(map(MyTestCase, tests))
results = unittest.TextTestRunner(stream=NullWriter()).run(suite())
print dir(results)
print 'setUp was run', SETUP_COUNTER, 'times'
I have two test cases (two different files) that I want to run together in a Test Suite. I can get the tests to run just by running python "normally" but when I select to run a python-unit test it says 0 tests run. Right now I'm just trying to get at least one test to run correectly.
import usertest
import configtest # first test
import unittest # second test
testSuite = unittest.TestSuite()
testResult = unittest.TestResult()
confTest = configtest.ConfigTestCase()
testSuite.addTest(configtest.suite())
test = testSuite.run(testResult)
print testResult.testsRun # prints 1 if run "normally"
Here's an example of my test case set up
class ConfigTestCase(unittest.TestCase):
def setUp(self):
##set up code
def runTest(self):
#runs test
def suite():
"""
Gather all the tests from this module in a test suite.
"""
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(ConfigTestCase))
return test_suite
if __name__ == "__main__":
#So you can run tests from this module individually.
unittest.main()
What do I have to do to get this work correctly?
you want to use a testsuit. So you need not call unittest.main().
Use of testsuit should be like this:
#import usertest
#import configtest # first test
import unittest # second test
class ConfigTestCase(unittest.TestCase):
def setUp(self):
print 'stp'
##set up code
def runTest(self):
#runs test
print 'stp'
def suite():
"""
Gather all the tests from this module in a test suite.
"""
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(ConfigTestCase))
return test_suite
mySuit=suite()
runner=unittest.TextTestRunner()
runner.run(mySuit)
All of the code to create a loader and suite is unnecessary. You should write your tests so that they are runnable via test discovery using your favorite test runner. That just means naming your methods in a standard way, putting them in an importable place (or passing a folder containing them to the runner), and inheriting from unittest.TestCase. After you've done that, you can use python -m unittest discover at the simplest, or a nicer third party runner to discover and then run your tests.
If you are trying to manually collect TestCases, this is useful: unittest.loader.findTestCases():
# Given a module, M, with tests:
mySuite = unittest.loader.findTestCases(M)
runner = unittest.TextTestRunner()
runner.run(mySuit)
I am assuming you are referring to running python-unit test against the module that consolidates the two test. It will work if you create test case for that module ie. subclassing unittest.TestCase and having a simple test that starts with the word 'test'.
e.g.
class testall(unittest.TestCase):
def test_all(self):
testSuite = unittest.TestSuite()
testResult = unittest.TestResult()
confTest = configtest.ConfigTestCase()
testSuite.addTest(configtest.suite())
test = testSuite.run(testResult)
print testResult.testsRun # prints 1 if run "normally"
if __name__ == "__main__":
unittest.main()