From 029a32decdcc52f1fed4758ebae39fc693f89c63 Mon Sep 17 00:00:00 2001 From: Steven Loria Date: Sat, 19 Apr 2014 14:27:43 -0400 Subject: [PATCH] Fix and simplify tests (all tests passing) --- {{cookiecutter.app_name}}/tests/conftest.py | 32 ++----- .../tests/test_models.py | 13 ++- .../{webtest_tests.py => test_webtests.py} | 84 +++++++++---------- .../{{cookiecutter.app_name}}/public/forms.py | 2 +- .../{{cookiecutter.app_name}}/settings.py | 2 +- 5 files changed, 55 insertions(+), 78 deletions(-) rename {{cookiecutter.app_name}}/tests/{webtest_tests.py => test_webtests.py} (54%) diff --git a/{{cookiecutter.app_name}}/tests/conftest.py b/{{cookiecutter.app_name}}/tests/conftest.py index f0272c2..91f21bd 100644 --- a/{{cookiecutter.app_name}}/tests/conftest.py +++ b/{{cookiecutter.app_name}}/tests/conftest.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- +"""Defines fixtures available to all tests.""" import os import pytest +from webtest import TestApp from {{ cookiecutter.app_name }}.settings import TestConfig from {{cookiecutter.app_name}}.app import create_app @@ -12,14 +14,19 @@ from .factories import ALL_FACTORIES @pytest.yield_fixture(scope='session') def app(): _app = create_app(TestConfig) - ctx = _app.app_context() + ctx = _app.test_request_context() ctx.push() yield _app ctx.pop() -@pytest.yield_fixture(scope='session') +@pytest.fixture(scope='session') +def testapp(app): + """A Webtest app.""" + return TestApp(app) + +@pytest.yield_fixture(scope='function') def db(app): _db.app = app with app.app_context(): @@ -28,24 +35,3 @@ def db(app): yield _db _db.drop_all() - - -@pytest.yield_fixture(scope='function') -def session(db): - conn = db.engine.connect() - transaction = conn.begin() - - opts = {'bind': conn, 'binds': {}} - _session = db.create_scoped_session(options=opts) - - # Set session for each factory class - for FactoryClass in ALL_FACTORIES: - FactoryClass.FACTORY_SESSION = _session - - db.session = _session - - yield _session - - transaction.rollback() - conn.close() - _session.remove() diff --git a/{{cookiecutter.app_name}}/tests/test_models.py b/{{cookiecutter.app_name}}/tests/test_models.py index 7ffb2fa..fa97242 100644 --- a/{{cookiecutter.app_name}}/tests/test_models.py +++ b/{{cookiecutter.app_name}}/tests/test_models.py @@ -4,25 +4,24 @@ import datetime as dt import pytest -from {{ cookiecutter.app_name }}.database import db from {{ cookiecutter.app_name }}.user.models import User, Role from .base import DbTestCase from .factories import UserFactory class TestUser: - def test_created_at_defaults_to_datetime(self, session): + def test_created_at_defaults_to_datetime(self, db): user = User(username='foo', email='foo@bar.com') user.save() assert bool(user.created_at) assert isinstance(user.created_at, dt.datetime) is True - def test_password_is_nullable(self, session): + def test_password_is_nullable(self, db): user = User(username='foo', email='foo@bar.com') user.save() assert user.password is None - def test_factory(self, session): + def test_factory(self, db): user = UserFactory(password="myprecious") assert bool(user.username) assert bool(user.email) @@ -31,17 +30,17 @@ class TestUser: assert user.active is True assert user.password == "myprecious" - def test_check_password_with_equality_operators(self, session): + def test_check_password_with_equality_operators(self, db): user = User.create(username="foo", email="foo@bar.com", password="foobarbaz123") assert user.password == 'foobarbaz123' assert user.password != "barfoobaz" - def test_full_name(self, session): + def test_full_name(self, db): user = UserFactory(first_name="Foo", last_name="Bar") assert user.full_name == "Foo Bar" - def test_roles(self, session): + def test_roles(self, db): role = Role(name='admin') role.save() u = UserFactory() diff --git a/{{cookiecutter.app_name}}/tests/webtest_tests.py b/{{cookiecutter.app_name}}/tests/test_webtests.py similarity index 54% rename from {{cookiecutter.app_name}}/tests/webtest_tests.py rename to {{cookiecutter.app_name}}/tests/test_webtests.py index a199bc9..26c81a0 100644 --- a/{{cookiecutter.app_name}}/tests/webtest_tests.py +++ b/{{cookiecutter.app_name}}/tests/test_webtests.py @@ -3,64 +3,58 @@ See: http://webtest.readthedocs.org/ ''' +import pytest from flask import url_for -from flask.ext.webtest import TestApp -from nose.tools import * # PEP8 asserts -from ..user.models import User + +from {{cookiecutter.app_name}}.user.models import User from .base import DbTestCase from .factories import UserFactory +@pytest.fixture +def user(db): + return UserFactory(password='myprecious') -class TestLoggingIn(DbTestCase): - - def setUp(self): - self.w = TestApp(self.app) - self.user = UserFactory(password="myprecious") - self.user.save() +class TestLoggingIn: - def test_can_log_in(self): + def test_can_log_in_returns_200(self, user, testapp): # Goes to homepage - res = self.w.get("/") + res = testapp.get("/") # Fills out login form in navbar form = res.forms['loginForm'] - form['username'] = self.user.username + form['username'] = user.username form['password'] = 'myprecious' # Submits - res = form.submit().follow() - assert_equal(res.status_code, 200) + res = form.submit() + assert res.status_code == 200 - def _login(self, username, password): - res = self.w.get("/") + def test_sees_alert_on_log_out(self, user, testapp): + res = testapp.get("/") # Fills out login form in navbar form = res.forms['loginForm'] - form['username'] = username - form['password'] = password + form['username'] = user.username + form['password'] = 'myprecious' # Submits - res = form.submit().follow() - return res - - def test_sees_alert_on_log_out(self): - res = self._login(self.user.username, 'myprecious') - res = self.w.get(url_for('public.logout')).follow() + res = form.submit() + res = testapp.get(url_for('public.logout')).follow() # sees alert - assert_in('You are logged out.', res) + assert 'You are logged out.' in res - def test_sees_error_message_if_password_is_incorrect(self): + def test_sees_error_message_if_password_is_incorrect(self, user, testapp): # Goes to homepage - res = self.w.get("/") + res = testapp.get("/") # Fills out login form, password incorrect form = res.forms['loginForm'] - form['username'] = self.user.username + form['username'] = user.username form['password'] = 'wrong' # Submits res = form.submit() # sees error - assert_in("Invalid password", res) + assert "Invalid password" in res - def test_sees_error_message_if_username_doesnt_exist(self): + def test_sees_error_message_if_username_doesnt_exist(self, user, testapp): # Goes to homepage - res = self.w.get("/") + res = testapp.get("/") # Fills out login form, password incorrect form = res.forms['loginForm'] form['username'] = 'unknown' @@ -68,17 +62,15 @@ class TestLoggingIn(DbTestCase): # Submits res = form.submit() # sees error - assert_in("Unknown user", res) - + assert "Unknown user" in res -class TestRegistering(DbTestCase): - def setUp(self): - self.w = TestApp(self.app) +class TestRegistering: - def test_can_register(self): + def test_can_register(self, user, testapp): + old_count = len(User.query.all()) # Goes to homepage - res = self.w.get("/") + res = testapp.get("/") # Clicks Create Account button res = res.click("Create account") # Fills out the form @@ -89,13 +81,13 @@ class TestRegistering(DbTestCase): form['confirm'] = 'secret' # Submits res = form.submit().follow() - assert_equal(res.status_code, 200) + assert res.status_code == 200 # A new user was created - assert_equal(len(User.query.all()), 1) + assert len(User.query.all()) == old_count + 1 - def test_sees_error_message_if_passwords_dont_match(self): + def test_sees_error_message_if_passwords_dont_match(self, user, testapp): # Goes to registration page - res = self.w.get(url_for("public.register")) + res = testapp.get(url_for("public.register")) # Fills out form, but passwords don't match form = res.forms["registerForm"] form['username'] = 'foobar' @@ -105,13 +97,13 @@ class TestRegistering(DbTestCase): # Submits res = form.submit() # sees error message - assert_in("Passwords must match", res) + assert "Passwords must match" in res - def test_sees_error_message_if_user_already_registered(self): + def test_sees_error_message_if_user_already_registered(self, user, testapp): user = UserFactory(active=True) # A registered user user.save() # Goes to registration page - res = self.w.get(url_for("public.register")) + res = testapp.get(url_for("public.register")) # Fills out form, but username is already registered form = res.forms["registerForm"] form['username'] = user.username @@ -121,4 +113,4 @@ class TestRegistering(DbTestCase): # Submits res = form.submit() # sees error - assert_in("Username already registered", res) + assert "Username already registered" in res diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/public/forms.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/public/forms.py index 5659c74..1c00e77 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/public/forms.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/public/forms.py @@ -22,7 +22,7 @@ class LoginForm(Form): self.username.errors.append("Unknown username") return False - if not self.user.check_password(self.password.data): + if self.user != self.password.data: self.password.errors.append("Invalid password") return False diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/settings.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/settings.py index 54e7e64..51d3ab4 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/settings.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/settings.py @@ -9,7 +9,7 @@ class Config(object): BCRYPT_LEVEL = 13 DEBUG_TB_ENABLED = False # Disable Debug toolbar DEBUG_TB_INTERCEPT_REDIRECTS = False - CACHE_TYPE = "simple" # Can be "memcached", "redis", etc. + CACHE_TYPE = 'simple' # Can be "memcached", "redis", etc. class ProdConfig(Config):