How can I get currently running testcase name, while in the testsuite collection there are 16 testcases. Tests are executed sequentially (in the order of adding test to the testSuite collection). When I add all tests to testSuite collection I can preview this object but how can I get currently executing test while tests are running. Maybe some variable holds this information?
example:
def suite():
testSuite= unittest.TestSuite()
testSuite.addTest(FlightsTestCases('test_sel__reservation_one_way_wizzair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_wizzair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_round_wizzair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_tair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_round_tair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_wizzair_credit_card'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_tair_credit_card'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_round_wizzair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_wizzair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_easyjet_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_ryanair_transfer'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_round_ryanair_credit_card'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_tair_duplicated'))
testSuite.addTest(FlightsTestCases('test_reservation_wrong_card_lowcost'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_tair_credit_card'))
testSuite.addTest(FlightsTestCases('test_sel_reservation_one_way_tair_wrong_credit_card'))
return testSuite
if __name__ == "__main__":
result = unittest.TextTestRunner(verbosity=2).run(suite())
sys.exit(not result.wasSuccessful())
Tests are executed using Selenium-RC framework.
unittest.TestCase.shortDescription()
Returns a description of the test, or None if no description has been provided. The default implementation of this method returns the first line of the test method’s docstring, if available, or None.
unittest.TestCase.id()
Return a string identifying the specific test case. This is usually the full name of the test method, including the module and class name.
Hopefully one of those is useful for your needs.
unittest.TestCase._testMethodName
Example code:
import unittest
class BasicTests(unittest.TestCase):
def test_print(self):
print(self._testMethodName)
Related
I have a handful of fixtures in conftest.py that work well inside actual test functions. However, I would like to parameterize some tests using pytest_generate_tests() based on the data in some of these fixtures.
What I'd like to do (simplified):
-- conftest.py --
# my fixture returns a list of device names.
#pytest.fixture(scope="module")
def device_list(something):
return ['dev1', 'dev2', 'dev3', 'test']
-- test001.py --
# generate tests using the device_list fixture I defined above.
def pytest_generate_tests(metafunc):
metafunc.parametrize('devices', itertools.chain(device_list), ids=repr)
# A test that is parametrized by the above function.
def test_do_stuff(devices):
assert "dev" in devices
# Output should/would be:
dev1: pass
dev2: pass
dev3: pass
test: FAIL
Of course, the problem I'm hitting is that in pytest_generate_tests(), it complains that device_list is undefined. If I try to pass it in, pytest_generate_tests(metafunc, device_list), I get an error.
E pluggy.callers.HookCallError: hook call must provide argument 'device_list'
The reason I want to do this is that I use that device_list list inside a bunch of different tests in different files, so I want to use pytest_generate_tests() to parametrize tests using the same list.
Is this just not possible? What is the point of using pytest_generate_tests() if I have to duplicate my fixtures inside that function?
From what I've gathered over the years, fixtures are pretty tightly coupled to pytest's post-collection stage. I've tried a number of times to do something similar, and it's never really quite worked out.
Instead, you could make a function that does the things your fixture would do, and call that inside the generate_tests hook. Then if you need it still as a fixture, call it again (or save the result or whatever).
#pytest.fixture(scope="module", autouse=True)
def device_list(something):
device_list = ['dev1', 'dev2', 'dev3', 'test']
return device_list
By using autouse=True in the pytest fixture decorator you can ensure that pytest_generate_tests has access to device_list.
This article somehow provides a workaround.
Just have a look at section Hooks at the rescue, and you're gonna get this:
import importlib
def load_tests(name):
# Load module which contains test data
tests_module = importlib.import_module(name)
# Tests are to be found in the variable `tests` of the module
for test in tests_module.tests.iteritems():
yield test
def pytest_generate_tests(metafunc):
"""This allows us to load tests from external files by
parametrizing tests with each test case found in a data_X
file
"""
for fixture in metafunc.fixturenames:
if fixture.startswith('data_'):
# Load associated test data
tests = load_tests(fixture)
metafunc.parametrize(fixture, tests)
See, here it is loading the data by invoking the fixture that is prefixed with data_.
I am trying to import a class, than test a method (production_warning) from that class by passing in values 'stage', 'prod' to see if it returns the expected results.
import runner
test=runnerData(force_redeploy=False, pfactor=None, preview=True)
def production_warning_test():
assert.test.production_warning('stage') not errors
assert.test.production_warning('prod') contains "warning"
#run unit test
productionwarningtest()
I am clearly using assert completely wrong here, how do I properly accomplish what I'm trying to do with assert.
To do this with asserts, you'd want to change your assert statements to something like:
assert test.production_warning('stage') is not errors
assert test.production_warning('prod') contains "warning"
I'd highly recommend looking into the python unit test module instead though.
In which case you'd want something like this (note runnerData will need to be in scope, I'm just copying from your question above):
import runner
import unittest
class TestRunner(unittest.TestCase):
def setUp(self):
self.test = runnerData(force_redeploy=False, pfactor=None, preview=True)
def test_production_warning(self):
self.assertTrue(self.test.production_warning('stage') is not errors)
self.assertTrue(self.test.production_warning('prod') contains "warning")
if __name__ == '__main__':
unittest.main()
I'm trying to promote our a team to migrate to py.test from unittest in hope that less boilerplate and faster runs will reduce accuses as to why they don't write as much unittests as they should.
One problem we have is that almost all of our old django.unittest.TestCase fail due to errors. Also, most of them are really slow.
We had decided that the new test system will ignore the old tests, and will be used for new tests only. I tried to get py.test to ignore old tests by creating the following in conftest.py:
def pytest_collection_modifyitems(session, config, items):
print ("Filtering unittest.TestCase tests")
selected = []
for test in items:
parent = test.getparent(pytest.Class)
if not parent or not issubclass(parent.obj, unittest.TestCase) or hasattr(parent.obj, 'use_pytest'):
selected.append(test)
print("Filtered {} tests out of {}".format(len(items) - len(selected), len(items)))
items[:] = selected
Problem is, it filters all tests, also this one:
import pytest
class SanityCheckTest(object):
def test_something(self):
assert 1
Using some different naming pattern for the new tests would be a rather poor solution.
My test class did not conform to the naming convention. I change it to:
import pytest
class TestSanity(object):
def test_something(self):
assert 1
And also fixed a bug in my pytest_collection_modifyitems and it works.
I am just getting started with Django, so this may be something stupid, but I am not even sure what to google at this point.
I have a method that looks like this:
def get_user(self,user):
return Utilities.get_userprofile(user)
The method looks like this:
#staticmethod
def get_userprofile(user):
return UserProfile.objects.filter(user_auth__username=user)[0]
When I include this in the view, everything is fine. When I write a test case to use any of the methods inside the Utility class, I get None back:
Two test cases:
def test_stack_overflow(self):
a = ObjName()
print(a.get_user('admin'))
def test_Utility(self):
print(Utilities.get_user('admin'))
Results:
Creating test database for alias 'default'...
None
..None
.
----------------------------------------------------------------------
Can someone tell me why this is working in the view, but not working inside of the test case and does not generate any error messages?
Thanks
Verify whether your unit test comply the followings,
TestClass must be written in a file name test*.py
TestClass must have been subclassed from unittest.TestCase
TestClass should have a setUp function to create objects(usually done in this way, but objects creation can happen in the test functions as well) in the database
TestClass functions should start with test so as to be identified and run by the ./manage.py test command
TestClass may have tearDown to properly end the unit test case.
Test Case Execution process:
When you run ./manage.py test django sets up a test_your_database_name and creates all the objects mentioned in the setUp function(Usually) and starts executing the test functions in the order of placement inside the class and once when all the test functions are executed, finally looks for the tearDown function executes if any present in the test class and destroys the test database.
It may be because that you might not have invoked objects creation in setUp function or elsewhere in the TestClass.
Can you kindly post the entire traceback and test file to help you better?
I have a folder with python scripts that contain doc tests that I want to do unit tests on. When I try to test it with one file like this:
import unittest
suite = unittest.TestSuite()
suite.addTest('/homes/ndeklein/workspace/MS/PyMS/pyMS/baseFunctions.py')
unittest.TextTestRunner().run(suite)
I get this error:
TypeError: the test to add must be callable
However, when I do it from the commandline
python '/homes/ndeklein/workspace/MS/PyMS/pyMS/baseFunctions.py'
it works.
How can I make my file callable?
addTest takes a TestCase or a TestSuite - and you're passing in a string.
Have a look at the docs here:
http://docs.python.org/library/unittest.html
It's not clear exactly what you want to do - but if baseFunctions.py defines a subclass of TestCase, you could try this:
import unittest
from baseFunctions import MyTestCase
suite = unittest.TestSuite()
suite.addTest(MyTestCase)
unittest.TextTestRunner().run(suite)