かなり久しぶりの投稿です。以前、次のような doctest に関する記事を投稿しました。
今回は モジュール での doctest の実行方法について書いてみます。
モジュールについて
最初に web2py のモジュールについて、簡単に説明します。モジュールは、共通関数などを抜き出し、独立性の高いコードとして設定するものです。 web2py管理画面の「モジュール」というセクションで、モジュールファイルの作成やアップロードが可能になっています。
モジュールを利用する場合の注意点を少し書いてみます。
- モデル変数の扱い
-
モジュールはコントローラやモデルでのコード記述とは違い、モデルで定義した変数にはアクセスできません。このためモジュールで記述する関数やクラスで、
モデル定義の変数(db や auth など)を使用したい場合は、
パラメータでこれらの変数を渡してやるcurrent変数に渡してやる 必要があります(注:記述が間違っていました web2py book モジュールからのAPIアクセスを参照)。 - Pythonモジュールの利用
-
easy_install や pip などで導入する Python モジュールを、web2py 内に設定し利用することが可能です。この場合は管理画面のモジュールを利用するのでは
無く、web2py ディレクトリの site-packages に設定します。具体的には次のページで設定方法を紹介していますので、
参考にしてください。
Google AppEngine での Python-OpenID モジュールの設定これは本番の Python 環境で、モジュールを追加できない場合などに利用可能です。
- コード開発時に便利な設定
-
モジュールは一度インポートされると、モジュールのコード変更しても再度読み込まれることはありません。
しかしこのような動作は、コード開発時には不都合です。
もし次のコードをモデル定義に記述しておけば、モジュールのインポート命令がある度に、コードの変更チェックを行います。
変更がある場合は、モジュールのリロードを行います。
from gluon.custom_import import track_changes; track_changes(True)
本番環境ではモジュールのリロードは不要ですので、コードをコメントにします。
モジュールテストの例
さて本題のモジュールのテストについて、入っていきます。まず date_calculator.py というモジュールファイルを生成し、次のコードを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #!/usr/bin/env python # coding: utf8 from gluon import * def last_friday(date=None): ''' >>> last_friday() #doctest: +ELLIPSIS datetime.date(... >>> last_friday('20130101') datetime.date(2012, 12, 28) >>> last_friday(20130101) Traceback (most recent call last): ... TypeError: must be string, not int >>> last_friday('2013/01/01') #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... ''' return retrieve_date(init_date=date, weekday=4, weeks=-1) def next_monday(date=None): ''' >>> next_monday() #doctest: +ELLIPSIS datetime.date(... >>> next_monday('20130101') datetime.date(2013, 1, 7) >>> next_monday(20130101) Traceback (most recent call last): ... TypeError: must be string, not int >>> next_monday('2013/01/01') #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... ''' return retrieve_date(init_date=date, weekday=0) def retrieve_date(init_date=None, weekday=None, **param): from datetime import date, datetime, timedelta if init_date is None: init_date = date.today() else: init_date = datetime.strptime(init_date, "%Y%m%d").date() date = init_date + timedelta(**param) if weekday is not None: d = weekday - date.weekday() date += timedelta(d if d > 0 else 7 + d) return date |
syntax2html |
簡単に解説すると、 last_friday と next_monday の2つの関数があり、それぞれ 指定日の一番最後の金曜日と、次の 月曜日の datetime.date オブジェクトを返します。既に doctest のコードは、この2つの関数には設定されています。
このコードの dcotest を実行するには、どうしたら良いでしょうか?。というのは web2pyの管理画面にはコントローラにあるようなテストボタンが、モジュールにはありません。また、コマンドラインからも実行できないようです。
モジュールテストの実行
doctest はモジュールのままでは実行出来ません。このため、テストが実行可能なコントローラにインポートします。
まず、ダミーのコントローラファイルを作成します。ここでは test.py とし、次のコードを記述します。
1 2 3 4 | # coding: utf8 # try something like from date_calculator import last_friday from date_calculator import next_monday |
syntax2html |
コードを記述し保存したら、管理画面からテストを実行してみます。
正常に、 doctest を実行したことが確認できました。
モジュールの doctest ではコントローラにダミーファイルを作成し、モジュールの関数をインポートすることにより実行できるということが、理解して頂けたと思います。