ラベル テスト の投稿を表示しています。 すべての投稿を表示
ラベル テスト の投稿を表示しています。 すべての投稿を表示

2012年2月20日月曜日

自動テスト時にPEP8コーディング規約をチェックさせる

unittestを自動テストでまわす時に、PEP8をコーディング規約をチェックさせてます。
この手の規約を守るのは面倒くさいのですが、
Eclipse(PyDev)に特化させることで かなり効率が上がったので、紹介します。

まず、【ここ】を参考にして、PEP8チェックをunittestに組み込んでみました。

それだけだと芸が無いので、テスト結果の出力形式をPyDev用に編集しました。

PyDevは、トレースバックのログから、エラー箇所へのリンクを作りますよね?
これはログの出力結果のパターンから リンクを生成しているように思えたので、PEP8のログを整形してトレースバックログに似せてみました。
(この辺、Pythonは改造が簡単で良いですね)

すると、トレースバックのログと同様に、PEP8に違反したところへのリンクができました!
これで、PEP8違反箇所の修正が、かなり簡単になります。

以下、ソースです

2012年1月12日木曜日

GAE Python 2.7のテスト環境の構築について考えてみる

今のGAEだと、

from google.appengine.ext import testbed

とかからで、必要なスタブを読み込んでいけばいいんですね。

プロダクション環境のビッグテーブルを使ってテストしなくちゃいけないほどハードなテストはしないよていなので、GAETestBaseは移植しないことにしました。

gaeunitみたいな、プロダクション環境でテストを動かす仕組みはあったほうが良い気がしますね。
今の案では、

  • ローカル環境:unittest + testbed + webtest + BeautifulSoupでテスト。
  • プロダクション環境:Seleniumでテスト
かな。

Python2.7の環境なら、unittestで、かなりいけるはず。noseとかいらないかもしんない。
webtest と BeautifulSoup は リクエストを投げて帰ってくるレスポンスの内容をテストする為にいるはず。


アプリのバージョンでnamespaceを分けるようにすれば、アプリを公開後もプロダクション環境でテストを走らせることは可能なはず。

ただ、そうした場合、バージョン間のデータのコピーとかを簡単にできるように環境を整えるのと、Seleniumのテスト開始時にデータストアを初期化するような仕組みがほしくなりますね。

んー面倒だから、プロダクション環境でのテストは後回しかな。
TDDで開発するには、ローカル環境でテストできれば十分だし。


2010年11月16日火曜日

Pythonのコーディングスタイル(PEP8)をチェック

参照元

なるほどー。そんな便利なコマンドがあったとは。
さっそく、nosetests起動用バッチコマンドに組み込みました。

1.pep8チェック
2.pep8チェックでエラー無:nosetestsを実行して終了。
3.pep8チェックでエラー有:pauseしてからnosetestsを別ウィンドウで実行。並行して1に戻る。

そのうち公開します。

2010年11月3日水曜日

開発進捗

''.join(list)のlistは、イテレート可能であればlistで無くても良いみたい。
listに間違ってジェネレータをそのまま指定したら、そのまま動いたので気がつきました。
試行錯誤した結果、''.join(ジェネレータ)で、単純な文字結合の約1.3倍の速度になりました。(ローカル環境での実測。本番環境ではどうなのかは未検証)

unittestのテストケースのメソッドにコメントを入れたら、noseの出力結果にコメントが出力された。
そんな小便利な機能があるのですね。
ただ、通常は「メソッド名(テストケースのクラス名)」と表示されたところが、「コメント」と出力されるので、どこの結果なのかがわかりにくいと思いました。
半端にコメントいれると、かえってまずそうなので、今はコメントを入れない方向です。

2010年11月1日月曜日

WindowsXP(eclipse)でGAE/Pのテスト駆動開発(nose)

WindowsXP環境でeclipse(PyDev)を使ってGoogle App Engine の開発をしているのですが、
・テストコードを簡単に実行したい
・エラーの有無を実行結果の色で判別したい
という思いから、以下のようなバッチを作ってみました。
 <nosetest.bat>
