「ゼロからFlaskがよくわかる本」を読み終わった感想

最近手を動かす系の本から遠ざかっていたので、 web アプリ関連の勉強も兼ねて 「ゼロからFlaskがよくわかる本」を読んでみました。

www.amazon.co.jp

kindle unlimited で無料で読めるのに解説が結構詳しくてありがたかったです。

内容はブログ用の web アプリケーションを Flask で作るというものでした。

いくつか詰まって自力で解決した部分と感動した部分を備忘録として載せておきます。 環境は Mac です。

pipenv を VSCode で使う

$ pip install pipenv

$ pipenv --python 3.8 # Pipfile が作られる

$ pipenv shell # 仮想環境に入る

$ which python # 仮想環境で使用している python のパスがわかる
# このパスを VSCode のインタープリターのパスに登録すると pipenv で install したパッケージを元に予測してくれる

$ pipenv install <パッケージ名> # pip install の代わり
# 初めてパッケージを install すると Pipfile.lock が作成される

$ pipenv requirements # install したパッケージ群が見られる。 Pipfile.lock がないとエラーを吐かれる。

仮想環境作るのめっちゃ楽になってる。。すごい。

pipenv で環境変数を設定する

本書では .env環境変数の設定を書いておけば flask run でも自動的に反映されるかのように書いてあったがうまくいかなかった。以下のように実行しないと .env で設定した環境変数が反映されない。

$ pipenv run flask run

Jinja2 のフォーマットを VSCode が認識できるようにする

  1. 「Better Jinja」というプラグインを入れる marketplace.visualstudio.com
  2. setting.json に以下を加える

    "emmet.includeLanguages": {
     "jinja-html": "html"
    },
    "[jinja-html]": { "editor.formatOnSave": false },
    
  3. VSCode 最下部のバーにある「言語モードの選択」をクリック

  4. 「Jinja HTML」を選択
  5. {{ }}{% %} に色がついたり、exte ぐらいまで打つと {% extends "" %} を予測してくれたりする。

textarea で入力したテキストをデータベースから取得して HTML で表示する

普通にやると、改行の \r がただのスペースとして表示されてしまう。

HTML に渡す前に \r<br> に変える必要がある

from flask import Markup
# text の改行コードをマークアップ言語に置き換える
text = Markup(text.replace('\r', '<br>'))

redirect ができているかを unittest でテストする

本書のテストでは、 flash のメッセージを見てログイン・ログアウトの成功・失敗を確認するだけだったので、他の処理のテストの仕方が気になった。

test_clientwith ブロックの中でないと、 request が使えないので注意。

import unittest
from request import request

class TestFlaskBlog(unittest.TestCase):
    def setUp(self): # こういう名前の関数を作っておくとテスト開始前に勝手に実行してくれる
        """ テスト開始前の初期設定 """
        self.app = create_app(test_config={
            'TESTING':True,
        })
        self.client = self.app.test_client()
    
    def test_error_handle_404(self): # テスト用のメソッドは、先頭が test_ で始まらないと流れてくれない
        # 不明な url の場合はログインページにリダイレクトされる
        client = self.client
        with client:
            ret = client.get('/hoge', follow_redirects=True)
            assert request.path == '/login'

coverage パッケージすげー

coverage というパッケージを使うと unittestcoverage コマンド経由で流してくれて、見やすいレポートまで作ってくれる。

カバレッジが簡単に出せるのもすごいけど、html でどの行を今のテストでカバーできていないかが視覚的にわかるのがとても嬉しい。テスト駆動開発全然できてないけど、これだったらできそう(?)

$ pipenv install coverage

$ coverage run -m unittest

$ coverage report -m # CLI 上でカバレッジのレポートを出力する
Name                     Stmts   Miss  Cover   Missing
------------------------------------------------------
blog/__init__.py            14      0   100%
blog/config.py               6      0   100%
blog/models/entries.py      16      4    75%   22-24, 28
blog/scripts/db.py           8      0   100%
blog/views/auth.py          30      0   100%
blog/views/entries.py       54     25    54%   21, 28-36, 43-48, 58-60, 66-73, 78-82
------------------------------------------------------
TOTAL                      128     29    77%

$ coverage html # レポート用の html を作成する