In Python, how can I have one setup (which may contain expensive function calls) for a whole set of unit tests?
Example:
import unittest
class Test1(unittest.TestCase):
def setUp(self):
print "expensive call"
def test1(self):
self.assertEqual(1, 1)
def test2(self):
self.assertEqual(1, 1)
if __name__ == "__main__":
unittest.main()
Will run the expensive call twice:
$ python unittest.py
expensive call
.expensive call
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
How can I change it so the expensive call is made only once and its resources accessible to all tests?
UPDATE: I'm using Python 2.6.
You can use setUpClass
import unittest
class Test(unittest.TestCase):
#classmethod
def setUpClass(cls):
print 'setUpClass'
cls.data = 123
def test_one(self):
print 'test_one'
print self.data
def test_two(self):
print 'test_two'
if __name__ == "__main__":
unittest.main()
See http://docs.python.org/library/unittest.html#unittest.TestCase.setUpClass
UPDATE:
For python 2.6, I suppose you could use class-level attributes:
class Test(unittest.TestCase):
value = result_of_some_expensive_function()
def test(self):
print self.value
That function will run once when your test is defined.
Related
I have one class BaseTest and all tests are extended from it.
Tests are located in different modules and packages.
setUpClass and tearDownClass methods are executed before each unittest.TestCase class.
How can I execute setUp and tearDown only once. Before and after all tests.
this is example of code:
import unittest
class BaseTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
print("setUpClass")
#classmethod
def tearDownClass(cls):
print("tearDownClass")
if __name__ == '__main__':
unittest.main()
module2.py:
class TestOne(BaseTest):
def test_one(self):
print("Test One")
class TestTwo(BaseTest):
def test_two(self):
print("Test Two")
if __name__ == '__main__':
unittest.main()
module3.py
class TestThree(BaseTest):
def test_three(self):
print("Test Three")
class TestFour(BaseTest):
def test_four(self):
print("Test Four")
if __name__ == '__main__':
unittest.main()
module4.py
class TestFive(BaseTest):
def test_five(self):
print("Test Five")
if __name__ == '__main__':
unittest.main()
I don't think unittest has a facility for universal setup and teardown. You should look into pytest, its fixtures are more powerful.
its possible to do with unittest copy the answer from https://stackoverflow.com/a/64892396/2679740 here
you can do it by defining startTestRun,stopTestRun of unittest.TestResult class.
by adding following code to my tests/__init__.py i managed to achieve it. this code runs only once for all tests(regardless of number of test classes and test files).
def startTestRun(self):
"""
https://docs.python.org/3/library/unittest.html#unittest.TestResult.startTestRun
Called once before any tests are executed.
:return:
"""
DockerCompose().start()
setattr(unittest.TestResult, 'startTestRun', startTestRun)
def stopTestRun(self):
"""
https://docs.python.org/3/library/unittest.html#unittest.TestResult.stopTestRun
Called once after all tests are executed.
:return:
"""
DockerCompose().compose.stop()
setattr(unittest.TestResult, 'stopTestRun', stopTestRun)
Imagine I have tests like that:
import unittest
class MyTests(unittest.TestCase):
print("Starting")
def test_first(self):
.....
Is the print statement guaranteed to be executed before test_first() and the rest? From what I've seen it does get executed first, but are there any edge cases?
You can use setUp()(docs) and setUpClass()(docs) methods for this. The setUp() method is executed before each individual test while the setUpClass() method is executed before all the tests in this class run.
import unittest
class MyTests(unittest.TestCase):
#classmethod
def setUpClass(cls):
print("Starting all the tests.")
def setUp(self):
print("Starting another test.")
def test_first(self):
...
In a hobby project I intend to use nose for testing, I want to put all tests for specific classes into classes since these tests share setup and other functionality. But I can't seem to get nose to execute the setup methods inside the classes.
Here is an example class that is tested:
class mwe():
def __init__(self):
self.example = ""
def setExample(self, ex):
self.example = ex
The tests work, when I don't use classes:
from nose.tools import ok_
import mwe
exampleList = []
def setUp():
print("setup")
exampleList.append("1")
exampleList.append("2")
exampleList.append("3")
def test_Example():
print("test")
for ex in exampleList:
t = mwe.mwe()
t.setExample(ex)
yield check, t, ex
def check(e, ex):
ok_(e.example == ex)
The output is as expected:
setup
test
...
----------------------------------------------------------------------
Ran 3 tests in 0.004s
OK
When a test class is used, the setup method is not executed and therefore no tests are executed.
from nose.tools import ok_
import mwe
class TestexampleClass(object):
def __init__(self):
print("__init__")
self.exampleList = []
def setup(self):
print("setup class")
self.exampleList.append("1")
self.exampleList.append("2")
self.exampleList.append("3")
def test_ExampleClass(self):
print("test class")
for ex in self.exampleList:
t = mwe.mwe()
t.setExample(ex)
yield self.check, t, ex
def check(self, we, ex):
print("check class")
ok_(we.example == ex)
I'm fairly new to python and a newbie with nose, my question is, why is setup not executed? Where is the error in my code?
__init__
test class
----------------------------------------------------------------------
Ran 0 tests in 0.002s
OK
I will be glad for any feedback.
When I use the code from this Question on SO the setup method is executed, as I would expect it.
SOLUTION: After a lot of desperation I found the following:
Nose executes the the class level setup method before the execution of the yielded function, not when the test_* methods are called, as I expected and as is the case for other test_* methods. This obviously goes against the nose documentation:
Setup and teardown functions may be used with test generators. However, please note that setup and teardown attributes attached to the generator function will execute only once. To execute fixtures for each yielded test, attach the setup and teardown attributes to the function that is yielded, or yield a callable object instance with setup and teardown attributes.
Looking at the bug reports, I found the bug report on github.
A possible workaround is to use class level fixtures:
#classmethod
def setup_class(cls):
#do stuff
pass
Your test class needs to extend TestCase and the setup method needs to be called setUp
from unittest import TestCase
class TestUtils(TestCase):
def setUp(self):
self.x = 1
def test_something(self):
self.assertEqual(1, self.x)
which outputs
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
In Pyunit framework, I have question as below:
import unittest
class xyz(object):
def test_fuc(self):
print "test_fun"
pass
class abc(unittest.Testcase, xyz):
def setUp(self):
print "setUp"
def tearDown(self):
print "tearDown"
def test_one(self):
print "test_one"
pass
def test_two(self):
print "test_two"
pass
Output:
test_one
test_two
test_fun
but I need output like below:
test_one
test_fun
test_two
test_fun
Please suggest, How do I do it?
Unit tests (ie. unittest.TestCase methods) are supposed to be independant, and thus there is no point of running them twice.
If you want to do that, you probably should design your tests another way.
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