class MyTests(unittest.TestCase):
def SetUp(self):
""" Setting up expected default values """
self.test = RandomTest()
def testReturnsArrayWithTuples(self):
result = self.test.next() # Error
self.assert_(len(result), 5)
if __name__ == "__main__":
unittest.main()
I have a basic test, but it fails with this error message:
AttributeError: 'MyTests' object has no attribute 'test'
Eclipse intellisense is showing me self.test though. What am I missing please?
Ok, its quite embarrassing, as it was just a typo. :)
def SetUp(self): has to be lowercase def setUp(self): in order to be found and executed.
I hope it prevents someone else chasing ghosts like I did.
Related
I am not able to explain the behaviour of the following code when running it in PyCharm:
class Empty:
def __init__(self):
pass
def __str__(self):
print('in!')
return f'<{__name__}.Empty object at {hex(id(self))!r}>'
if __name__ == '__main__':
e = Empty()
The output:
in!
in!
There is no output when running the code from the terminal like this python .\my_script.py. May someone have an explanation for this? Thanks!
I am going to attach two blocks of code, the first is the main code that is ran the second is the testClass file containing a sample class for testing purposes. To understand what's going on it's probably easiest to run the code on your own. When I call sC.cls.print2() it says that the self parameter is unfulfilled. Normally when working with classes, self (in this case) would be sC.cls and you wouldn't have to pass it as a parameter. Any advice is greatly appreciated on why this is occuring, I think it's something to do with exec's scope but even if I run this function in exec it gives the same error and I can't figure out a way around it. If you'd like any more info please just ask!
import testClass
def main():
inst = testClass.myClass()
classInfo = str(type(inst)).split()[1].split("'")[1].split('.')
print(classInfo)
class StoreClass:
def __init__(self):
pass
exec('from {} import {}'.format(classInfo[0], classInfo[1]))
sC = StoreClass()
exec('sC.cls = {}'.format(classInfo[1]))
print(sC.cls)
sC.cls.print2()
if __name__ == '__main__':
main()
class myClass:
def printSomething(self):
print('hello')
def print2(self):
print('hi')
I have 92 tests and I want to make sure that no silent errors occurred during the calls.
Unfortunately error handing in OpenGL is not quite good. I want to test if glGetError() returns other then GL_NO_ERROR It is enough if I test it once per TestCase. It would be better if I could add an assert after every test methods. (I don't want to add it manually in 92 methods)
I made an example snippet that shows a solution that is not acceptable since the assert is done in the tearDownClass(cls) method and tearDownClass should not do any testing logic.
How can I add an extra assert after my tests?
The lines with comments show what I wan't to achieve.
import struct
import unittest
import ModernGL
class TestCase(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.ctx = ModernGL.create_standalone_context()
#classmethod
def tearDownClass(cls):
error = cls.ctx.error # Store error in a variable
cls.ctx.release() # Then release the context
cls.assertEqual(error, 'GL_NO_ERROR') # Check if there were errors before the release
def test_1(self):
...
def test_2(self):
...
def test_3(self):
...
if __name__ == '__main__':
unittest.main()
NOTE:
cls.ctx.error is a property (glGetError() as a string) and the possible values are:
"GL_NO_ERROR"
"GL_INVALID_ENUM"
"GL_INVALID_VALUE"
"GL_INVALID_OPERATION"
"GL_INVALID_FRAMEBUFFER_OPERATION"
"GL_OUT_OF_MEMORY"
"GL_STACK_UNDERFLOW"
"GL_STACK_OVERFLOW"
"GL_UNKNOWN_ERROR"
You could do the test in the tearDown (as opposed to tearDownClass) method, as this is a regular instance method:
class TestCase(unittest.TestCase):
def setUp(self):
self.ctx = ModernGL.create_standalone_context()
def tearDown(self):
error = self.ctx.error # Store error in a variable
self.ctx.release() # Then release the context
self.assertEqual(error, 'GL_NO_ERROR') # Check if there were errors before the release
I'm in trouble replacing a python function from a different module with a TestClass
I'm trying to test a part of my code that contains the function in a module; more in details I would like monkey patch this function.
So, the situation is similar to the following:
Function in the module
def function_in_module():
# do some stuff
return 'ok'
Part of my code that I would like testing
from dir_1.dir_2.dir_3.module_name import function_in_module
class ExampleClass():
def __init__(self):
# do some stuff
self.var_x = function_in_module()
# do some stuff again
Test class
from dir_1.dir_2.dir_3 import module_name
class TestClass(TestCase):
de_monkey = {}
mp = None
def setUp(self):
# save original one
self.de_monkey['function_in_module'] = module_name.function_in_module()
if self.mp is None:
self.mp = MP()
def tearDown(self):
# rollback at the end
module_name.function_in_module = self.de_monkey['function_in_module']
def test_string(self):
module_name.function_in_module = self.mp.monkey_function_in_module
test_obj = ExampleClass()
self.assertEqual(test_obj.var_x, 'not ok')
class MP(object):
#staticmethod
def monkey_function_in_module(self):
return 'not ok'
As the assert statement shows, the expected result is 'not ok', but the result is 'ok'.
I have debugged about this and seems that the different way to call the functions is the reason because this monkey patch doesn't work.
In fact, if I try to call the function in ExampleClass in this way
self.var_x = module_name.function_in_module()
works correctly.
What am I missing? maybe it's a banality but it's driving me crazy
Thank you in advance
Your code under test imports function_in_module and references it directly. Changing the value of module_name.function_in_module has no effect on the code.
You should replace the function directly in the module that contains the code under test, not in the source module.
Note that your life would be easier if you used the mock library, although the question of where to patch would still be the same.
Currently I have a function that creates a screenshot and I call it here
def tearDown(self):
self.save_screenshot()
self.driver.quit()
There is also a folder being created which is used to store the screenshots.
I don't want this to happen when the test passes.
What do I have to add in order for this not to happen?
Thanks for all the help
If your test failed, the sys.exc_info will have an exception. So you can use it as pass/fail result of your test:
if sys.exc_info()[0]:
# 'Test Failed'
else:
# 'Test Passed'
And if you want to take a screenshot on failure:
import unittest
import sys
from selenium import webdriver
class UrlTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
def test_correct_url(self):
self.driver.get('https://google.com')
self.assertTrue('something.com' in self.driver.current_url)
def tearDown(self):
if sys.exc_info()[0]:
self.driver.get_screenshot_as_file('screenshot.png')
self.driver.quit
if __name__ == '__main__':
unittest.main()
Here is one way to capture screenshot only when failure:
def setUp(self):
# Assume test will fail
self.test_failed = True
def tearDown(self):
if self.test_failed:
self.save_screenshot()
def test_something(self):
# do some tests
# Last line of the test:
self.test_failed = False
The rationale behind this approach is when the test reaches the last line, we know that the test passed (e.g. all the self.assert* passed). At this point, we reset the test_failed member, which was set to True in the setUp. In tearDown, we now can tell if a test passed or failed and take screenshot when appropriate.
In your initialisation method set a self.NoFailuresSnapped = 0 and check your test environment for the current number of failures being > self.NoFailuresSnapped before calling or within your function and of course set it again before returning.