Pyunit framework extending the classes of unittest - python

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.

Related

How to cleanup after pytest was run? [duplicate]

I am using selenium for end to end testing and I can't get how to use setup_class and teardown_class methods.
I need to set up browser in setup_class method, then perform a bunch of tests defined as class methods and finally quit browser in teardown_class method.
But logically it seems like a bad solution, because in fact my tests will not work with class, but with object. I pass self param inside every test method, so I can access objects' vars:
class TestClass:
def setup_class(cls):
pass
def test_buttons(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def test_buttons2(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def teardown_class(cls):
pass
And it even seems not to be correct to create browser instance for class.. It should be created for every object separately, right?
So, I need to use __init__ and __del__ methods instead of setup_class and teardown_class?
According to Fixture finalization / executing teardown code, the current best practice for setup and teardown is to use yield instead of return:
import pytest
#pytest.fixture()
def resource():
print("setup")
yield "resource"
print("teardown")
class TestResource:
def test_that_depends_on_resource(self, resource):
print("testing {}".format(resource))
Running it results in
$ py.test --capture=no pytest_yield.py
=== test session starts ===
platform darwin -- Python 2.7.10, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
collected 1 items
pytest_yield.py setup
testing resource
.teardown
=== 1 passed in 0.01 seconds ===
Another way to write teardown code is by accepting a request-context object into your fixture function and calling its request.addfinalizer method with a function that performs the teardown one or multiple times:
import pytest
#pytest.fixture()
def resource(request):
print("setup")
def teardown():
print("teardown")
request.addfinalizer(teardown)
return "resource"
class TestResource:
def test_that_depends_on_resource(self, resource):
print("testing {}".format(resource))
When you write "tests defined as class methods", do you really mean class methods (methods which receive its class as first parameter) or just regular methods (methods which receive an instance as first parameter)?
Since your example uses self for the test methods I'm assuming the latter, so you just need to use setup_method instead:
class Test:
def setup_method(self, test_method):
# configure self.attribute
def teardown_method(self, test_method):
# tear down self.attribute
def test_buttons(self):
# use self.attribute for test
The test method instance is passed to setup_method and teardown_method, but can be ignored if your setup/teardown code doesn't need to know the testing context. More information can be found here.
I also recommend that you familiarize yourself with py.test's fixtures, as they are a more powerful concept.
This might help http://docs.pytest.org/en/latest/xunit_setup.html
In my test suite, I group my test cases into classes. For the setup and teardown I need for all the test cases in that class, I use the setup_class(cls) and teardown_class(cls) classmethods.
And for the setup and teardown I need for each of the test case, I use the setup_method(method) and teardown_method(methods)
Example:
lh = <got log handler from logger module>
class TestClass:
#classmethod
def setup_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
#classmethod
def teardown_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
def setup_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def teardown_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def test_tc1(self):
<tc_content>
assert
def test_tc2(self):
<tc_content>
assert
Now when I run my tests, when the TestClass execution is starting, it logs the details for when it is beginning execution, when it is ending execution and same for the methods..
You can add up other setup and teardown steps you might have in the respective locations.
Hope it helps!
As #Bruno suggested, using pytest fixtures is another solution that is accessible for both test classes or even just simple test functions. Here's an example testing python2.7 functions:
import pytest
#pytest.fixture(scope='function')
def some_resource(request):
stuff_i_setup = ["I setup"]
def some_teardown():
stuff_i_setup[0] += " ... but now I'm torn down..."
print stuff_i_setup[0]
request.addfinalizer(some_teardown)
return stuff_i_setup[0]
def test_1_that_needs_resource(some_resource):
print some_resource + "... and now I'm testing things..."
So, running test_1... produces:
I setup... and now I'm testing things...
I setup ... but now I'm torn down...
Notice that stuff_i_setup is referenced in the fixture, allowing that object to be setup and torn down for the test it's interacting with. You can imagine this could be useful for a persistent object, such as a hypothetical database or some connection, that must be cleared before each test runs to keep them isolated.
Your code should work just as you expect it to if you add #classmethod decorators.
#classmethod
def setup_class(cls):
"Runs once per class"
#classmethod
def teardown_class(cls):
"Runs at end of class"
See http://pythontesting.net/framework/pytest/pytest-xunit-style-fixtures/
import pytest
class Test:
#pytest.fixture()
def setUp(self):
print("setup")
yield "resource"
print("teardown")
def test_that_depends_on_resource(self, setUp):
print("testing {}".format(setUp))
In order to run:
pytest nam_of_the_module.py -v
I'm not sure I got the specifics of using Selenium in your original questions, but in case you were simply asking about how to use a more classical setUp/tearDown style, Pytest supports most unittest features, so you could do something like:
import unittest
class TestHello(unittest.TestCase):
def setUp(self):
print('running setUp')
def test_one(self):
print('running test_one')
def test_two(self):
print('running test_two')
def tearDown(self):
print('running tearDown')
Which produces:
$ pytest -s -v
====================== test session starts =======================
platform linux -- Python 3.8.2, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /gnu/store/nckjv3ccwdi6096j478gvns43ssbls2p-python-wrapper-3.8.2/bin/python
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/test/.hypothesis/examples')
rootdir: /tmp/test
plugins: hypothesis-5.4.1
collected 2 items
test_hw.py::TestHello::test_one running setUp
running test_one
running tearDown
PASSED
test_hw.py::TestHello::test_two running setUp
running test_two
running tearDown
PASSED

Python unittests, statement before test cases

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

How do I correctly setup and teardown for my pytest class with tests?

I am using selenium for end to end testing and I can't get how to use setup_class and teardown_class methods.
I need to set up browser in setup_class method, then perform a bunch of tests defined as class methods and finally quit browser in teardown_class method.
But logically it seems like a bad solution, because in fact my tests will not work with class, but with object. I pass self param inside every test method, so I can access objects' vars:
class TestClass:
def setup_class(cls):
pass
def test_buttons(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def test_buttons2(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def teardown_class(cls):
pass
And it even seems not to be correct to create browser instance for class.. It should be created for every object separately, right?
So, I need to use __init__ and __del__ methods instead of setup_class and teardown_class?
According to Fixture finalization / executing teardown code, the current best practice for setup and teardown is to use yield instead of return:
import pytest
#pytest.fixture()
def resource():
print("setup")
yield "resource"
print("teardown")
class TestResource:
def test_that_depends_on_resource(self, resource):
print("testing {}".format(resource))
Running it results in
$ py.test --capture=no pytest_yield.py
=== test session starts ===
platform darwin -- Python 2.7.10, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
collected 1 items
pytest_yield.py setup
testing resource
.teardown
=== 1 passed in 0.01 seconds ===
Another way to write teardown code is by accepting a request-context object into your fixture function and calling its request.addfinalizer method with a function that performs the teardown one or multiple times:
import pytest
#pytest.fixture()
def resource(request):
print("setup")
def teardown():
print("teardown")
request.addfinalizer(teardown)
return "resource"
class TestResource:
def test_that_depends_on_resource(self, resource):
print("testing {}".format(resource))
When you write "tests defined as class methods", do you really mean class methods (methods which receive its class as first parameter) or just regular methods (methods which receive an instance as first parameter)?
Since your example uses self for the test methods I'm assuming the latter, so you just need to use setup_method instead:
class Test:
def setup_method(self, test_method):
# configure self.attribute
def teardown_method(self, test_method):
# tear down self.attribute
def test_buttons(self):
# use self.attribute for test
The test method instance is passed to setup_method and teardown_method, but can be ignored if your setup/teardown code doesn't need to know the testing context. More information can be found here.
I also recommend that you familiarize yourself with py.test's fixtures, as they are a more powerful concept.
This might help http://docs.pytest.org/en/latest/xunit_setup.html
In my test suite, I group my test cases into classes. For the setup and teardown I need for all the test cases in that class, I use the setup_class(cls) and teardown_class(cls) classmethods.
And for the setup and teardown I need for each of the test case, I use the setup_method(method) and teardown_method(methods)
Example:
lh = <got log handler from logger module>
class TestClass:
#classmethod
def setup_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
#classmethod
def teardown_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
def setup_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def teardown_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def test_tc1(self):
<tc_content>
assert
def test_tc2(self):
<tc_content>
assert
Now when I run my tests, when the TestClass execution is starting, it logs the details for when it is beginning execution, when it is ending execution and same for the methods..
You can add up other setup and teardown steps you might have in the respective locations.
Hope it helps!
As #Bruno suggested, using pytest fixtures is another solution that is accessible for both test classes or even just simple test functions. Here's an example testing python2.7 functions:
import pytest
#pytest.fixture(scope='function')
def some_resource(request):
stuff_i_setup = ["I setup"]
def some_teardown():
stuff_i_setup[0] += " ... but now I'm torn down..."
print stuff_i_setup[0]
request.addfinalizer(some_teardown)
return stuff_i_setup[0]
def test_1_that_needs_resource(some_resource):
print some_resource + "... and now I'm testing things..."
So, running test_1... produces:
I setup... and now I'm testing things...
I setup ... but now I'm torn down...
Notice that stuff_i_setup is referenced in the fixture, allowing that object to be setup and torn down for the test it's interacting with. You can imagine this could be useful for a persistent object, such as a hypothetical database or some connection, that must be cleared before each test runs to keep them isolated.
Your code should work just as you expect it to if you add #classmethod decorators.
#classmethod
def setup_class(cls):
"Runs once per class"
#classmethod
def teardown_class(cls):
"Runs at end of class"
See http://pythontesting.net/framework/pytest/pytest-xunit-style-fixtures/
import pytest
class Test:
#pytest.fixture()
def setUp(self):
print("setup")
yield "resource"
print("teardown")
def test_that_depends_on_resource(self, setUp):
print("testing {}".format(setUp))
In order to run:
pytest nam_of_the_module.py -v
I'm not sure I got the specifics of using Selenium in your original questions, but in case you were simply asking about how to use a more classical setUp/tearDown style, Pytest supports most unittest features, so you could do something like:
import unittest
class TestHello(unittest.TestCase):
def setUp(self):
print('running setUp')
def test_one(self):
print('running test_one')
def test_two(self):
print('running test_two')
def tearDown(self):
print('running tearDown')
Which produces:
$ pytest -s -v
====================== test session starts =======================
platform linux -- Python 3.8.2, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /gnu/store/nckjv3ccwdi6096j478gvns43ssbls2p-python-wrapper-3.8.2/bin/python
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/test/.hypothesis/examples')
rootdir: /tmp/test
plugins: hypothesis-5.4.1
collected 2 items
test_hw.py::TestHello::test_one running setUp
running test_one
running tearDown
PASSED
test_hw.py::TestHello::test_two running setUp
running test_two
running tearDown
PASSED

Python nose setup/teardown class fixture method not executed for test generators

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

Unittest setUp/tearDown for several tests

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

Categories

Resources