AttributeError: module 'unittest' has no attribute 'Testcase' - python

I am new with python, i am trying to fllow the tutorial on youtube https://www.youtube.com/watch?v=6tNS--WetLI&t=168s
I have the error message
code:
import unittest
import calc
class TestCalc(unittest.Testcase):
def test_add(self):
result=calc.add(10,5)
self.assertEqual(result,15)
suite = unittest.TestLoader().loadTestsFromTestCase(TestCalc)
unittest.TextTestRunner(verbosity=2).run(suite)
I already seen all the answer on stackoverflow but the error resist.
Please help

You did a typo when writing the class name. It is with capitalized case TestCase, like you can see in the documentation.

Related

Can anyone help me howto import a module class?

I have a module example.py with the follow class:
class add:
def __init__(self, x, y):
self.x= x
self.y= y
def adding_two_nbr(self):
return self.x*self.y
when I import the module as the following i got error:
import example
obj = example.add(1,2)
obj.adding_two_nbr()
error:
AttributeError: 'add' object has no attribute 'adding_two_nbr'
The code works for me smoothly. Change the second block of code as
import example
obj = example.add(1,2)
print(obj.adding_two_nbr())
Save this file as import_file.py in the same directory as example.py and run import_file.py.
I think add class is already defined in python module so you need to change to another name
AttributeError: 'add' object has no attribute 'adding_two_nbr'
adding_two_nbr not defined in python add module.

How to patch a module that hasn't been imported by parent package's __init__.py

