Can "attrib" of nosetests work with "__init__()" function in Python - python

I have a simple Python class here which has 3 functions. "test_a" (attr=slow), "test_b" (attr=fast) and init(). The print statement in init() does not get called irrespective of whether I use "attr" in it or not. How can I have init() also called? Or is it even possible to do it with nosetests?
from testconfig import config as c
from nose.plugins.attrib import attr
class TestMe(object):
#attr(speed='slow')
def __init__(self):
print "I am inside init of test_me"
#attr(speed='slow')
def test_a(self):
assert 'c' == 'c'
print "I am here_a"
#attr(speed='fast')
def test_b(self):
assert 'c' == 'c'
print "I am here_b"

__init__ isn't a test, so nosetests ignores the attribute. That function must run in order to instatiate the class in order to run test_b. I think you are not seeing the output because you aren't running nosetests with the -s option. Here's the output I get with that option and setting speed to "fast":
% nosetests -s -a speed=fast tmp.py
I am inside init of test_me
I am here_b
.
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK

Related

#cached_property doctest is not detected

I have a code. a.py
from functools import cached_property, cache
import doctest
class C1:
def test_1(self):
"""
>>> C1().test_1()
'f'
"""
return "f"
#property
def test_2(self):
"""
>>> C1().test_2
'p'
"""
return "p"
#cached_property
def test_3(self):
"""
>>> C1().test_3
'cp'
"""
return "cp"
#cache
def test_4(self):
"""
>>> C1().test_4()
'c'
"""
return "c"
doctest.testmod()
test_3 is a function decorated by #cached_property.
It has a doctest. but that was not executed.
$ python3 a.py -v
Trying:
C1().test_1()
Expecting:
'f'
ok
Trying:
C1().test_2
Expecting:
'p'
ok
Trying:
C1().test_4()
Expecting:
'c'
ok
2 items had no tests:
__main__
__main__.C1
3 items passed all tests:
1 tests in __main__.C1.test_1
1 tests in __main__.C1.test_2
1 tests in __main__.C1.test_4
3 tests in 5 items.
3 passed and 0 failed.
Test passed.
How can I run test_3 doctest?
Environment
$ python3 --version
Python 3.9.6
$ uname
Darwin
The problem is likely caused by a difference in the implementation of cache and cached_property. Namely, cache sets __module__ whereas cached_property does not:
>>> from functools import cache, cached_property
>>> #cache
... def f(): pass
...
>>> #cached_property
... def g(): pass
...
>>> f.__module__
'__main__'
>>> g.__module__
'functools'
Functions that are not defined in the current __module__ are ignored by doctesting. This is intentional since otherwise all the doctests of the methods that you import at the top of the file would run. However, in this case, this seems like a bug to me.
One can explicitly add a method (or class) to the doctests for a module by adding it to __test__, so in your case this should do the trick:
__test__= { "C1.test_3": C1.test_3 }
To fix this in Python, one should probably add self.__module__ = func.__module__ to this initializer and maybe all the others that update_wrapper() sets for #cache. But maybe this has unintended side effects and that's why this was not set in the first place.

Python : is coverage using skipped test

Here is a test :
#skip("my test is skipped")
def test_coverage():
my_function()
My question is simple :
If i run my coverage, will my_function will be covered or not (considering my test is skipped) ?
Thanks !
Skipped tests are not executed. Code that is not executed is not covered, by definition.
Demo; given a coverage_demo module:
def foo():
var = "This function has is covered"
def bar():
var = "This function is not"
and a coverage_demo_tests.py file:
from unittest import TestCase, skip
import coverage_demo
class DemoTests(TestCase):
def test_foo(self):
coverage_demo.foo()
#skip("No bar for us today")
def test_bar(self):
import coverage_demo
coverage_demo.bar()
if __name__ == '__main__':
import unittest
unittest.main()
running this under coverage shows that line 5 in coverage_demo is not executed:
$ coverage run coverage_demo_tests.py
s.
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK (skipped=1)
$ coverage report --include=coverage_demo\.py -m
Name Stmts Miss Cover Missing
------------------------------------------------
coverage_demo.py 4 1 75% 5
The def statements at the top level are always executed, but line 5 is the only line in the bar() function.

How to pass extra arguments to my py.test setup method?

I need to setup tests depending on where or how I want to run py.test tests. I want to be able to do something like this
py.test --do_this
py.test --do_that
and retrieve the values in the setup method of a test class
class TestSuite(object):
def setup(self):
if (do_this):
...
Something like that. Can this be done? And if so, how?
From the documentation, you can add arguments to the pytest caller
# content of test_sample.py
def test_answer(do):
if do == "this":
print ("do this option")
elif do == "that":
print ("do that option")
assert 0 # to see what was printed
# content of conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption("--do", action="store", default="that",
help="my option: this or that")
#pytest.fixture
def do(request):
return request.config.getoption("--do")
Then, you can call pytest as pytest -q test_sample.py to get the default case with that and pytest -q --do=this for the other case

Setup and teardown functions executed once for all nosetests tests

How to execute setup and teardown functions once for all nosetests tests?
def common_setup():
#time consuming code
pass
def common_teardown():
#tidy up
pass
def test_1():
pass
def test_2():
pass
#desired behavior
common_setup()
test_1()
test_2()
common_teardown()
Note that there exists a similar question with an answer that is not working with python 2.7.9-1, python-unittest2 0.5.1-1 and python-nose 1.3.6-1 after replacing the dots with pass and adding the line import unittest.
Unfortunately my reputation is too low to comment on that.
You can have a module level setup function. According to nose documentation:
Test modules offer module-level setup and teardown; define the method
setup, setup_module, setUp or setUpModule for setup, teardown,
teardown_module, or tearDownModule for teardown.
So, more specifically, for your case:
def setup_module():
print "common_setup"
def teardown_module():
print "common_teardown"
def test_1():
print "test_1"
def test_2():
print "test_2"
Running test gives you:
$ nosetests common_setup_test.py -s -v
common_setup
common_setup_test.test_1 ... test_1
ok
common_setup_test.test_2 ... test_2
ok
common_teardown
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
It does not matter which name you choose, so both setup and setup_module would work the same, but setup_module has more clarity to it.

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

Categories

Resources