nose まとめ2 (nose の基本的な使い方)

はじめに

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

条件式がTrueかどうか、2値が等しいかどうかをチェックする方法です。

テストの作成

まずテスト用モジュールを作成します。

モジュール名には、 "test" を含んでいる必要があります。
そのためテストしたいモジュール名+"_test"などとするとわかりやすくなると思います。

つぎに、同じルールでテスト用関数を作成します。

関数名にも、 "test" を含んでいる必要があります。
1つの機能ごとに名前を付けていくと良いです。

ソースコード

# coding: utf-8
"""
テスト対象のモジュール
"""
def add(x, y):
  return x + y

def sub(x, y):
  return x - y
# coding: utf-8
"""
テスト用モジュール
"""

from nose.tools import ok_, eq_

import ex1

def add_test():
  """ ex1.add test """
  eq_(ex1.add(1, 2), 3)

def sub_test():
  """ ex1.sub test """
  eq_(ex1.sub(1, 1), 0)

def if_test():
  """ if test """
  ok_(1 == 1)

def fail_test():
  """ test fail """
  # ok_(1 == '1', "失敗しました。")
  assert(1 == '1')

テストの補足

nose では、 assert 文がそのまま使えますが、
nose.tools の `ok_` , `eq_` を利用するほうがコードは読みやすくなります。

`ok_` , `eq_` は、 assert のラッパーです。

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

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

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

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

テストの実行

テストの実行は、 nosetests を実行するだけです。
テスト用モジュールのテストがすべて実行されます。

$ nosetests ex1_test.py
...F
   ======================================================================
FAIL: test fail
----------------------------------------------------------------------
Traceback (most recent call last):
...
   assert(1 == '1')
AssertionError

----------------------------------------------------------------------
Ran 4 tests in 0.026s

FAILED (failures=1)


実行時に "-v" を付与することで、テスト関数の docstring を出力できます。

1 行説明を追加すると結果が見やすくなるので、 docstring の記述と "-v" オプションはおすすめです。

-v あり

$ nosetests -v ex1_test.py
ex1.add test ... ok
ex1.sub test ... ok
if test ... ok
test fail ... FAIL
   ======================================================================
FAIL: test fail
----------------------------------------------------------------------
...
    assert(1 == '1')
AssertionError

----------------------------------------------------------------------
Ran 4 tests in 0.003s

FAILED (failures=1)

nose まとめ 1

はじめに

nose を勉強しているので、自分用のまとめを公開していくことにしました。

nose とは

nose は、Python 用のテストフレームワークです。

Python には、 doctest、 unittest といったいくつかのテスト方法があります。
nose は、特に利便性が高く、かつプラグインが充実しているため便利です。

まずは、インストール方法の紹介です。

インストール方法

Python のライブラリは、 インストールコマンドからインストールするの一般的です。

基本的には、パッケージ名を指定することで、インストールが完了します。

  • easy_install
   $ easy_install nose
  • pip
   $ pip install nose

プラグイン

nose を利用したテストを実施していくような環境では、同時にカバレッジを取得したり、テスト件数の増加を確認することが多いです。
カバレッジを取得したり、テスト件数を保存したりする場合のオプションを nose プラグインで用意しています。

プラグインを有効にするために、次のライブラリをインストールします。

   $ easy_install coverage
   $ easy_install unittest-xml-reporting

実行時に、"--with-coverage"、"--with-xunit"オプションを付与するだけで、自動的にカバレッジとテスト件数を保存してくれます。
カバレッジは、テスト実行後に、 xml か html に変換する必要があります。

次回

nose を使ったテストの書き方を予定してます。

nose でテスト実行時のカバレッジを取得する。

はじめに

nose の組み込みプラグインを利用するとテストで実行された時のカバレッジを取得できます。
テスト実行時のカバレッジを取得できるので、テストでカバーできていない範囲など確認できます。

カバレッジを取得する

nose と python-coverage がインストールされている必要があります。
nosetests コマンド実行時に、 --with-coverage オプションを付けることでカバレッジを取得できます。
--cover-tests を付与すると実行されたテスト用コードのカバレッジを取得できます。

インストール手順

 $ easy_install -ZU nose
 $ easy_install -ZU coverage

nose からのカバレッジ取得し、HTMLに変換する。

 $ cd myproject
 $ nosetests -v --with-coverage tests/test.py
 $ coverage html
  • coverage xml とすることで、Jenkins Cobertura Plugin と連携できます。

Jenkins との連携例

 $ nosetests -v -w tests/ --with-coverage --with-xunit
 $ coverage xml
  • テスト結果を xunit形式で出力し、カバレッジを同時に取得しています。
  • テスト実行後にプラグインで読み込めるように、xml形式に変換しています。

独自のジョブ失敗通知

はじめに

Jenkins では、ジョブ結果の通知には、既存のE-Mail通知機能がとても有効です。
しかし、メールで通知されたくなく、独自の通知ツールを使いたい場合には、有効なプラグインがない(見つけられていない)です。

やりたいこと

ジョブが失敗したときに、独自の通知ツールを実行させる。

いま運用中の手順

