【Streamlit】Streamlitのテスト用モジュール入門
こんにちは。データエンジニアの山口歩夢です!
Streamlitにはたくさんの便利な関数が用意されていて、簡単にアプリケーションの開発ができますが、AppTest
というテスト用にも便利なモジュールも用意されています。
こちらを活用することで、テストコードを非常に手軽に書くことができます。
テストコードを書くことで、ユーザーがウィジェットに入力した内容や出力値などを検証することができ、アプリケーションの保守性を高めることができます。
本記事ではpytest
とAppTest
を組み合わせてテストを行いますが、pytest
に限らず、様々なテストツールを使用できるようです。
今回は、「Streamlit入門 Pythonで学ぶデータ可視化&アプリ開発ガイド」で紹介している以下のようなアプリケーションのテストコードを作成してみようと思います!
細かくテストするというよりも、サイドバーのセレクトボックスやタイトル名、データフレームの数などをサクッと簡単にテストしてみます。
実装
それでは早速実装していきます!
ptytestのインストール
まずは、pytest
をインストールします。
pip installなどでインストールすることができます。
$ pip install pytest
ファイルの用意
以下のような構成でディレクトリを用意します。
テストを書くファイルは、先頭または末尾にtest
と付くように命名します。
本記事では、test_app.py
とします。
├── streamlit_app.py
└── tests/
└── test_app.py
テストコードの用意
それでは、テストコードを用意していきます。
アプリケーションの以下の要素に対してテストを行っていきます。
サイドバー
-
st.title
のテキスト -
st.selectbox
- labelのテキスト
- 初期入力値
メインエリア
-
st.header
のテキスト -
st.dataframe
で出力しているデータフレームの数
結論、以下のようなテストコードを用意しました!
テスト用の関数にもtest_app
というように、先頭にtest
が付くように命名します。
# test_app.pyファイル
from streamlit.testing.v1 import AppTest
def test_app():
# アプリをテストする準備
at = AppTest.from_file("streamlit_app.py").run()
# サイドバーのタイトルと選択ボックスのラベルを確認
assert "製品の選択" in at.sidebar.title[0].value
# selectbox ラベルの確認
assert at.sidebar.selectbox[0].label == "製品大分類の選択"
at.sidebar.selectbox[0].set_value("電子機器").run() # 大分類
assert at.sidebar.selectbox[1].label == "製品中分類の選択"
at.sidebar.selectbox[1].set_value("コンピューター").run() # 中分類
assert at.sidebar.selectbox[2].label == "製品小分類の選択"
at.sidebar.selectbox[2].set_value("ノートパソコン").run() # 小分類
assert "製品データ可視化ダッシュボード" in at.header[0].value
# データフレームの確認
assert len(at.dataframe) == 1
以下のようなコマンドを実行することで、上記のテストコードを使用してテストを行うことができます。
$ pytest test_app.py
テスト結果は以下のように表示されました。
1 passed
と出力されているので、テストコード内の関数がテストを通過していることが分かります。
テストコードの解説
ライブラリのインポート
StreamlitにはAppTest
というテストコードを書くためのライブラリが用意されています。
以下のようにimportをして、こちらのライブラリを使用してテストコードを書いていきます。
from streamlit.testing.v1 import AppTest
AppTest
インスタンス初期化&アプリの実行
AppTest
を使用してテストを行う場合、最初にAppTest
のインスタンスを初期化する必要があります。
ドキュメントを読む限り、AppTest.form_file()
を使用して、インスタンスを初期化することが推奨されていました。
こちらを使用すると、テスト対象のPythonスクリプト(streamlit_app.py
)を指定して、テストを行うことができます。
そして、末尾にrun()
をつけることで、アプリケーションの実行を再現します。
at = AppTest.from_file("streamlit_app.py").run()
st.titleのテキスト
サイドバーにst.title
で出力しているタイトルのテキストは以下のようにテストをします。
アプリケーション内で最初のst.title
をテストするため、at.slidebar.title[0].value
と書いています。
もし、他にもst.title
で出力しているタイトルがあれば、
at.sidebar.title[1].value
、at.sidebar.title[2].value
...のように、title[n]
のnの数値を増やしていきます。
assert "製品の選択" in at.sidebar.title[0].value
st.selectboxのラベル・初期入力値
サイドバーのセレクトボックスのラベルや初期入力値は、以下のようにテストをします。
出力しているセレクトボックスが複数あるため、
at.sidebar.selectbox[1].value
、at.sidebar.selectbox[2].value
...と`selectbox[n]のnの値が増えていっています。
assert at.sidebar.selectbox[0].label == "製品大分類の選択"
at.sidebar.selectbox[0].set_value("電子機器").run() # 大分類
assert at.sidebar.selectbox[1].label == "製品中分類の選択"
at.sidebar.selectbox[1].set_value("コンピューター").run() # 中分類
assert at.sidebar.selectbox[2].label == "製品小分類の選択"
at.sidebar.selectbox[2].set_value("ノートパソコン").run() # 小分類
st.headerのテキスト
メインエリアのst.header
は以下のようにテストをします。
assert "製品データ可視化ダッシュボード" in at.header[0].value
st.dataframeのデータフレームの出力数
st.dataframeで出力しているデータフレームの数は以下のようにテストしました。
assert len(at.dataframe) == 1
その他
st.file_uploader
などは、まだテスト用の関数が用意されておらず、順次追加予定の様子です。
まとめ
Streamlitには、テスト用の関数が多く用意されていることが分かりました。
細かくテストをするというよりも、シンプル且つ高速にテストをするのに便利だなといった印象でした。
公式で用意されている、以下のチートシートを見ながらテストコードを書くのがおすすめです!
宣伝
12/6に「Streamlit入門 Pythonで学ぶデータ可視化&アプリ開発ガイド」という技術書を発売致しました。
Streamlitの基礎から、Streamlitを活用したアプリケーションの開発について、300ページにわたって解説させていただきました!
Discussion