How to do one setUp for a unit test suite - python

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.

Related

Only run setUp when a specific test requires it

How would I limit running a setUp method to only run when a specific test is run, e.g.
class Tests(unittest.TestCase):
setUpClass(cls):
#requirements for all tests
def test1(self):
#something
def test2(self):
#something else
def setUp(self):
#requirements for test 3
def test3(self):
#something requiring setup
In this case, I only want to run setUp when test3 is called
You can call a test-specific setup method inside test method, e.g.:
class Tests(unittest.TestCase):
setUpClass(cls):
#requirements for all tests
def test1(self):
#something
def test2(self):
#something else
def setUp(self):
#requirements for test 3
def test3(self):
self.prepareForTest3();
#execute test case
def prepareForTest3(self):
#do preparations here

Is there a way to run "setup" only once for the entire suite of Python tests? [duplicate]

Is there a function that is fired at the beginning/end of a scenario of tests? The functions setUp and tearDown are fired before/after every single test.
I typically would like to have this:
class TestSequenceFunctions(unittest.TestCase):
def setUpScenario(self):
start() #launched at the beginning, once
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
def tearDownScenario(self):
end() #launched at the end, once
For now, these setUp and tearDown are unit tests and spread in all my scenarios (containing many tests), one is the first test, the other is the last test.
As of 2.7 (per the documentation) you get setUpClass and tearDownClass which execute before and after the tests in a given class are run, respectively. Alternatively, if you have a group of them in one file, you can use setUpModule and tearDownModule (documentation).
Otherwise your best bet is probably going to be to create your own derived TestSuite and override run(). All other calls would be handled by the parent, and run would call your setup and teardown code around a call up to the parent's run method.
I have the same scenario, for me setUpClass and tearDownClass methods works perfectly
import unittest
class Test(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
#classmethod
def tearDownClass(cls):
cls._connection.destroy()
Here is an example: 3 test methods access a shared resource, which is created once, not per test.
import unittest
import random
class TestSimulateLogistics(unittest.TestCase):
shared_resource = None
#classmethod
def setUpClass(cls):
cls.shared_resource = random.randint(1, 100)
#classmethod
def tearDownClass(cls):
cls.shared_resource = None
def test_1(self):
print('test 1:', self.shared_resource)
def test_2(self):
print('test 2:', self.shared_resource)
def test_3(self):
print('test 3:', self.shared_resource)
For python 2.5, and when working with pydev, it's a bit hard. It appears that pydev doesn't use the test suite, but finds all individual test cases and runs them all separately.
My solution for this was using a class variable like this:
class TestCase(unittest.TestCase):
runCount = 0
def setUpClass(self):
pass # overridden in actual testcases
def run(self, result=None):
if type(self).runCount == 0:
self.setUpClass()
super(TestCase, self).run(result)
type(self).runCount += 1
With this trick, when you inherit from this TestCase (instead of from the original unittest.TestCase), you'll also inherit the runCount of 0. Then in the run method, the runCount of the child testcase is checked and incremented. This leaves the runCount variable for this class at 0.
This means the setUpClass will only be ran once per class and not once per instance.
I don't have a tearDownClass method yet, but I guess something could be made with using that counter.
import unittest
class Test(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.shared_data = "dddd"
#classmethod
def tearDownClass(cls):
cls.shared_data.destroy()
def test_one(self):
print("Test one")
def test_two(self):
print("Test 2")
For more visit Python
unit test document

Python unittest loading test data on the fly

I'm trying to load test data base on the application name from a configuration file.
I'm using ConfigParser which is a nosetest plug in.
Here is my code. I just don't know how to pass the app name while loading the tests on the fly. I tried the constructor, but could not figure out a way to pass parameters to the loadTestsFromTestCase method.
Any ideas?
import unittest
class TestMyApp(unittest.TestCase):
def test1(self):
print "test1: %s" % self.app
def test2(self):
print "test2: %s" % self.app
if __name__ == '__main__':
# here specify the app name
suite = unittest.TestLoader().loadTestsFromTestCase(TestMyApp)
# here specify the other app name
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMyApp))
unittest.TextTestRunner(verbosity=2).run(suite)
You are need a test parametrization! It is easy to done with pytest. Look at this code example:
import pytest
class AppImpl:
def __init__(self, app_name):
self.name = app_name
def get_name(self):
return self.name
#pytest.fixture(params=['App1', 'App2'])
def app(request):
return AppImpl(request.param)
def test_1(app):
assert app.get_name()
def test_2(app):
assert 'App' in app.get_name()
if __name__ == '__main__':
pytest.main(args=[__file__, '-v'])
By using class implementation of you logic AppImpl, you can create a fixture app, which can be parametrized by specific arg params=['App1', 'App2']. Then in your tests test_1 and test_2, use fixture name app in funcargs. This possibility provides more modularity and readability tests.