Hudson Post build task を使っています。

  1. 前処理で、Post build task が実行できるようにログを出力し、失敗検知用のファイルを作成します。
  2. ビルド処理を実行させます。
  3. 後処理で、失敗検知用のファイルを削除します。
  4. Post build task は必ず実行され、失敗検知用のファイルが残っている場合は、通知ツールを実行させます。

ビルド処理に失敗すれば、後ジョブが実行されないため、失敗検知用のファイルが残り、通知ツールが実行されるという仕組みです。

前処理

echo "@@@@START $JOB_NAME/$BUILD_NUMBER @@@@"
touch BUILDING

ビルド処理
後処理

rm BUILDING

Post build task

if [ -f BUILDING ];
then
  $HOME/bin/send_xmpp_server.py
fi

理想は、既存のE-Mail通知機能と同じ動きで、メールの代わりに独自通知ツールを実行させたいのですが。

終わりに

もっと良いプラグインがあるよ。 とか、この機能使えばもっと良くなる等ありましたら、教えてください。

Jenkins のサービス化 その2

はじめに

Twitter で、rpmで利用している人もいるようでしたので、その手順の紹介です。

rpm でのインストール

Tomcat の他に、Fedora, CentOS は、rpmでインストールすることで、サービスとして実行することができます。
インストールから起動までの手順

  1. Jenkins の rpmyum で見つられるようにする。
  2. yum install する。
  3. サービスを実行する。
 # wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
 # rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
 # yum search jenkins
 # yum install jenkins
 # /sbin/service jenkins start

rpm でインストールすると自動設定されること。

  • rpm でインストールすると同時に、ユーザ: jenkins、グループ: jenkins が作成されます。
  • JENKINS_HOME は、 /var/lib/jenkins に設定されます。
  • ランレベル3,5 でjenkinsが自動実行されます。
  • ログファイルは、 /var/log/jenkisn に出力されます。
    • *ログローテートされるかは未確認。

いろいろと自動設定されるので、FedoraCentOS では、rpm からのインストールするほうが良さそうです。

JenkinsをTomcatで動作させる。

はじめに

nohup を利用した運用でも十分利用できますが、動作ログの管理が面倒になります。
そこで、Tomcatなどのアプリケーションサーバを利用します。
内容は、公式サイトほぼそのままです。

Tomcat を用意する

まずは、Tomcatダウンロードして、解凍します。

Jenkins を実行できるようにする。

Tomcatは、Jenkinsだけを運用するため、解凍したTomcatディレクトリ内のwebapps/* をすべて削除します。
次に、jenkins.war を webapps/ROOT.war にコピーします。
実行前にTomcat 用の環境変数を設定するsetenv.shを作成します。
setenv.sh では、 Jenkins のホームディレクトリとヒープサイズを設定します。
ヒープサイズは、環境にあわせて調整すると良いです。
binディレクトリのファイルに対して、アクセス権を変更し、実行します。
Jenkinsが、ROOT.warとして動作するため、
http://localhost:8080/ のみでアクセスすることができます。

手順

 $ wget http://ftp.kddilabs.jp/infosystems/apache/tomcat/tomcat-7/v7.0.8/bin/apache-tomcat-7.0.8.zip
 $ unzip apache-tomcat-7.0.8.zip
 $ cd apache-tomcat-7.0.8
 $ rm -r webapps/*
 $ vi bin/setenv.sh ## 次の内容を書き込みます。
...
#!/bin/bash
export CATALINA_OPTS="-DHUDSON_HOME=/path/to/hudson_home -Xmx512m"
...
 $ chmod 755 bin/*.sh
 $ ./bin/catalina.sh start

動作ログの管理も Tomcat 側で管理されるので長期的に運用する場合に楽になります。

追記しました

コメントを参考に、setenv.sh を利用する手順に変えました。

JenkinsとPythonの連携

はじめに

今回は、Jenkins と Python の連携についてです。

使用するツールは、とても便利なテストフレームワーク nose と
カバレッジ coverage との連携についてです。

nose連携

まず、 nose との連携からです。
nose をそのまま実行したのでは、Jenkinsに取り込めないため、XUnit形式のレポートを出力する必要があります。
XUnit形式のレポート出力には、 unittest-xml-reporting を導入する必要があります。
unittest-xml-reporting がインストールされていると、noseの出力レポートをXUnit形式にすることができます。

インストール

 $ easy_install -ZU nose
 $ easy_install -ZU unittest-xml-reporting

nose の使い方は割愛しますが、コマンドから --with-xunit オプションを付与することで
XUnit形式のレポートを出力させることができます。

レポート結果の集約には、ビルド後の処理に、JUnitテスト結果の集計 へチェックをいれ出力ファイルとなる nosetests.xml を入力します。


coverage 連携

python-coverage を利用するには、 Cobertura Plugin が必要です。
まずは、プラグインをインストールします。

ジョブ中に coverage を XML 形式で出力させます。
ビルド後の処理に、Cobertura カバレッジ・レポートの集計を実行し、出力ファイルを読み込ませます。


最後に

実行結果です。

CIを継続するにあたって、テスト件数の増加とカバレッジの増加が
可視化されているのはモチベーションにつながるので是非とも導入しましょう。