2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
横瀬明仁氏:それでは、Django管理サイトのカスタマイズで苦労するポイント4「コードが断片化しやすくテストがしづらい」という点についてです。
まずは、このadmin.pyのコードを見てみてください。ModelAdminを継承して、クラス変数をオーバーライドしたり、メソッドを追加したりしていますが、例えばこれをカバレッジ100パーセントにしても、もうまったく意味がないような気がしませんか?
このように、AdminSiteやModelAdminを継承したクラスは、断片的なコードしかないので、どのようなテストをすればよいかが悩みどころだと思います。最後のポイント4では、Django管理サイトの効率的なテストについて解説していきたいと思います。
解決策としては2つあります。どちらもパッケージを使って効率的なテストをしていくアプローチです。
まず1番目。lxmlを使ってテストをしていくパターンです。lxmlは、HTMLやXMLを解析するためのライブラリです。通常のViewのテストでは、テストクライアントとselfのclientを使って、レスポンスを取得してテストをすると思います。ただ、ステータスコードなどは検証できても、画面項目の細かな検証までは難しいと思います。
そこで、lxmlパッケージを使います。responseのrendered_contentという属性が、レンダリング後のHTML文字列になっています。それを使って、lxmlというライブラリでパースすれば、画面項目を検証が可能になります。
具体的なコードはあとで実際のコードを見てもらったほうがいいと思います。このテストコードでは、Bookモデルの一覧画面の検証をしているイメージです。setUpでテストレコードを作成して、まずtestメソッドの中でログインします。モデル一覧画面を表示するためのリクエストを実行して、レスポンスを受け取っています。
ChangeListPageがモデル一覧の画面部品をlxmlでパースして、HTMLエレメントオブジェクトを返してくれるように作った自作のクラスです。これのイニシャライザにresponseのrendered_contentを渡して、あとは要素をそれぞれチェックする流れになっています。TestCaseクラスをオーバーライドしているので、Djangoのtestコマンドで実行できるテストになっています。
これが先ほど説明したChangeListPageの実装ですが、イニシャライザでresponseのrendered_contentを受け取ってパースします。そして、それぞれのプロパティで画面のHTMLエレメントオブジェクトを返すような仕組みになっています。
ここでは、lxmlでパースして画面項目を検証することで、効率的で効果的なテストができるという雰囲気だけをつかんでもらえればOKだと思います。
それでは2番目、Seleniumのブラウザーテストのお話です。Seleniumは、プログラムからブラウザーを操作するためのツールです。実際にブラウザーにレンダリングされたHTMLを操作するので、よりユーザーに近いテストができます。
Seleniumには、ブラウザーのAPIを利用するためのWebDriverインターフェイスと、主要なブラウザー向けの実装クラスが含まれていますが、Chromeを利用する場合はChromeDriverが別途必要になります。
Pythonの場合は、Seleniumパッケージです。ChromeDriverを使う場合はchromedriver-binaryパッケージが利用できます。chromedriver-binaryパッケージは、ローカルやサーバーで使うChromeと、一応同じバージョンのパッケージをインストールしておくのが無難かなと思います。
次に、Django組み込みのTestCaseクラスについて説明します。(スライドを指して)Django組み込みのTestCaseクラスの継承関係を図示したものですが、これがDjangoのデータベースに関係するテストをする時によく使うTestCaseクラスです。これ以外にもSeleniumをテストする時には、StaticLiveServerTestCaseをよく利用します。
Django管理サイトの場合は、特にDjangoは組み込みでAdminSeleniumTestCaseがデフォルトで用意されています。setUpClassでは、WebDriverインスタンス、テストメソッドからはselfのseleniumでアクセスを作成して、さらにWebサーバーも起動してくれます。
(スライドを指して)実際のコードはこんな感じです。これがAdminSeleniumTestCaseを継承したテストコードの例です。クラスメソッドのcreate_webdriverをオーバーライドしているのは、ChromeDriverをインスタンス化して、ヘッドレスモードで立ち上げるような仕組みにするために、create_webdriverをオーバーライドしています。
その続きは、Bookモデルの一連のCRUD操作をするためのテストメソッドをイメージして作っています。まずadmin_loginは、親クラスのAdminSeleniumTestCaseに作られているメソッドです。ログインすると、self.selenium.save_screenshotがスクリーンショットを撮ってくれます。
これはキャプチャー画像が撮れるので、テスト後に目検でこの画像をチェックすることで、実際にCSSがどのように反映されているのかを、目測でもチェックできます。
モデル一覧画面でキャプチャーして、「本を追加」ボタンを押して、モデル追加画面をゴニョゴニョしたあと、最後に「保存」ボタンを押すという流れです。ずらっと一連の動きを実行しつつ、キャプチャーを撮っていくことができます。
ポイント4のまとめです。「コードが断片化しやすくテストがしづらい」という困りごとに対しては、生成されるHTMLをlxmlでパースして画面部品を検証する。そして状況に応じて、Seleniumのブラウザテストを追加することで対応します。このSeleniumのテストは実行時間が長くなりがちなので、対応には注意してください。
カスタマイズするにあたっての再度の苦労ポイントとして「日本語の情報が少ない」という問題があります。最近、Djangoの日本語書籍がどんどん増えてきて、特に2021年7月19日に芝田(将)さんが出した『実践Django』は、超期待の本です。とはいえ、まだまだDjango管理サイトについては情報が少ないのは確かです。なにかいい本がないだろうかと思っている方もいるかもしれません。
そこで、はい。ドン。『現場で使えるDjango管理サイトのつくり方』という本があります。実は私が書きました。Django管理サイトだけに特化した、ニッチでオンリーワンな、152ページの狂気じみた本です。
というわけで、Django管理サイトのまとまった日本語情報がない問題については、『現場で使えるDjango管理サイトのつくり方』を現場に1冊置きましょうということで完全に解決しました。
それでは全体のまとめです。このトークでは、Django管理サイトをカスタマイズするにあたって苦労するポイントと、その解決策を話しました。
そして、5つのポイント5つについては、それぞれ全体構造を把握しよう。テンプレートの修正には、テンプレートの優先順位と継承を使ってカスタマイズしよう。
画面のスタイルを変えるのが大変という問題については、CSSファイルを追加する仕組みを理解しよう。コードが断片化しやすくテストがしづらいという点については、lxmlやSeleniumを使っていきましょう。そして日本語情報については、すばらしい本があるのでぜひ読んでみましょうということで、このトークを終わりにしたいと思います。
ご清聴ありがとうございました。
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略