I'm trying to test a tool I'm building which uses some jMetalPy functionality. I had/have a previous version working but I am now trying to refactor out some external dependencies (such as the aforementioned jMetalPy).
Project Code & Structure
Here is a minimalist structure of my project.
MyToolDirectory
¦--/MyTool
¦----/__init__.py
¦----/_jmetal
¦------/__init__.py
¦------/core
¦--------/quality_indicator.py
¦----/core
¦------/__init__.py
¦------/run_manager.py
¦----/tests
¦------/__init__.py
¦------/test_run_manager.py
The _jmetal directory is to remove external dependency on the jMetalPy package - and I have copied only the necessary packages/modules that I need.
Minimal contents of run_manager.py
# MyTool\core\run_manager.py
import jmetal
# from jmetal.core.quality_indicators import HyperVolume # old working version
class RunManager:
def __init__(self):
pass
#staticmethod
def calculate_hypervolume(front, ref_point):
if front is None or len(front) < 1:
return 0.
hv = jmetal.core.quality_indicator.HyperVolume(ref_point)
# hv = HyperVolume(ref_point)
hypervolume = hv.compute(front)
return hypervolume
Minimal contents of test_run_manager.py
# MyTool\tests\test_run_manager.py
import unittest
from unittest.mock import MagicMock, Mock, patch
from MyTool import core
class RunManagerTest(unittest.TestCase):
def setUp(self):
self.rm = core.RunManager()
def test_calculate_hypervolume(self):
ref_points = [0.0, 57.5]
front = [None, None]
# with patch('MyTool.core.run_manager.HyperVolume') as mock_HV: # old working version
with patch('MyTool.core.run_manager.jmetal.core.quality_indicator.HyperVolume') as mock_HV:
mock_HV.return_value = MagicMock()
res = self.rm.calculate_hypervolume(front, ref_points)
mock_HV.assert_called_with(ref_points)
mock_HV().compute.assert_called_with(front)
Main Question
When I run a test with the code as-is, I get this error message:
E ModuleNotFoundError: No module named 'MyTool.core.run_manager.jmetal'; 'MyTool.core.run_manager' is not a package
But when I change it to:
with patch('MyTool.core.run_manager.jmetal.core') as mock_core:
mock_HV = mock_core.quality_indicator.HyperVolume
mock_HV.return_value = MagicMock()
res = self.rm.calculate_hypervolume(front, ref_points)
mock_HV.assert_called_with(ref_points)
mock_HV().compute.assert_called_with(front)
... now the test passes. What gives?!
Why can't (or rather, how can) I surgically patch the exact class I want (i.e., HyperVolume) without patching out an entire sub-package as well? Is there a way around this? There may be code in jmetal.core that needs to run normally.
Is the reason this isn't working only because there is no from . import quality_indicator statement in jMetalPy's jmetal\core\__init__.py ?
Because even with patch('MyTool.core.run_manager.jmetal.core.quality_indicator) throws:
E AttributeError: <module 'jmetal.core' from 'path\\to\\venv\\lib\\site-packages\\jmetal\\core\\__init__.py'> does not have the attribute 'quality_indicator'
Or is there something I'm doing wrong?
In the case that it is just about adding those import statements, I could do that in my _jmetal sub-package, but I was hoping to let the user default to their own jMetalPy installation if they already had one by adding this to MyTool\__init__.py:
try:
import jmetal
except ModuleNotFoundError:
from . import _jmetal as jmetal
and then replacing all instances of import jmetal with from MyTool import jmetal. However, I'd run into the same problem all over again.
I feel that there is some core concept I am not grasping. Thanks for the help.

module "twitter" has no attribute "Twitter"

I have the following file, twitter.py, which defines a class called Twitter:
class Twitter:
data = {}
def __init__(self):
pass
def tweet(self):
print("I'm tweeting")
And I have another file, main.py, in the same directory as twitter.py which imports twitter and attempts to instantiate the class:
import twitter
twitterObj = twitter.Twitter()
Unfortunately, Python throws the error message: AttributeError: module 'twitter' has no attribute 'Twitter'
What am I doing wrong?
Can't reproduce this error on my machine. I'm assuming you have a module with the name "twitter" installed to your python path that is overriding the project file. Try renaming twitter.py.

import file by url route python

Im trying to import files on Flask app in base of url route. I started to coding python few days ago so i havent idea if i doing it well. I write this on :
#app.route('/<file>')
def call(file):
__import__('controller.'+file)
hello = Example('Hello world')
return hello.msg
And i have other file called example.py into a controller folder that contains this:
class Example:
def __init__(self, msg):
self.msg = msg
So i start from terminal the app and i try to enter to localhost:5000/example.
Im trying to show in screen Hello world but give me the next error:
NameError: global name 'Example' is not defined
Thanks for all!
__import__ returns the newly imported module; names from that module are not added to your globals, so you need to get the Example class as an attribute from the returned module:
module = __import__('controller.'+file)
hello = module.Example('Hello world')
__import__ is rather low-level, you probably want to use importlib.import_module() instead:
import importlib
module = importlib.import_module('controller.'+file)
hello = module.Example('Hello world')
If you need to dynamically get the classname too, use getattr():
class_name = 'Example'
hello_class = getattr(module, class_name)
hello = hello_class('Hello world')
The Werkzeug package (used by Flask) offers a helpful functions here: werkzeug.utils.import_string() imports an object dynamically:
from werkzeug.utils import import_string
object_name = 'controller.{}:Example'.format(file)
hello_class = import_string(object_name)
This encapsulates the above process.
You'll need to be extremely careful with accepting names from web requests and using those as module names. Please do sanitise the file argument and only allow alphanumerics to prevent relative imports from being used.
You could use the werkzeug.utils.find_modules() function to limit the possible values for file here:
from werkzeug.utils import find_modules, import_string
module_name = 'controller.{}'.format(file)
if module_name not in set(find_modules('controller')):
abort(404) # no such module in the controller package
hello_class = import_string(module_name + ':Example')
I think you might not add the directory to the file, add the following code into the previous python program
# Add another directory
import sys
sys.path.insert(0, '/your_directory')
from Example import Example
There are two ways for you to do imports in Python:
import example
e = example.Example('hello world')
or
from example import Example
e = Example('hello world')

Error when trying to use `assert not mock.method.called`

I'm trying to assert that a method is not called using Python Mock. Unfortunately, I can't seem to get past this error:
AttributeError: MockCallable instance has no attribute 'called'
I'm running Python 2.7.1 and Python Mock 0.1.0 for my tests. Google says: No results found for "AttributeError: MockCallable instance has no attribute 'called'". How can I resolve this error?
Here's the test:
import unittest2
import main
from mock import Mock
class TestCli(unittest2.TestCase):
def setUp(self):
self.mockView = Mock()
self.mockFriendManager = Mock()
self.mockedCli = main.CLI(self.mockView, self.mockFriendManager)
[...]
def testCliDoesntGetFriendPropertiesWhenNotSelected(self):
view = Mock( { "requestResponse":2 } )
friendManager = Mock()
cli = main.CLI(view, friendManager)
cli.outputMenu()
assert not friendManager.getFriendProperties.called, 'hello'
You must update you mock library by pip. Attribute called was introduced in 0.4.0 as you can see in http://www.voidspace.org.uk/python/mock/changelog.html#version-0-4-0
Anyway by update it you will get a lot of more useful facilities and tools.

Categories

Resources