TestSuite with testsuites and testcases - python

I need to make a big python suitecase consisted of other suitcases and testcase which I have already made to execute together.
How do I do this?
For example, here there is a suitecase (suiteFilter.py) which I want to add:
import testFilter1
import testFilter2
import unittest
import sys
def suite():
return unittest.TestSuite((\
unittest.makeSuite(testFilter1.TestFilter1),
unittest.makeSuite(testFilter2.TestFilter2),
))
if __name__ == "__main__":
result = unittest.TextTestRunner(verbosity=2).run(suite())
sys.exit(not result.wasSuccessful())
And a testcase structure (Invoice.py):
from selenium import selenium
import unittest, time, re
from setup_tests import filename, fileForNrTest, username, password, server_url
fileW=open(filename,'a')
class TestInvoice(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 4444, "*firefox", server_url)
self.selenium.start()
def test_invoice(self):
sel = self.selenium
[...]
def tearDown(self):
self.selenium.stop()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
Thank you!

You could give some additional information like the structure of your program / test cases and suites. The way I do it is define a suite() for each module. So I have say for UserServiceTest module:
def suite():
"""
Gather all the tests from this module in a test suite.
"""
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(UserServiceTest))
return test_suite
if __name__ == "__main__":
#So you can run tests from this module individually.
unittest.main()
Then I have a main test for each package:
def suite():
"""
Gather all the tests from this package in a test suite.
"""
test_suite = unittest.TestSuite()
test_suite.addTest(file_tests_main.suite())
test_suite.addTest(userservice_test.suite())
return test_suite
if __name__ == "__main__":
#So you can run tests from this package individually.
TEST_RUNNER = unittest.TextTestRunner()
TEST_SUITE = suite()
TEST_RUNNER.run(TEST_SUITE)
You can do this the recursevly until the root of your project. So main test from package A will gather all module in package A + main test from subpackages of package A and so on. I was assuming you-re using unittest since you didn't give any additional details but I think this structure can be applied to other python testing frameworks as well.
Edit: Well I'm not quite sure I fully understand your problem, but from what I can understand you want to add both the suite defined in suiteFilter.py and the testcase defined in Invoice.py in the same suite? If so why not just do in a mainTest.py for example:
import unittest
import suiteFilter
import Invoice
def suite()
test_suite = unittest.TestSuite()
test_suite.addTest(suiteFilter.suite())
test_suite.addTest(unittest.makeSuite(Invoice))
if __name__ == "__main__":
result = unittest.TextTestRunner(verbosity=2).run(suite())
sys.exit(not result.wasSuccessful())
You can add tests and suites all the same to a test_suite.

Related

How to do one setUp for a unit test suite

I have the following to do two unit tests:
import unittest
from unittest import TestCase
class TestUM(unittest.TestCase):
def setUp(self):
self.client = SeleniumClient()
def test_login(self):
self.client.login()
self.assertIn("my-data", self.client.driver.current_url)
print ('Log in successful.')
def test_logout(self):
self.client.logout()
print ('Log out successful.')
if __name__ == '__main__':
unittest.main()
However, it does setUp twice -- once for each of the unit tests. Is there a way I can do one setup across all the unittests for TestUM ? If so, how would I do that?
You can use setupClass for that:
class TestUM(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.client = SeleniumClient()
From the documentation, this method is called only once before tests in class are run.

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)

Python suite test doesn't run tests

I am trying to code a suite test, I have one module which runs unit test correctly but I intend to add more modules and test them at once, so I have coded the following code:
#main.py
import unittest
from test.Services import TestOS
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTests( TestOS.TestOS() )
unittest.TextTestRunner().run(suite)
TestOS.py
import unittest
from app.Services.OS import OS
class TestOS(unittest.TestCase):
os = OS()
def setUp(self):
pass
def tearDown(self):
pass
def testOSName(self):
self.assertEquals(self.os.getPlatform(), 'Windows')
def testOSVersion(self):
self.assertEquals(self.os.getVersion(), '7')
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
After running it, I get this output:
Finding files... done.
Importing test modules ... done.
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
It didn't find any test, What's wrong with my code?
suite.addTest( TestOS.TestOS() ) works only if your testcase contains a runTest() function.
Otherwise you need a "TestLoader" to detect the functions of TestOS that start with "test*".
#main.py
import unittest
from test.Services import TestOS
if __name__ == '__main__':
suite = unittest.TestSuite()
tests = unittest.defaultTestLoader.loadTestsFromTestCase(TestOS)
suite.addTests(tests)
unittest.TextTestRunner().run(suite)
modify your setUp method as follows
def setUp(self):
self.os = OS()
pass

What's the right way to pass a var to a Python unittest TestCase and/or TestSuite?

I need to run a Python unittest test suite against multiple REST backend resources so I need to pass in a Resource object to the test suite and individual testcases.
Is setting a global var the right way to do this, or is there a better way?
resource = Resource('http://example.com')
class RestTestCase(unittest.TestCase):
def setUp(self):
self.resource = resource
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(RestTestCase))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='suite')
Follow the example of the how the standard library writes its own unittests. Put the resource in a class variable and use inheritance to test the various resources:
class RestTestCase(unittest.TestCase):
resource = Resource('http://example.com')
def sometest(self):
r = self.resource
...
self.assertEqual(expectedresult, actualresult)
class SomeOtherRestTestCase(RestTestCase):
resource = Resource('http://someother.example.com')
class YetAnotherRestTestCase(RestTestCase):
resource = Resource('http://yetanother.example.com')
if __name__ == '__main__':
unittest.main()

Ignoring modules other than own in testoob coverage reporting

I use testoob in the following way:
def suite():
import unittest
return unittest.TestLoader().loadTestsFromNames([
'my_module.my_unittest_class',
'my_module.my_other_unittest_class',
])
if __name__ == '__main__':
import testoob
testoob.main(defaultTest="suite")
And then run the unittest suite with the following:
python my_unittest.py --coverage=normal
This however will also print code coverage figures of all modules that my module and unittest depends on, which I'm not interested in at all. How can I configure testoob to only report coverage for my own module?
I ended up overriding the private _should_cover_frame function in the testoob Coverage class and comparing the frame's file path to my module. Not the nicest solution, but at least it works.
from testoob.coverage import Coverage
orig_should_cover = Coverage._should_cover_frame
def my_should_cover_frame(self, frame):
from os.path import abspath
filename = abspath(frame.f_code.co_filename)
if filename.find('my_module') == -1:
return False
else:
return orig_should_cover(self, frame)
Coverage._should_cover_frame = my_should_cover_frame

Categories