読者です 読者をやめる 読者になる 読者になる

Sphinx で Google Analytics を利用する。

SphinxGoogle Analytics をトラックするスクリプトを埋めるのは
どうすればいいんだろと思っていたら、 sphinx-contrib にプラグイン
公開されていました。


sphinxcontrib-googleanalytics
https://bitbucket.org/birkenfeld/sphinx-contrib/src/bb0b2036aa45/googleanalytics/


sphinxcontrib-googleanalytics の使い方を紹介します。


1. Google Analytics のIDを取得する。
2. Sphinx / sphinxcontrib-googleanalytics をインストールする。

   $ easy_install -ZU sphinx
   $ easy_install -ZU sphinxcontrib-googleanalytics

3. sphinxプロジェクトを作成する。
4. conf.py に sphinxcontrib-googleanalytics の設定をします。
プラグインを有効にします。

extensions = ['sphinxcontrib.googleanalytics']

Google Analytics の設定をします。

# Google Analytics
googleanalytics_id = 'UA-123-456'

5. make html をして、HTMLページを生成する。

以上の手順で簡単に Google Analytics を利用できます。

Google Analytics を埋め込んだページ例 http://aohta.github.com/nose_tutorial/

dotcloud に flask アプリをデプロイする。

はじめに

最近、dotcloud のアカウントを入手したので、Flaskアプリをデプロイしてみました。
dotcloud の最初の手順は、id:ymotongpoo記事がわかりやすいです。

アプリケーションをデプロイする

Flask アプリケーションをデプロイしてみます。

ディレクトリ構成は次のようにしました。

$ tree www/
www/
├── hello
│%% ├── hello.py
│%% └── hello.pyc
├── requirements.txt
└── wsgi.py

import sys
sys.path.append('hello')
from hello import app

def application(environ, start_response):
  return app(environ, start_response)
  • requirements.txt を用意します。
    • echo flask >> requirements.txt で作成します。
  • 肝心のFlaskアプリケーションは、"Hello, World"を出すだけです。

nose まとめ7 (nose plugin のインターフェース)

はじめに

nose プラグイン用インターフェースの紹介です。

nose プラグインは、インターフェースごとに動作するタイミングが決められています。
プラグインを実行させたい、タイミングで実行されるインターフェースを記述することで、プラグインを作成してきます。

インターフェース

プラグイン作成時によく使いそうなインターフェースを紹介します。

addError(test, err)

テストの実行が失敗したときに呼び出されます。

err タプルの中には、Exception の内容が入ります。

addFailure(test, err)

テストが失敗した後に呼び出されます。

err タプルの中には、Exception の内容が入ります。

addSuccess(test)

テストが成功した後に呼び出されます。

beforeTest(test)

テスト実行前に呼び出されます。

afterTest(test)

テスト実行後に呼び出されます。

テスト結果は、考慮されません。

おわりに

ここで紹介したインターフェースは、ごく一部です。
詳しくは、 nose: Plugin Interface を参照してください。

nose まとめ6 (nose プラグインの実行)

はじめに

nose プラグインの実行方法です。
作成したプラグインは、明示的に指定しないと利用できません。

実行方法

nose プラグインの実行方法は、あらかじめ登録されているプラグインを呼び出すか
実行スクリプトからプラグインを登録し、実行させる2種類の方法があります。

あらかじめ登録する

nose のプラグインとして実行環境にインストールする方法です。

インストールには、 setup.py を利用します。

インストールが完了すると、 nosetest コマンドから呼び出せるようになります。
プラグインが有効かどうかは、 nosetest -h で確認できます

実行スクリプトから

nosetest コマンドを実行する以外に、nose.main を実行しテストを実行する方法があります。
プラグインファイルがあるディレクトリに、 PYTHONPATH が通っていれば使用できます。

プラグインを import し、 addplugins にリストとして渡します。
実行時オプションに、プラグインを利用する引数(--with-afterlog)を渡す必要があります。

   #!/usr/bin/env python

   import nose
   from logplug import AfterLog

   if __name__ == '__main__':
       nose.main(argv=["-v", "--with-afterlog"],
                 addplugins=[AfterLog()])

nose まとめ5 (nose plugin)

はじめに

nose のプラグインの作成方法です。

役割

テスト関数から外れた処理をする場合は、プラグインを作成する必要があります。

たとえば、次のような場合にプラグインを作成します。

  • 各テスト実行後に特定処理を実行させたいが、テスト関数ごとに teardown を書くのがめんどくさい。
  • レポートの出力形式を独自のものにしたい。

書き方

nose.plugins.Plugin を継承したクラスを作成します。

必要なことは、 name を指定すること、プラグインを動作させたいエントリポイントをオーバーライドすることです。

name は、実行時にプラグインを指定するときに使用します。

エントリポイントは、プラグインの動作を定義します。

   from nose.plugins import Plugin

   class AfterLog(Plugin):
     """テスト実行ごとに、ログを出力させます。
     """

     name = 'afterlog'


プラグインを afterlog という名前で登録しています。
実行時には、 --with-afterlog というオプションが生成されており、 --with-afterlog を付与するとプラグインが呼び出されます。

   def afterTest(self, test):
     fd = open('/Users/kuma8/Desktop/log.txt', 'a')
     fd.write('after ')
     fd.write(test.__repr__())
     fd.write('\n')
     fd.close()

テスト実行後に、ファイルに記録させています。

afterTest というエントリポイントは、テスト実行後に実行されます。

ソースコード

テスト関数実行ごとに実行関数をファイルに記録する。