PyUnit: How to run all tests from different unittest.TestCase subclass present in a file

import unittest
import HTMLTestRunner
class TestClass1(unittest.TestCase):
def setUp(self):
pass
def case1(self):
assert 4 == 3
def case2(self):
assert 4 == 4
def tearDown(self):
pass
class TestClass2(unittest.TestCase):
def setUp(self):
pass
def case3(self):
assert 1 == 2
def tearDown(self):
pass
def suite():
suite = unittest.TestSuite()
suite.addTest(TestClass1(['case1','case2']))
suite.addTest(TestClass2('case4'))
return suite
test_suite = suite()
unittest.TextTestRunner(verbosity=2).run(test_suite)
fp = file('my_report.html', 'wb')
runner = HTMLTestRunner.HTMLTestRunner(
stream=fp,
title='My unit test',
description='This demonstrates the report output by HTMLTestRunner.'
)
runner.run(test_suite)
I am trying to run all the methods in both the classes in a single run. However, the code above did not do so. In the suite function, I tried to add multiple tests from the classes but that also did not work and was giving an error.
From this answer at the question "Is test suite deprecated in PyUnit?":
"unittest.TestSuite is not necessary if you want to run all the tests in a single module as unittest.main() will dynamically examine the module it is called from and find all classes that derive from unittest.TestCase."
There's more in that answer about when unittest.TestSuite is useful.
That said, I needed to make some changes to get these tests to work. Firstly, unittest looks for functions with "test_" at their start. Also, unittest's assertEqual and similar methods should be used, instead of just Python's assert statement. Doing that and eliminating some unneeded code led to:
import unittest
class TestClass1(unittest.TestCase):
def test_case1(self):
self.assertEqual(4, 3)
def test_case2(self):
self.assertEqual(4, 4)
class TestClass2(unittest.TestCase):
def test_case3(self):
self.assertEqual(1, 2)
unittest.main()
This produced appropriate output (3 tests run with 2 failures), which I won't reproduce here in the interest of space.

How can I share one webdriver instance in my test classes in the suite? I use Selenium2 and Python

My code is like this:
class class1(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def testListRolesTitle(self):
driver=self.driver
driver.get("www.google.com")
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
asert...
class class2(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def testListRolesTitle(self):
driver=self.driver
driver.get("www.google.com")
assert...
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
def suite():
s1 = unittest.TestLoader().loadTestsFromTestCase(class1)
s2 = unittest.TestLoader().loadTestsFromTestCase(class2)
return unittest.TestSuite([s1,s2])
if __name__ == "__main__":
run(suite())
When I ran the suite both of the test classes started a new firefox instance in setup methord.
My question is if it's possible to make the two test classed use the same firefox instance?
I don't want to put them together in one class.
Any ideas?
You can have a setup function that applies to the whole module instead of just to the class as explained here.
In your case, that would be something like:
def setUpModule():
DRIVER = webdriver.Firefox()
def tearDownModule():
DRIVER.quit()
Note that DRIVER is a global variable in this case so that it's available to the objects of all classes.
Also, note that test case ordering might cause that your module setup functions are called multiple times as explained in the documentation:
The default ordering of tests created by the unittest test loaders is to group all tests from the same modules and classes together. This will lead to setUpClass / setUpModule (etc) being called exactly once per class and module. If you randomize the order, so that tests from different modules and classes are adjacent to each other, then these shared fixture functions may be called multiple times in a single test run.
It think this example should make clear when each setup method/function is executed:
import unittest
def setUpModule():
print 'Module setup...'
def tearDownModule():
print 'Module teardown...'
class Test(unittest.TestCase):
def setUp(self):
print 'Class setup...'
def tearDown(self):
print 'Class teardown...'
def test_one(self):
print 'One'
def test_two(self):
print 'Two'
The output from this is:
$ python -m unittest my_test.py
Module setup...
Class setup...
One
Class teardown...
.Class setup...
Two
Class teardown...
.Module teardown...
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK

Categories