Trying to implement python TestSuite - python

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()

Related

Python unittest output only on test failures

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.')

Python Unit-Testing: In Nose is there a way to skip a test case from nose.run()?

I am writing a set of test cases say Test1, Test2 in a test module.
Is there a way to skip Test1 or selectively execute only Test2 in that module using the command nose.main()?
My module contains,
test_module.py,
class Test1:
setUp(self):
print('setup')
tearDown(self):
print('teardown')
test(self):
print('test1')
class Test2:
setUp(self):
print('setup')
tearDown(self):
print('teardown')
test(self):
print('test2')
I run it from a different python file using,
if __name__ == '__main__':
nose.main('test_module')
The notion of skipping test and not running a test are different in the context of nose: skipped tests will be reported as skipped at the end of the test result. If you want to skip the test you would have to monkey patch your test module with decorators or do some other dark magic.
But if you want to just not run a test, you can do it the same way you would do it from the command line: using --exclude option. It takes a regular expression of the test you do not want to run. Something like this:
import sys
import nose
def test_number_one():
pass
def test_number_two():
pass
if __name__ == '__main__':
module_name = sys.modules[__name__].__file__
nose.main(argv=[sys.argv[0],
module_name,
'--exclude=two',
'-v'
])
Running the test will give you:
$ python stackoverflow.py
stackoverflow.test_number_one ... ok
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK

How to run python unittests repeatedly from a script and collect results

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'

How do I run multiple Classes in a single test suite in Python using unit testing?

How do I run multiple Classes in a single test suite in Python using unit testing?
If you want to run all of the tests from a specific list of test classes, rather than all of the tests from all of the test classes in a module, you can use a TestLoader's loadTestsFromTestCase method to get a TestSuite of tests for each class, and then create a single combined TestSuite from a list containing all of those suites that you can use with run:
import unittest
# Some tests
class TestClassA(unittest.TestCase):
def testOne(self):
# test code
pass
class TestClassB(unittest.TestCase):
def testOne(self):
# test code
pass
class TestClassC(unittest.TestCase):
def testOne(self):
# test code
pass
def run_some_tests():
# Run only the tests in the specified classes
test_classes_to_run = [TestClassA, TestClassC]
loader = unittest.TestLoader()
suites_list = []
for test_class in test_classes_to_run:
suite = loader.loadTestsFromTestCase(test_class)
suites_list.append(suite)
big_suite = unittest.TestSuite(suites_list)
runner = unittest.TextTestRunner()
results = runner.run(big_suite)
# ...
if __name__ == '__main__':
run_some_tests()
I'm a bit unsure at what you're asking here, but if you want to know how to test multiple classes in the same suite, usually you just create multiple testclasses in the same python file and run them together:
import unittest
class TestSomeClass(unittest.TestCase):
def testStuff(self):
# your testcode here
pass
class TestSomeOtherClass(unittest.TestCase):
def testOtherStuff(self):
# testcode of second class here
pass
if __name__ == '__main__':
unittest.main()
And run with for example:
python mytestsuite.py
Better examples can be found in the official documention.
If on the other hand you want to run multiple test files, as detailed in "How to organize python test in a way that I can run all tests in a single command?", then the other answer is probably better.
The unittest.TestLoader.loadTestsFromModule() method will discover and load all classes in the specified module. So you can just do this:
import unittest
import sys
class T1(unittest.TestCase):
def test_A(self):
pass
def test_B(self):
pass
class T2(unittest.TestCase):
def test_A(self):
pass
def test_B(self):
pass
if __name__ == "__main__":
suite = unittest.TestLoader().loadTestsFromModule( sys.modules[__name__] )
unittest.TextTestRunner(verbosity=3).run( suite )
Normally you would do in the following way (which adds only one class per suite):
# Add tests.
alltests = unittest.TestSuite()
alltests.addTest(unittest.makeSuite(Test1))
alltests.addTest(unittest.makeSuite(Test2))
If you'd like to have multiple classes per suite, you can use add these tests in the following way:
for name in testnames:
suite.addTest(tc_class(name, cargs=args))
Here is same example to run all classes per separate suite you can define your own make_suite method:
# Credits: http://codereview.stackexchange.com/a/88662/15346
def make_suite(tc_class):
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(tc_class)
suite = unittest.TestSuite()
for name in testnames:
suite.addTest(tc_class(name, cargs=args))
return suite
# Add all tests.
alltests = unittest.TestSuite()
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj) and name.startswith("FooTest"):
alltests.addTest(make_suite(obj))
result = unittest.TextTestRunner(verbosity=2).run(alltests)
If above doesn't suite, you can convert above example into method which could accept multiple classes.
I've found nose to be a good tool for this. It discovers all unit tests in a directory structure and executes them.

Problem's running unittest test suite OO

I have a test suite to perform smoke tests. I have all my script stored in various classes but when I try and run the test suite I can't seem to get it working if it is in a class. The code is below: (a class to call the tests)
from alltests import SmokeTests
class CallTests(SmokeTests):
def integration(self):
self.suite()
if __name__ == '__main__':
run = CallTests()
run.integration()
And the test suite:
class SmokeTests():
def suite(self): #Function stores all the modules to be tested
modules_to_test = ('external_sanity', 'internal_sanity')
alltests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
alltests.addTest(unittest.findTestCases(module))
return alltests
if __name__ == '__main__':
unittest.main(defaultTest='suite')
This output's an error:
Attribute Error: 'module' object has no attribute 'suite'
So I can see how to call a normal function defined but I'm finding it difficult calling in the suite. In one of the tests the suite is set up like so:
class InternalSanityTestSuite(unittest.TestSuite):
# Tests to be tested by test suite
def makeInternalSanityTestSuite():
suite = unittest.TestSuite()
suite.addTest(TestInternalSanity("BasicInternalSanity"))
suite.addTest(TestInternalSanity("VerifyInternalSanityTestFail"))
return suite
def suite():
return unittest.makeSuite(TestInternalSanity)
If I have someSuite() inside the class SmokeTests python cannot find the attribute suite but if I remove the class it work's. I run this as a script and call in variables into the tests. I do not want to have to run the tests by os.system('python tests.py'). I was hoping to call the tests through the class I have like any other function
Can anyone help me with getting this running?
Thanks for any help in advance.
I know this is not the answer, but I'd suggest using library that can use test discovery, like nose or unittest capability from Python 2.7+.
Possibility to do
nosetests module.submodule
or
nosetests module.submodule:TestCase.test_method
is priceless :)
This can't work:
class SmokeTests():
def suite(self): #Function stores all the modules to be tested
modules_to_test = ('external_sanity', 'internal_sanity')
alltests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
alltests.addTest(unittest.findTestCases(module))
return alltests
if __name__ == '__main__':
unittest.main(defaultTest='suite')
This output's an error: Attribute Error: 'module' object has no attribute 'suite'.
Your suite the value of the SmokeTests().suite() method. Note a variable named suite, since you have no such variable.
It's easier to use a simple function for your suite.
def someSuite():
modules_to_test
...
return alltests
if __name__ == "__main__":
unittest.main( defaultTest= someSuite() )
Something like that would be closer to correct.

Categories

Resources