Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Replacement for 'from playhouse.test_utils import test_database'

During the Flask track we we're using 'from playhouse.test_utils import test_database' to test Peewee models using a test_db.

test_database no longer exists.

I have tried to use this from Charles Leifer (his comment from 1 Feb 2018) - https://github.com/coleifer/peewee/issues/1450

But when I run it in PyCharm I am getting; AttributeError: enter

My code;

import unittest
import datetime

from flask import Flask
from flask_bcrypt import Bcrypt
from flask_login import UserMixin
from functools import wraps
from peewee import *

from models import User, Receptive

MODELS = (User, Receptive)

test_db = SqliteDatabase(':memory:')


def use_test_database(func):
    @wraps(func)
    def inner(self):
        with test_db.bind(MODELS):
            test_db.create_tables(MODELS)
            try:
                func(self)
            finally:
                test_db.drop_tables(MODELS)

    return inner


class TestSomething(unittest.TestCase):
    @use_test_database
    def test_something(self):
        # ... models are bound to test database ...
        pass


if __name__ == '__main__':
    unittest.main()

I'm not sure why I'm getting this error and the documentation on the error is confusing me even more.

Am I missig something in my code?

Do you have another option for replacing playhouse.test_utils import test_database?

3 Answers

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,720 Points

Designing tests for your code is a great way to improve your projects-- nice work!

Normally in the deployed Flask app I will be connecting in the @before_request hook. But when you are testing, you typically don't use the hook, so probably should insert a connection to the database right after you declare it.

Good luck!

test_db = SqliteDatabase(':memory:') # you did this, good.
test_db.connect() # you might be missing this unless I missed it.

Thanks Jeff.

I've added that in.

I was still getting the Attribute Error, so I've changed the way I use bind() and it's now working.

For anyone else looking for a replacement for playhouse.test_utils import test_database. I'm calling bind on the table like this

    def test_create_user(self):
        User.bind(test_db)
        self.create_users()
        self.assertEqual(User.select().count(), 2)
        self.assertNotEqual(
            User.select().get().password,
            'password'
        )

Essentially replacing the with test_database() call with <table>.bind(database)

For reference, this is how the tests we're written in the Flask track tutorials;

def test_create_user(self):
        with test_database(TEST_DB, (User,)):
            self.create_users()
            self.assertEqual(User.select().count(), 2)
            self.assertNotEqual(
                User.select().get().password,
                'password'
            )

I don't know if this best practice, but it's working for me. Always open to suggestions for how my code can be improved though.

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,720 Points

I fired up my local version of TacoCat and did a "pip freeze"

I noticed my code is using an OLDER version of PeeWee (2.8.1) which still used the now deprecated playhouse.test_utils.

Charles Leifer made some big changes in the 3.x version. The way I wrote my code, I did not have a need to use the .bind() method.

So I think some of my advice is a little outdated! :-P

.bind() documentation

http://docs.peewee-orm.com/en/latest/peewee/api.html#Model.bind

Extracted from my code setup in the tests module.

import unittest

from playhouse.test_utils import test_database # this is deprecated
from peewee import *

import tacocat
from models import User, Taco

TEST_DB = SqliteDatabase(':memory:')
TEST_DB.connect()
TEST_DB.create_tables([User, Taco], safe=True)