# coding: utf-8

from nose.plugins import Plugin

class AfterLog(Plugin):
  """テスト実行後にログを書き出す。
  """

  name = 'afterlog'
  score = 2 # run late

  def __init__(self):
    super(AfterLog, self).__init__()

  def afterTest(self, test):
    fd = open('/tmp/log.txt', 'a')
    fd.write('after ')
    fd.write(test.__repr__())
    fd.write('\n')
    fd.close()

動作結果

$ nosetest -v --with-afterlog ex1_test.py
$ cat /tmp/after.txt
after Test(sample_test.add_test)

thanks

@aodag先生と@shimizukawa先生に教えてもらいました。
だいたい、1,2時間あれば nose plugin かけますよ。

nose まとめ4 (nose.tools を使う)

はじめに

nose には、簡単にテストするための機能が用意されています。
機能は、 nose.tools パッケージにまとまっています。
いくつかの機能は、前回までに出ていますが、あらためて書いてあります。

使い方

nose.tools.ok_
   ok_(expr, msg=None)

expr が True かどうかを評価します。
msg がある場合は、テスト結果に出力します。

nose.tools.eq_
   eq_(a, b, msg=None)

a と b が等しいかどうかを評価します。
msg がある場合は、テスト結果に出力します。

nose.tools.raises
   @raises(TypeError)
   def raise_test():
     raise TypeError("This test passes")

   @raises(TypeError, ValueError)
   def raise_test():
     pass

テスト関数に期待する値が、例外の場合に使用します。
raises デコレータは、値を複数持てます。

nose.tools.timed
   @timed(.1)
   def time_test():
     import time
     time.sleep(.5)

テスト実行に制限時間を持たせる場合に使用します。
timed で指定した時間を越えた場合は、テスト失敗になります。

nose.tools.with_setup
   @with_setup(setup=x_setup, teardown=x_teardown)
   def x_test():
     pass

テストごとに setup と teardown を実行させる場合に使用します。
パッケージレベル、モジュールレベルの setup/teardown は実行されます。

nose.tools.istest
   @istest
   def skip():
     pass

テストと見なされない関数をテストとして実行させる場合に使用します。

nose.tools.nottest
   @nottest
   def skip_test():
     pass

テストをスキップさせたい場合に使用します。

サンプル

# coding: utf-8
"""
例題3 nose.tools を使う。
"""

from nose.tools import *

def ok_test():
  """ nose.tools.ok_ : expr が True かどうかを評価します。 """
  ok_(1 == 1)

def eq_test():
  """ nose.tools.eq_ : a と b が等しいかどうかを評価します。 """
  eq_(1 + 1, 2)

@raises(TypeError)
def except_test():
  """ nose.tools.raises : テスト関数に期待する値が、例外の場合に使用します。 """
  raise TypeError("This test passes")

@timed(.1)
def time_test():
  """ nose.tools.timed : テスト実行の制限時間を設定します。 このテストは失敗します。 """
  import time
  time.sleep(.5)

def ex3_setup():
  pass

def ex3_teardown():
  pass

@with_setup(setup=ex3_setup, teardown=ex3_teardown)
def ex3_test():
  """ nose.tools.with_setup : テストごとに、setup/teardown を実行します。"""
  ok_(True)

@istest
def skip():
  """ nose.tools.istest : 通常はスキップされますが、テストとして見なされます。 """
  ok_(True)

@nottest
def run_test():
  """ nose.tools.nottest : 通常は実行されますが、テストしません。
  ** run_test は、表示されません。**
  """
  ok_(True)

まとめ

nose.tools を一通り使えば、複雑なテストでない限りはそう困らないと思います。

nose まとめ3 (nose のsetup/teardown)

はじめに

nose の基本的な使い方その2です。

setup/teardown の動作についてです。

役割

テストを行う上で、あらかじめデータを用意しておく必要あったり、
テスト後に作成したデータを削除するときに利用します。

詳しくは、他のブログなどをみましょう。

書き方

nose では、パッケージレベル、モジュールレベル、関数レベルで定義することができます。

パッケージレベルでは、 __init__.py に setup/teardown を定義します。

モジュールレベルでは、テスト用モジュールに setup/teardown を定義します。

関数レベルでは、 nose.tools.with_setup に関数ごとに呼び出したい、setup/teardown をデコレータに渡します。

呼び出し順

テストパッケージ内に上の3つのレベルで、 setup/teardown が定義されていると呼び出し順序は次のようになります。

  1. パッケージの setup
  2. モジュールの setup
  3. 個々の関数の setup/teardown
  4. モジュールの teardown
  5. パッケージの teardown

サンプル

# coding: utf-8
"""
例題2 setup/teardown 付きのテストケースを記述してあります。                                                             
"""

from nose.tools import ok_, eq_, with_setup

def debug_write(message):
  debug_file = open('debug.txt', 'a')
  debug_file.write(message)
  debug_file.close()

def setup():
  debug_write("module setup\n")

def teardown():
  debug_write("module teardown\n")

def b_setup():
  debug_write("func b setup\n")

def b_teardown():
  debug_write("func b teardown\n")

def a_test():
  """ テスト a の呼び出し確認 """
  debug_write(a_test.__str__() + '\n')
  ok_(True)

@with_setup(b_setup, b_teardown) 
def b_test():
  """ テスト b の呼び出し確認 """
  debug_write(b_test.__str__() + '\n')
  ok_(True)

出力結果

$ cat debug.txt
module setup

func b setup

func b teardown
module teardown