PySpec リファレンス

仕様定義デコレータ

@spec

このデコレータが付くと、PySpecは検証メソッドとして扱います。
クラスのメソッド、モジュールの関数の両方に使用できます。

example::
  @spec
  def stack_empty_behavior():
    """スタックは空かどうかチェックできる"""
    stack = Stack()
    About(stack).should_empty()


パラメータ 説明
``expected`` 検証で出力される例外を指定します
``group`` 使用する準備メソッドを指定します

@context

仕様の前提条件を設定するメソッドに指定します。JUnitで言うところの
setupメソッドになります。このコンテキストメソッドは、仕様メソッドが
呼ばれる前に呼ばれます。
PySpecでは、準備コードはなるべくこのコンテキストメソッドの中に書くことを
推奨しています。他のxUnitフレームワークよりも多くの準備メソッドを書くことに
なると思います。

もしもgroupパラメータを指定しなかった場合にはすべてのコンテキストメソッドが
仕様メソッドがそれぞれ実行される前に呼ばれます。

パラメータ 説明
``group`` コンテキストメソッドのグループを指定します

@spec_finalize

検証メソッド実行後の片づけのメソッドに指定します。JUnitで言うところの
teardownメソッドになります。それぞれの検証メソッドが呼ばれた後に呼ばれます。

パラメータ 説明
``group`` 片付けメソッドのグループを指定します

@class_context

@contextと似ていますが、このデコレータを指定したメソッドは、最初の検証メソッドの前に、
1度だけ実行されます。もし何か変数を設定したりする場合にはクラス変数にして
ください。

@class_finalize

@finalizeと似ていますが、このデコレータを指定したメソッドは、
最後の検証メソッドの後に、1度だけ実行されます。
このメソッドは、仕様のテストが失敗しても実行されます。

@ignore

検証メソッドの実行を無視します。

example::
  @spec
  @ignore
  def test_stack():
    # 未実装
    pass

テスト用検証メソッド

About(実際値).should_equal(期待値)

値が同一である、ということを検証します。同一でないことを示す、
``shouldnotequal()`` もあります。

About(実際値).shouldequalnearly(期待値, 誤差)

浮動小数点数の同値性テスト。値が誤差以内かどうかでテストを行います。
誤差値を省略した場合は、誤差値は期待値の1%になります。
同一でないことを示す、 ``shouldnotequal_nearly()`` もあります。

About(実際値).shouldbetrue()

値がTrueかどうかを検証します。 ``shouldbefalse()`` もあります。

About(実際値).shouldbesame(期待値)

両方のオブジェクトが同一( ``id()`` の返値が同一)かどうかを検証します。
``shouldnotbe_same()`` もあります。

About(配列).should_include(要素)

指定された要素が配列に含まれるかどうかを検証します。指定できるのは、
配列( ``contains()`` か ``iter()``
が実装されているオブジェクト)です。 ``shouldnotinclude()`` もあります。

About(配列).shouldbeempty()

指定された配列が空かどうかを検証します。指定できるのは、配列( ``len()``
が実装されているオブジェクト)です。 ``shouldnotbe_empty()`` もあります。

Verify.fail()

テストを失敗させます。実行パスが間違っているということを表明する場合に使用します::
  @spec
  def exception_should_be_raised():
    try:
      do_something()
      Verify.fail()
    except ValueError:
      pass


例外を扱うことができないテスティングフレームワークでは、例外を投げる
仕様を記述するためには、このように100%失敗する表明メソッドを利用する
必要がありました。
PySpecではもっとシンプルに以下のように書くことができます::
  @spec(expect=ValueError)
  def exception_should_be_raised():
    do_something()

もしこのメソッドのいい使い方を思いついた方は僕まで送って下さい。

Verify.ignore()

テストを無視させます。 ``@ignore`` を指定するのと同じです。

example::
  @spec
  def connect_to_SQLServer():
    if sys.platform != "win32":
      Verify.ignore()
    do_something()

簡易モックオブジェクト

これらのクラスは ``pyspec.mockobject`` モジュールで定義されています。
これらはPySpec自身のテストのために実装されました。

MockObject / MockObjectRecorder