@ECHO OFF
CD /D %~dp0
REM ========================================
REM nosetests 起動バッチ
REM   ①nosetests にパラメータを指定して起動、出力結果を一時ファイルに保存
REM   ②テストでエラーなし:テスト結果を標準出力に出力
REM     テストでエラーあり:テスト結果をエラー出力に出力
REM   ③30秒間(パラメータ1で変更可能)そのままポーズして終了
REM ========================================
REM 起動パラメータ:
REM     パラメータ1=指定された秒数だけ表示(デフォルトは30秒)
REM     パラメータ2=nosetestsの追加パラメータ
REM ========================================

IF "%1"=="" (SET WAIT_TIME=30) ELSE (SET WAIT_TIME=%1)
SET EXTENDS = %~2
SET /A WAIT_TIME=%WAIT_TIME%+1 >NUL

REM ======================================
REM 内部パラメータ:
REM     EXE_COMAND=nosetest.exeの起動コマンド(必要に応じてpathも指定)
REM     SRC_PATH=ソースディレクトリの相対パス
REM     NOSETESTS_RESULT_FILE=noseの実行結果の保存ファイル
REM ======================================

SET EXE_COMAND=nosetests.exe -v --with-gae --gae-lib-root="C:\Program Files\Google\google_appengine" --without-sandbox
SET SRC_PATH=..\src
SET NOSETESTS_RESULT_FILE=nosetests_result.txt

REM ======================================
REM 実処理
REM ======================================

SET EXE_COMAND=%EXE_COMAND% %EXTENDS%
TITLE %EXE_COMAND%

CD /D %SRC_PATH%
%EXE_COMAND% 2>%~dp0\%NOSETESTS_RESULT_FILE%
CD /D %~dp0
FINDSTR "FAILED (*" %NOSETESTS_RESULT_FILE% > NUL
SET ERROR_CODE=%ERRORLEVEL%

IF "%ERROR_CODE%"=="0" (color 4F & type %NOSETESTS_RESULT_FILE% 1>&2 & SET RETURN_CODE=1) ELSE (color 27 & type %NOSETESTS_RESULT_FILE% 2>&1 & SET RETURN_CODE=0)
@PING -n %WAIT_TIME% localhost >NUL
EXIT /B %ERROR_CODE%

動作確認環境:WindowsXP SP3 + eclipse3.5.2 ( +PyDev 1.6.3 + Nose 0.11.4+ NoseGAE 0.1.7)

配置はこんな感じを前提にしてます。
[workspace]\[project]\bat\nosetest.bat
[workspace]\[project]\src\app.yaml
[workspace]\[project]\src\app.yaml
[workspace]\[project]\src\main.py
[workspace]\[project]\src\test_main.py
[workspace]\[project]\src\htmlgenerator\base.py
[workspace]\[project]\src\htmlgenerator\test_base.py
使い方:
その1:
  外部ツールにnosetests.batを登録、起動時のパラメータに0を指定。
  登録した外部ツールを、一度実行。
  「前回実行した外部ツールを起動」のメニューに、Ctrl+Tを割り当て。
 その2:
  ショートカットを作成して、スタートメニューに登録。
  Windowsキーを押してスタートメニューを表示させて、Nを押す。

2010年10月27日水曜日

PythonによるGoogle App Engingeのテスト駆動開発

GAE/P で、テスト駆動開発をeclipseで効率よく進める方法を自分なりに模索してました。

個人的な結論:
doctestは便利だけど、ソースが見づらくなりがちなので、無し。
unitttest + nose(+NoseGAE)のほうが、テストコードと本番コードを分離できるので良い。
さらに、GAETestBase(+gaeunit.py)は、便利そうなので、解読中。
ただ、どうもkayにバンドルされているものの方が一部よさそうなので、
標準のものと見比べながら都合の良いテストモジュールを作成中。

試行錯誤の際につまったこと:

問題1:
ただnosetestsを実行すると、PYTHONPATHが足らなくて盛大にこける。
解決1:
実行前にSET PYTHONPATH=???;???・・・で適当に足すと通るようになる。

