Pylons+memcacheDB...忘れんうちにテスト記述

Pylonsはnoseというプログラムを使ってテストをする。本来はUnit Testに重きを置くのが好きなのだが、今回の方式ではPOPO(Plain Old Python Object)が相手なので特にやることがない。むしろ、コントローラが所望の動きをしているかどうかを確認することが大事になる。

まずはテスト用memcachedbの環境をPylonsに教える必要がある。PhoneBook/test.iniを以下のように記述。

#
# PhoneBook - Pylons testing environment configuration
#
# The %(here)s variable will be replaced with the parent directory of this file
#
[DEFAULT]
debug = true
# Uncomment and replace with the address which should receive any error reports
#email_to = you@yourdomain.com
smtp_server = localhost
error_email_from = paste@localhost

[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 5000

[app:main]
use = egg:PhoneBook
full_stack = true
cache_dir = %(here)s/data
beaker.session.key = phonebook
beaker.session.secret = hogehogehoge

sqlalchemy.url = sqlite:///%(here)s/test.db
memcachedb.servers = 127.0.0.1:31201

→test.iniから起動される場合、memcachedbはポート31201のほうが呼ばれるようになる。

テストだが、以下の確認ができていればよかろう。

  • new...フォームが表示されていること
  • view...
    • データが表示されていること
    • 不正なidが渡されたり、Phone以外のクラスを表示しようとしたらエラー404になること。
  • create...
    • データを格納し、viewに制御を渡すこと


phonebook/tests/functional/test_phone.py

from phonebook.tests import *
from routes import url_for
import memcache
from pylons import config
from jsonpickle import Pickler, Unpickler
import phonebook.model as model
from urlparse import urlparse
import uuid

class TestPhoneController(TestController):

    def setUp(self):
        import datetime
        phone = model.Phone('408-444-4444',
                            'Hogeyama Hogeo',
                            '1400 Fashion Island',
                            '650-666-6666',
                            datetime.datetime(1960,1,1))

        from jsonpickle import Pickler
        p = Pickler()
        ser = p.flatten(phone)
        mc = memcache.Client([config['app_conf']['memcachedb.servers']], debug = 0)
        mc.set(phone.id, ser)
        self._id = phone.id

    def test_new(self):
        """Tests to ensure that NEW form is displayed properly"""
        response = self.app.get(url_for(controller = 'phone',
                                        action = 'new'))
        assert 'Create' in response

    def test_view(self):
        """Tests to ensure that GET id=1 methods are propery implemented"""
        response = self.app.get(url_for(controller = 'phone',
                                        action = 'view',
                                        id = self._id))
        assert 'Hogeyama Hogeo' in response
        assert 'REQUEST_METHOD' in response.req.environ


    #tests for create()
    def test_create_prohibit_get(self):
        """Tests to ensure that GET requests are prohibited"""
        response = self.app.get(
            url = url_for(controller = 'phone', action = 'create'),
            params = {'mobile_number': u'000-0000-0000',
                      'name': u'name name',
                      'address': u'the address',
                      'home_number': u'111-1111-1111',
                      'dob': u'2000/01/01'},
            status = 405)

    def test_create_invalid_form_data(self):
        """Tests that invalid data results in the form being returned with
        error messages"""
        response = self.app.post(
            url = url_for(controller = 'phone', action = 'create'),
            params = {'mobile_number': u'000-0000-0000',
                      'name': u'',
                      'address': u'',
                      'home_number': u'',
                      'dob': u'2000/01/01'},
            )
        assert 'Please enter a value' in response

    def hogetest_create(self):
        """Tests that valid data is saved to the database, that the response
        redirects to the view() action that a flash message is set in the session"""
        response = self.app.post(
            url = url_for(controller = 'phone', action = 'create'),
            params = {'mobile_number': u'Created',
                      'name': u'Created',
                      'address': u'Created',
                      'home_number': u'Created',
                      'dob': u'2000/01/01'},
            )

        mc = memcache.Client([config['app_conf']['memcachedb.servers']], debug = 0)
        ser = mc.get('2')

        u = Unpickler()
        c = u.restore(ser)

        assert c.__class__.__name__ == 'Phone'
        assert c.mobile_number == u'Created'
        assert c.name == u'Created'
        assert c.address == u'Created'
        assert c.home_number == u'Created'
        assert c.dob == u'2000/01/01'

        assert urlparse(response.response.location).path == url_for(
            controller = 'phone', action = 'view', id = '2')
        assert response.status_int == 302

これでPhoneBookディレクトリからnosetestsを実行。

$ nosetests
....
----------------------------------------------------------------------
Ran 4 tests in 0.930s

OK

Gitコミット先