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.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには