4

単体テスト、機能テスト、統合テストを別々に扱うプラグインを作成しています。
私のテストフォルダーは、正確に次の構造になります。

/tests
-- /unit
-- /functional
-- /integration

各単体テストは unit ディレクトリに存在し、各機能テストは機能ディレクトリに存在します。

私はLayersプラグインに精通していますが、テストを慣習に従わせたいと思っています。
テストを実行する前に適切なレイヤーを挿入するには、どのフックを正確に使用する必要がありますか? それはloadTestsFromModuleフックであるべきですか? 例を見せてもらえますか?

また、テストの種類ごとに要約レポートを分けたいと思います。
どのフックを使用すればよいですか?

4

3 に答える 3

2

これは、発見用のnose2プラグインと、テストを装飾できるattribnose1プラグインからコピーされたいくつかのコードを使用して、nose2で機能するようになりました。attrib

ノーズ 2attribプラグインの使用

あなたは、nose2attribプラグインがカスタム属性をテスト関数とクラスで定義できることを確認できます。

これを機能させるには、テスト関数を定義した後にテストの属性を指定する必要があります。

class MyTestCase(unittest.TestCase):
    def test_function(self):
        self.assertEqual(1+1, 2)
    test_function.custom_attr1 = True
    test_function.custom_attr2 = ['foo', 'bar']

次に、コマンド ライン引数として-Aorを指定して、一連のフィルター処理されたテストを実行し、テスト スイートと照合する属性を一覧表示できます。テスト属性を一致させるためのより複雑な Python 式を許可するorの式コマンドライン引数を使用することもできます。--attributenose2-E--eval-attribute

たとえば、の値で指定されたnose2 -v -A custom_attr1
すべてのテストを実行します。custom_attr1

デコレーターを使用してテスト属性を指定する

ただし、定義後にテストでこれらの属性を定義するという考えが気に入らなかったため、これは私にとっては十分ではありませんでした。代わりにデコレータを使用したかったのnose2ですが、これを行うための組み込みのデコレータがありませんでした。

プラグインのnose1ソースコードattribに行き、関数のソースをコピーしましたattr

def attr(*args, **kwargs):
    """Decorator that adds attributes to classes or functions
    for use with the Attribute (-a) plugin.
    """
    def wrap_ob(ob):
        for name in args:
            setattr(ob, name, True)
        for name, value in kwargs.iteritems():
            setattr(ob, name, value)
        return ob
    return wrap_ob

test/attrib_util.pyこれをファイルに入れました。代わりにデコレータを使用して属性を指定できるようになりました。上記の元のテスト クラス コードは、(IMO) に簡単に変換できます。

from test.attrib_util import attr

class MyTestCase(unittest.TestCase):
    @attr('custom_attr1', custom_attr2=['foo', 'bar'])
    def test_function(self):
        self.assertEqual(1+1, 2)

属性は args または kwargs として指定できることに気付くでしょう。すべての引数は、デフォルト値の を取得しますTrue

このデコレーターをテスト クラスまたは基本クラスで使用することもできattr、属性は内部で定義されたすべてのテスト関数に適用されます。これにより、単体テストと機能テストを非常に簡単に分離できます。

from test.attrib_util import attr

@attr('functional')
class FunctionalTestCase(unittest.TestCase):
    pass

class MyFunctionalCase(FunctionalTestCase):
    def test_function(self):
        print 'this will be considered a "functional" test function'
于 2016-02-16T16:35:03.403 に答える
1

プラグインを作成する必要はありません。組み込みの attr モジュールはこの目的のために設計されています。ただし、ファイル階層には依存しません。代わりに、個々のテストを単体、機能、または統合としてマークします。これは次のようになります。

from nose.plugins import attrib

@attrib.attr("functional")
class FunctionalTestCase(unittest.TestCase):
    pass

機能テストのみを実行するには、次のようにします。

nosetests -a functional

このテスト レイアウトを作成していた場合、おそらく 3 つの unittest.TestCase サブクラスがあり、既に「ユニット」、「機能」、および「統合」とマークされています。新しいテストは、適切なテスト タイプを簡単に継承できます。

于 2013-10-21T19:30:31.070 に答える
0

すでにテストをディレクトリに分類している場合 (前述のとおり)、wantDirectoryメソッドを使用するプラグインを作成できます。

import os.path
from nose.plugins import Plugin

class TestCategory(Plugin):
    """
    Run tests in a defined category (unittest, functional, integration.  Always
    runs uncategorized tests.
    """
    def wantDirectory(self, dirname):
         dirname = os.path.basename(dirname)
         if (dirname in ('unit', 'functional', 'integration') and 
             dirname != self.category):
             return False
         return None

このプラグインの有効化と無効化、およびユーザーの選択したカテゴリの収集を処理するメソッドを作成する必要がoptions()あります。configure()ノーズテストを実行するときは、次の 3 つのカテゴリから選択します。

nosetests --category functional

一度に実行されるテスト カテゴリは 1 つだけなので、テスト カテゴリごとに個別のレポートが作成されます。もちろん、このプラグインを有効にしないことで、いつでもすべてのテストを実行できます。

(まったく異なるアプローチであるため、別の回答として追加します)。

于 2013-10-21T19:51:09.000 に答える