unittest is not working - python-3.x

I am trying to run a test using unit test by using python3 functional_tests.py -the file name- but i get
"----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK"
here is my code:
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
self.browser.quit()
def testcan_start_a_list_and_retrieve_it_later(self):
self.browser.get('http://localhost:8000')
self.assertIn('To-Do', self.browser.title)
self.fail('finish test')
if __name__ == '__main__':
unittest.main(warnings='ignore')
i am using python 3.5.2

Are you doing the exercises in Test-Driven Development with Python? Are these Django tests? If they are Django tests, you can try the following:
python3 manage.py test functional_tests
Even so, the commenter states correctly that the if __name... portion of the code should not be indented. It should be fully on the left margin.

Related

Running Django with Pyto on iPad

I am trying to build my first Webb app using Django. I’m using my iPad because I am on the move a lot. Anyways, I’m trying to follow Django’s instructions for building a poll application. I got the server running but when i made the changes that should have printed the Hello World but its now its giving me a ModuleNotFoundError.
I’ve tried copy and pasting the lines of code from Django’s website and I’ve tried to type it in on my own.
ModuleNotFoundError: No module named 'WellnessApp'
import os
`import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'WellnessProject.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
#if __name__ == '__main__':
# main()
if __name__ == '__main__':
import background as bg
with bg.BackgroundTask() as b:
main()`

VSCode test explorer stops discovering tests when I add an import to python code file

This python code file works perfectly. But when I add either of the commented imports, the vscode test feature gives "No tests discovered, please check the configuration settings for the tests." No other errors.
# import boto3
# import pymysql
import decimal
import datetime
def increment(x):
return x + 1
def decrement(x):
return x - 1
What is it that I don't understand about imports and the test feature that explains why these would break the test explorer?

Spin up a local flask server for testing with pytest

