Code below is unit test I'm writing for a flask app but results in the following error when I run the test:
File "/Users/ausername/projects/term_trader/tt2/tests/testRoutes.py", line 47, in test_deposit_route
response = self.app.post(BASE_URL,
AttributeError: 'TestRoutes' object has no attribute 'app'
Imports look okay to me as I had some other tests running out of a 'tests' folder with no issue. The routes themselves work just fine when I tested them in curl, I'm just trying to get in the habit of writing tests. Just can't seem to figure out what the issue is. This is flask version 1.0.3. Any advise is appreciated.
Code:
from unittest import TestCase
from model.user import User
from model.position import Position
from model.trade import Trade
from flask_app.app import app
from schema import build_user, build_positions, build_trades
import json
import os
BASE_URL = 'http://localhost:5000/api/'
class TestRoutes(TestCase):
def setup(self):
self.app.config['TESTING'] = True
self.app.config['DEBUG'] = False
self.app = app.test_client()
build_user()
build_positions()
build_trades()
bob = User(**{
"user_name": "bobdean",
"password": "password",
"real_name": "Bob Dean",
"balance": 0.0
})
bob.hash_password("password")
bob.api_key = "11111111111111111111"
bob.save()
def tearDown(self):
pass
def test_deposit_route(self):
bob = User.from_pk(1)
self.assertEqual(mike.user_name, "bobdean")
deposit = {"amount":1500.0}
response = self.app.post(BASE_URL,
data=json.dumps(deposit),
content_type='application/json')
self.assertEqual(response.status_code, 201, "Status Code should be 201")
self.assertEqual(bob.balance, 1500.0, "Bob's balance should equal 1500")
You need to rename setup to setUp according to the documentation
Related
I have the following main.py:
...
app = FastAPI(docs_url="/jopapi/documentation", redoc_url=None)
password_encryptor = PasswordEncryptor(
os.environ.get("JUPYTERHUB_COOKIE_SECRET"), fernet=Fernet
)
...
I already tried to use a custom fixture like this:
#mock.patch.dict(os.environ, {"JUPYTERHUB_COOKIE_SECRET": "471bAcmHjbIdu3KLWphYpgXSW1HNC8q7"}, clear=True)
#pytest.fixture(name="client")
def client_fixture():
client = TestClient(app)
yield client
But the following test:
def test_generic(client: TestClient):
response = client.get("/jobapi/generic")
assert response.status_code == 200
still fails, since the environment variable seems not to get set, which results in None
from src.app.main import app
src\app\main.py:38: in <module>
password_encryptor = PasswordEncryptor(
src\app\auth.py:33: in __init__
self.fernet = fernet(self._generate_fernet_key(self.secret))
src\app\auth.py:36: in _generate_fernet_key
bytestring = secret.encode()
E AttributeError: 'NoneType' object has no attribute 'encode'
When I set the env variable in the main.py file per hand, it works. How can I fix this?
I think you need to create a .env at the root of your project and then read that file using python's dotenv, so finally you can easily use it with os.environ.get() later in your main.py file,
.env
JUPYTERHUB_COOKIE_SECRET=471bAcmHjbIdu3KLWphYpgXSW1HNC8q7
main.py
import os
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, ".env"))
app = FastAPI(docs_url="/jopapi/documentation", redoc_url=None)
password_encryptor = PasswordEncryptor(
os.environ.get("JUPYTERHUB_COOKIE_SECRET"), fernet=Fernet
)
I have a problem with getting response in django testing
this is the problem appear in terminal
self.assertEquals(self.response.status_code, 200)
AttributeError: 'StoreCreateTest' object has no attribute 'response'
This is the command
py manage.py test
This is my def
def test_store_create_view_status_code(self):
self.assertEquals(self.response.status_code, 200)
and this is my import
from django.test import TestCase
from configuration.models import Stores
please help me getting this.
I watched this tutorial on YouTube https://www.youtube.com/watch?v=6wxO8hRIP4w and it helped me in a way but the tutorial lacks on how to test a Django Model.
Here's the code I've got so far:
conftest.py
import pytest
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
#pytest.fixture(name="homepage")
def fixture_homepage(function_scoped_container_getter) -> str:
service = function_scoped_container_getter.get('app').network_info[1]
base_url = f"http://{service.hostname}:{service.host_port}"
retry = Retry(
total = 30,
backoff_factor=10,
status_forcelist = [500, 502, 503, 504]
)
session = requests.Session()
session.mount('http://', HTTPAdapter(max_retries=retry))
return base_url
first_test.py
from requests import get
pytest_plugins = ["docker_compose"]
def test_one():
assert 1==1
def test_initial_ticket(homepage: str):
print("HOMEPAGE: ", homepage)
temp_str = get(homepage+"/admin").text
#check if the pytest can already open the admin login page
assert "Admin Login" in temp_str
When I run pytest integration_tests/initial_user_receipt_test.py -s, both of the tests in first_test.py passes. I can also see that when I run this script, the docker image is built.
However, I want to test inserting to a model.py which is located in the same folder as the integration_tests folder. I have tried importing the model directly and some classes inside it but it doesn't work.
My folder structure is as follows:
- Project
- integration_tests
- conftest.py
- first_test.py
- apps.py
- models.py #contains a User class
We have an ETL data API repo. We do all etl processing inside of it, then spit the data out in API's. These API's are run one at a time from a single command passing the resource class through to the server to build an API. the resource class is in a web directory in an __init__.py.
This is a wonderful convention and quite simple to use, but the problem I am having is coming from trying to get one of the 3 API's available spun up for testing. Our directory stucture is like this (calling the project 'tomato')
tomato
- category_api
- web
- etl
- test
- here is where we are writing some tests (test_category_api.py)
- data
- article_api
- web
- etl
- test
- data
- recommendation_api
- web
- etl
- test
- data
- common
- common shit
Inside this test, I have the following test class. On the seventh line up from the bottom,
you will see a comment on where it breaks. It is the import_module method.
import unittest
import sys
import os
import sys
import json
from importlib import import_module
from flask import Flask
from flask_restful import Api, abort, wraps
from flask_restful.utils import cors
from flask.ext.testing import TestCase
#dir_above_top_level = os.path.join(os.path.abspath(__file__), '../../.. /')
#sys.path.append(os.path.abspath(dir_above_top_level))
_CATEGORY_ENDPOINT = '/v1/category/'
_PACKAGE_NAME = os.environ['RECO_API_PACKAGE_NAME']
_CORS = cors.crossdomain(origin='*',
headers=['Origin', 'X-Requested-With',
'Content-Type', 'Accept'],
methods=['GET', 'HEAD', 'OPTIONS'],
max_age=3600)
class CategoryTests(TestCase):
def __init__(self):
self.app = Flask(__name__)
self._configure_app()
for resource in self.resource_classes:
self.api.add_resource(self.resource,
self.resource.URI_TEMPLATE)
def test_status_code(self):
self.response = self.client.post(_CATEGORY_ENDPOINT,
data=json.dumps(
{'title': 'Enjoy this delicious food'}),
headers=json.dumps(
{'content-type':'application/json'}))
self.assertEqual(self.response.status_code, 200)
def test_version(self):
self.response = self.client.post(_CATEGORY_ENDPOINT,
data=json.dumps(
{"title": "eat some delicious stuff"}),
headers=json.dumps(
{'content-type':'application/json'}))
self.assertEqual(json.dumps(self.response['version']), '1')
def _configure_app(self):
self.app = Flask(__name__)
self.app.config['TESTING'] = True
self.app.debug = True
self.decorators = [_CORS]
self.app.Threaded = True
self.web_package = 'tomato.category.web'
self.package = import_module('.__init__', self.web_package) # WE BREAK HERE
self.resources = package.RESOURCE_NAMES
self.resource_classes = [ getattr(package, resource) for resource in resources ]
self.api = Api(self.app, catch_all_404s=True, decorators=self.decorators)
if __name__ == '__main__':
unittest.main()
we are given an exception when running these tests:
ImportError: No module named tomato.category.web.__init__
yet cd into the main top dir, and ls tomato/category/web gets us __init__.py and its right there with the resource class.
How do I import this class so that I can instantiate the API to run the tests in this class?
Or if I'm completely on the wrong track what should I be doing instead?
You don't need to import __init__, just like you probably wouldn't do from tomato.category.web import __init__. You should be able to import the web package directly.
self.web_package = 'tomato.category.web'
self.package = import_module(self.web_package)
The problem here lies in the directory structure. In the current path, I am not at the top level. It is a module. So What was needed was to uncomment the line two lines at the top, and change the structure to append the path like this.
dir_above_top_level = os.path.join(os.path.abspath(__file__), '../../../..')
sys.path.append(os.path.abspath(dir_above_top_level))
and now, I can import it using
self.web_package = 'tomato.category.web'
self.package = import_module('.__init__', self.web_package)
and now it will import fine and I can grab the resource class to set up the testing API
I want to make pyramid auth in my app with persona or browser id, the problem is that using both of us i see an error.
The console drops me this when i use persona:
Import error: No module named pyramid_persona
and when I use browser ID drops me no modul named browserid
This is my code:
MY VIEW FILE
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.security import authenticated_userid
#from waitress import serve
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.security import authenticated_userid
from pyramid.exceptions import Forbidden
def hello_world(request):
userid = authenticated_userid(request)
if userid is None:
raise Forbidden()
return Response('Hello %s!' % (userid,))
MY INIT FILE
from pyramid.config import Configurator
from resources import Root
import views
import pyramid_jinja2
import os
here = os.path.dirname(os.path.abspath(__file__))
settings={
'persona.secret': 'some secret',
'persona.audiences': 'http://localhost:8080'
}
settings['mako.directories'] = os.path.join(here, 'templates')
__here__ = os.path.dirname(os.path.abspath(__file__))
def make_app():
""" This function returns a Pyramid WSGI application.
"""
settings = {}
settings['mako.directories'] = os.path.join(__here__, 'templates')
config = Configurator(root_factory=Root, settings=settings)
config.include('pyramid_persona')////////////////////////THE ERROR AND TROUBLEMAKER
config.add_renderer('.jinja2', pyramid_jinja2.Jinja2Renderer)
config.add_view(views.my_view,
context=Root,
renderer='zodiac1.mako')
#config.add_route( "home", "/home")
#config.add_view(views.home_view, route_name="home", renderer="zodiac1.mako" )
config.add_static_view(name='static',
path=os.path.join(__here__, 'static'))
# config.add_route('zodiac', '/zodiac')
# config.add_view(views.home_view, route_name='zodiac', #renderer='main.mako')
#config.add_route('zodiac1', '/zodiac1')
#config.add_view(views.home_view, route_name='zodiac1', renderer='zodiac1.mako')
config.add_route('zodiac2', '/zodiac2')
config.add_view(views.zodiac2_view, route_name='zodiac2', renderer='zodiac2.mako')
config.add_route('zodiac3', '/zodiac3')
config.add_view(views.guestbook, route_name='zodiac3', renderer='zodiac3.mako')
config.add_route('hello', '/hello')
config.add_view(views.guestbook, route_name='zodiac3', renderer='zodiac3.mako')
return config.make_wsgi_app()
application = make_app()
Please tell me what I am doing wrong, I'm sure that it didn't like how to I import config.include('pyramid_persona')
Thanks
From this error:
Import error: No module named pyramid_persona
You can tell Python cannot find the pyramid_persona module. Perhaps because its not installed. You should install it with pip install pyramid_persona.
You will also need to install pyramid_whoauth to get BrowserID support.
This can get a bit complicated stitching all the parts together, so I recommend having a read of this great writeup by Ryan Kelly (who works at Mozilla) that shows how everything plugs together.