問題2:
でもどうせならNoseGAEという便利なものがあるらしいので入れてみる。
しかし、nosegaeをいれて、nosetests --with-gaeとやると、
エラー(ImportError: No module named dev_appserver)が発生。
解決2:
http://d.hatena.ne.jp/sinsoku/20100714/1279036364
google_appengineのデフォルトのパスの指定がunix用になっているので、指定する。
指定方法1:
nosetests --with-gae --gae-lib-root="C:\Program Files\Google\google_appengine"
指定方法2:
D:\Documents and Settings\自分のWindowsID\.nosercに、以下のように記載する:
[nosetests]
gae-lib-root=C:\Program Files\Google\google_appengine

問題3:
単体実行すると動作するテストコード達が、
nosetests --with-gae --gae-lib-root="C:\Program Files\Google\google_appengine"
から実行すると、なにやら盛大に全部エラーになる。
解決3:
イッシーのテストコードの書き方がおかしいのかもしれませんが、
以下のように起動すると、とりあえず普通にテストしてくれました。
nosetests --with-gae --gae-lib-root="C:\Program Files\Google\google_appengine" --without-sandbox
でも、sandbox環境を使わないと、NoseGAEの意味が半減しているような?

問題4:
nosetestsをEclipseから実行するのがめんどう
解決4:
その1:
WindowsXPのショートカット・キー登録機能を使う:
http://www.atmarkit.co.jp/fwin2k/win2ktips/150use_shortcut/use_shortcut.html
その2:
WindowsXPのスタートメニューを利用:
http://www.geocities.co.jp/SiliconValley/4900/s-cut.html
その3:
eclipseの外部ツール登録して起動:
①nosetestsを外部ツールとして登録
②外部ツールを実行
③「最後に起動された外部ツールを実行」にショートカットを設定
http://www.ryuzee.com/contents/blog/553
その4:
eclipseのプロジェクトのビルド設定に組み込んで起動:
http://d.hatena.ne.jp/Nilfs/20100413

イッシーは、その2とその3にしました。
その4は、他の処理(カバレッジの取得とか)でも勝手に動いてしまったりするのが気になりました。

問題5:
nosetestsの実行結果がしょぼくて、ぱっと見てエラーかどうかがわからない。
Red/Green/Refactor、っていうけど、赤くもならないし緑にもならない。赤くらい欲しいな。
red-noseを入れても、XPのコマンドラインでは、ansiエスケープシーケンスを処理できないので、色がつかない。
Eclipseから実行すると、みんなエラー扱いになる。
解決5:
以下のようなバッチファイルを作成。
①nosetestsの実行し、出力結果を一時ファイルに出力させる
②一時ファイルを見て、中身にエラーが含まれていた場合:
コマンドラインの背景色を赤に変える
エラー出力に一時ファイルの内容を出力する
③一時ファイルを見て、中身にエラーが含まれていなかった場合:
コマンドラインの背景色を緑に変える
標準出力に一時ファイルの内容を出力する
④一定時間(デフォルト30秒)たってからコマンドラインを閉じる

具体例は、次のエントリで書きます。

検討中の課題:
課題1:
バッチから起動したnosetestsが、なんか重い
対策1:
原因は、一時ファイルに対して、ウィルスチェックが走っていることらしい。
回避策を検討。(たぶん拡張子を変えればいける)
あと、テストが完了してからでないと結果を見れないのは、標準出力を使っているから仕方が無い。
その点は色をつけるのとトレードオフなので、あきらめる。

課題2:
nosetestsで実行したカバレッジは、eclipseではうまく使えない?
対策2:
どうもnoseとeclipseで使っているカバレッジの仕様が違うようなので、仕方が無い?
カバレッジの取得は、eclipseの機能を使うかな。
http://zakizaki.cocolog-nifty.com/software/2010/10/pydevtrac-plugi.html
特に、
ウィンドウ→設定→実行/デバッグ→起動→起動操作=常に前回起動したアプリケーションを実行する
とやると、簡単にこれで起動できる。
んー。カバレッジはこっちでやろう。
色にこだわらなければ、テストの実行もeclipseの機能でよいかも。