この二つのクラスが基本的なモックオブジェクトのクラスになります。
これらのクラスは一緒に使用します。MockObjectRecorderクラスによって
メソッド呼び出しを記録します。MockObjectRecorder.getmockobject()
を呼ぶと、記録済みのMockObjectのオブジェクトが取得できます。
このオブジェクトを使うと、メソッド呼び出しの検証を行うことができます。

example::
  recorder = MockObjectRecorder()     # まずレコーダーを作成します
  recorder.add(1, 2) == 3             # このメソッドは3を返します
  calc = recorder._get_mock_object_() # ここで記録終了です
  
  print calc(1, 2)    # => 3
  calc._verify_()     # もし、まだ呼ばれていないメソッドがあれば
                      # AssertionError例外を投げます


MockObjectRecorderに対する操作はコンテキストメソッド中に書くのをおすすめします。
また、作成されたモックオブジェクトの verify() メソッド呼び出しは仕様記述
メソッドに記述してください。

モックオブジェクトに関するクラスの特殊なメソッドの一覧に関しては以下の表を
見て下さい。これら以外のメソッド呼び出しに関しては、レコーダーオブジェクトが
すべて記録します。

MockObjectRecorder(is_print=False) is_print=True にすると、コンソールに記録、呼び出し情報を出します
MockObjectRecorder._get_mock_object_() モックオブジェクトを作成して返します
MockObject._verify_() 仕様記述メソッドの最後で呼んで下さい。


MockObjectRecorderは以下のような柔軟なメソッド呼び出しの記録をサポートしています。.

example::
  recorder = MockObjectRecorder()
  recorder.add(1, 2).repeat(3) == 3    # 3回呼び出します
  recorder.mul().with_any_parameter()  # どんなパラメータ呼び出しも許可します

FileMockObject

ファイル出力を検証するための、ファイルオブジェクトのモックです。
コンストラクタで指定された文字列との比較検証を行います。

ただし、出力メソッドのサポートはwrite()のみで、writelines()や、
その他のメソッドは実装されていません。

FileMockObject(expected_contents) 期待される結果をcontents(文字列)で設定する
write(actual) 書き込みを行います。期待される結果と異なれば例外が発生します
_verify_() 期待された結果との比較を行います。テストケースの最後に呼んで下さい

MockSocket

ソケットオブジェクトのモックです。送受信のシミュレートを行います。
Pythonの標準ライブラリと使い方は一緒です。

ブロックモード、ノンブロックモードの両方に対応しています。
モードの違いは、recvを呼び出したときに、受信予定文字列が空になったときの挙動に影響があります。
ノンブロックモード時はAssertionError, ブロックモード時はsocket.errorが発生します

MockSocket(recv=None, send=None) 送受信の期待値を設定することができます。文字列の配列で指定します
_add_recv_message_(*message) 受信文字列を追加します
_add_send_message_(*message) 送信文字列を追加します

仕様名称

良い仕様を書くためには、良い名前を付ける必要があります。 PySpecでは、この名前を付けるのに
二通りの方法があります。これらの仕様名は結果レポートの中に書き込まれます。

メソッド名

メソッド名を使用する書き方がシンプルな方法です。

メソッド名 仕様名
A_stack_which_have_one_value() A stack which have one value
version_info__in_sys_module() version_info in sys module
one_of__test_method__should_fail() one of test_method should fail


この機能は pyspec.util.createspecname() で実装されています。

Docstring

Docstringも仕様名として使用されます。Python 2.Xはメソッド名としてはアスキー英数字のみ
が使用できます。この機能はアジア圏のプログラマが自分の言語を使いたい場合に使用できます。

もしコンテキストメソッドおよび、仕様メソッドにdocstringを書いたとすると、最初の行が
仕様名として使用されます。

PySpecはソースコードの最初の行から文字コードを取得します。もし日本語や中国語などの
言語を使用したい場合には以下のように書きます::

# -*- coding: utf8 -*-

PySpecはPythonで扱えるコーデックならば扱うことができます。

example::
    class StackBehavior(object):
        """スタックの動作仕様."""
        @context
        def A_stack_with_one_item(self):
            """要素をひとつ持つスタック."""
            self.stack = Stack()
            self.stack.push("one item")  

        @spec
        def should_not_be_empty(self):
            """空ではない."""
            About(self.stack).should_not_be_empty()

result::
    要素をひとつ持つスタック
        空ではない ... OK

Last edited Jan 23, 2008 at 4:13 PM by shibu, version 1

Comments

No comments yet.