I have the following problem.
I'd like to run tests on the local flask server before deploying to production. I use pytest for that. My conftest.py looks like that for the moment:
import pytest
from toolbox import Toolbox
import subprocess
def pytest_addoption(parser):
"""Add option to pass --testenv=local to pytest cli command"""
parser.addoption(
"--testenv", action="store", default="exodemo", help="my option: type1 or type2"
)
#pytest.fixture(scope="module")
def testenv(request):
return request.config.getoption("--testenv")
#pytest.fixture(scope="module")
def testurl(testenv):
if testenv == 'local':
return 'http://localhost:5000/'
else:
return 'https://api.domain.com/'
This allows me to test the production api by typing the command pytest and to test a local flask server by typing pytest --testenv=local
This code WORKS flawlessly.
My problem is that I have to manually instantiate the local flask server from the terminal each time I want to test locally like this:
source ../pypyenv/bin/activate
python ../app.py
Now I wanted to add a fixture that initiates a terminal in the background at the beginning of the tests and closes the server down after having finished testing. After a lot of research and testing, I still cannot get it to work. This is the line I added to the conftest.py:
#pytest.fixture(scope="module", autouse=True)
def spinup(testenv):
if testenv == 'local':
cmd = ['../pypyenv/bin/python', '../app.py']
p = subprocess.Popen(cmd, shell=True)
yield
p.terminate()
else:
pass
The errors I get are from the requests package that says that there is no connection/ refused.
E requests.exceptions.ConnectionError:
HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded
with url: /login (Caused by
NewConnectionError(': Failed to establish a new connection:
[Errno 111] Connection refused',))
/usr/lib/python3/dist-packages/requests/adapters.py:437:
ConnectionError
This means for me that the flask server under app.py is not online. Any suggestions? I am open to more elegant alternatives
For local testing the Flask test_client is a more elegant solution. See the docs on Testing. You can create a fixture for the test_client and create test requests with that:
#pytest.fixture
def app():
app = create_app()
yield app
# teardown here
#pytest.fixture
def client(app):
return app.test_client()
And use it like this:
def test_can_login(client):
response = client.post('/login', data={username='username', password='password'})
assert response.status_code == 200
If the only problem are the manual steps, maybe consider a bash script that does your manual setup for you and after that executes pytest.
I am using the following for this purpose so that testing configuration is also preserved in the test server
#pytest.fixture(scope="session")
def app():
db_fd, db_path = tempfile.mkstemp()
app = create_app({
'TESTING': True,
'DATABASE': db_path
})
yield app
os.close(db_fd)
os.unlink(db_path)
from flask import request
def shutdown_server():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
#pytest.fixture
def server(app):
#app.route('/shutdown',methods=('POST',))
def shutdown():
shutdown_server()
return 'Shutting down server ...'
import threading
t = threading.Thread(target=app.run)
yield t.start()
import requests
requests.post('http://localhost:5000/shutdown')
References
https://flask.palletsprojects.com/en/1.1.x/tutorial/tests/
How do I terminate a flask app that's running as a service?
How to stop flask application without using ctrl-c
With a bash script (thanks #ekuusela) I now finally succeeded in what I wanted.
I added a fixture that calls the bashscript spinserver.sh in a new terminal window. This works in ubuntu, the command is different in different environments (see Execute terminal command from python in new terminal window? for other environments).
#pytest.fixture(scope="session", autouse=True)
def client(testenv):
if testenv != 'local':
pass
else:
p = subprocess.Popen(['gnome-terminal', '-x', './spinserver.sh'])
time.sleep(3)
yield
Here the very simple bashscript
#!/bin/bash
cd ..
source pypyenv/bin/activate
python app.py
The sleep command is necessary because the server takes some time to
initialize.
Don't forget to make your bash script executable (chmod
u+x spinserver.sh)
I tried to do a teardown after yield, but p.kill does not really
close the window. This is acceptable for me as it does not matter
if I have to manually close a terminal window & I can even see
flask debugging if necessary

pytest-benchmark: Run setup on each benchmark iteration

I'm trying to benchmark the bundling process of our js bundles using pytest-benchmark. For accurate processing the target directory needs to empty. I've tried cleaning this on each run using the pedantic setup argument, but this only runs on initialization of the benchmark, and not in between runs. This is the code of my last try:
import shutil
import os
import pytest
def clean_bundles():
print("Cleaning bundles")
shutil.rmtree(os.path.abspath('precompiled'), True)
def bundle(gulpfile):
os.system("gulp --gulpfile %s createBundles" % gulpfile)
def test_bundle(benchmark):
benchmark.pedantic(lambda: bundle("gulpfile.js"), setup=clean_bundles(), rounds=5, iterations=1)
Is there anyway to run a clean between each iteration without making it part of the benchmark results?

How not to call initialize at each request with Tornado

I want to set variables when starting my Tornado webserver, so I tried to override initialize on my RequestHandler class. But apparently, initialize is launched each time a request is made, according to the following code and its output:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def initialize(self):
print("Launching initialization...")
def get(self):
print("Get: {}{}".format(self.request.host, self.request.uri))
app = tornado.web.Application([=
(r"/.*", MainHandler)
])
def runserver():
import tornado.ioloop
app.listen(8080)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
runserver()
stdout:
~ ➤ ./redirector.py
Launching initialization...
Get: 127.0.0.1:8080/
Launching initialization...
Get: 127.0.0.1:8080/favicon.ico
Launching initialization...
Get: 127.0.0.1:8080/favicon.ico
Launching initialization...
Get: 127.0.0.1:8080/
This behavior is the complete contrary to what is written in the doc:
Hook for subclass initialization.
(Meaning it is called at the end of __init__)
So, does anybody know how to do what I want to ?
Thanks in advance.
It's not contrary to the doc; have a look at the Structure of a Tornado app section. A RequestHandler object is created for each request.
If you want code to be executed when the app is started only, subclass the Application class and override __init__, or just put it in your runserver function.

Resources