Pythonのユニットテストフレームワークのシリーズ:ユニットテスト:(A)の単位テストフレームワークPythonの話


著者:HelloGitHub- Prodesire

「オープンソース・プロジェクトの説明」シリーズのHelloGitHub、プロジェクトのアドレスします。https://github.com/HelloGitHub-Team/Article

序文

それはPythonのユニットテストフレームワークになると、おそらくパイソンにさらさ友人が最初に考えがある頭のunittest
確かに、非常に良好で、広く様々なプロジェクトで使用されているPythonの標準ライブラリ、など。しかし、あなたは何を知っていますか?実際には、多くのPythonのプロジェクト、これよりはるかに主流のユニットテストフレームワーク。

Pythonは、異なるシナリオ、時間のさまざまなニーズに直面して誰もが、最良の選択し、バランスをとることができるようせるために、その機能や特徴について話すと、彼らの類似点と相違点を比較するための記事のこのシリーズは、人気のユニットテストフレームワークを紹介しますユニットテストフレームワーク。

本文默认以 Python 3 为例进行介绍,若某些特性在 Python 2 中没有或不同,会特别说明。

I.はじめに

ユニットテストのJUnitに触発ユニットテストフレームワークは早い、ユニットテストフレームワークと他の主流の言語は、同様のスタイルを持っています。

これは、テストの自動化、事前共有テスト(セットアップ)複数のクリーン(TEARDOWN)コード、重合濃度をテストするためのテストケースを複数、及び試験及び独立レポートフレームワークをサポートします。

第二に、例により調製

この次の簡単な例は、から来ている公式文書の文字列メソッドの3種類をテストするために、: 、upperisuppersplit

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

継承によって上記例たunittest.TestCaseテストケースを作成します。
このクラスでは、で定義されたtest方法、テストフレームの先頭は、実行するために独立したテストとして使用されます。

各ユースケースは、使用するunittest測定対象物の挙動を決定するための内蔵アサーションメソッドが予想される場合、例えば:

一部はなぜビルトインアサーションを使用しない、不思議に思うかもしれませんassert、とそんなに追加のアサーションメソッドとそれの使用を提供すること?その理由は、使用していることであり、unittestランの終了時にテストフレームワークによって提供されるアサーション・メソッドを、すべてのテスト結果は、情報およびテストレポートの富を生成するために集約することができます。直接使用することは、assertあなたも期待に沿った測定対象かどうかを確認する目的が、エラーが発生したユースケースを実現することができますが、エラーメッセージは金持ちではありません。

第三に、実行し、使用が認められました

unittest 例で見つかったの自動サポート(再帰的に):

  • 現在ですべての行で見つかったデフォルトのディレクトリtest*.pyテストケース
    • 使用しますpython -m unittestか、python -m unittest discover
  • することで-s、カタログのパラメータは、自動検出を指定する-pパラメータはモードでファイル例名を指定します
    • python -m unittest discover -s project_directory -p "test_*.py"
  • 位置パラメータと名のパターンの例でファイルで指定された自動検出ディレクトリ
    • python -m unittest discover project_directory "test_*.py"

unittest 指定されたユースケースの実装をサポートしています:

  • テストモジュールを指定します。
    • python -m unittest test_module1 test_module2
  • テストクラスを指定します。
    • python -m unittest test_module.TestClass
  • 試験方法を指定します
    • python -m unittest test_module.TestClass.test_method
  • テストファイルのパスを指定します(のみPythonの3)
    • python -m unittest tests/test_something.py

第四に、テストフィクスチャ(備品)

テストフィクスチャは、試験前(SETUP)及びクリーン(TEARDOWN)法です。

予備試験法セットアップは() データベース接続を確立するように、いくつかの準備作業を行います。それは自動的にユースケーステストフレームワークの実装前に呼び出されます。

クリーンアップのための試験方法ティアダウンを()いくつかのクリーンアップ作業、データベースからそのような切断を行います。テストフレームが自動的に起動された後には、(障害が発生した場合を含む)の実施形態を使用して実行を完了する。

事前テストとクリーンアップの方法は、異なる実行レベルを持つことができます。

4.1効果のレベルを取る:試験方法

私たちは、各テストの前と後の各テストメソッドの前に前およびクリーンアップの方法を実行する必要がある場合は、テストクラスを定義する必要がありますセットアップ()ティアダウンを()

class MyTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

4.2効果のレベルを取る:クラスのテストを

我々は方法の前に一度だけ、単一のテストクラスをしたい、その後、テストクラス内のすべてのテストを実行し、最終的にクリーンアップメソッドを実行する場合は、テストクラスを定義する必要がありますsetUpClass()tearDownClassを()

class MyTestCase(unittest.TestCase):
    def setUpClass(self):
        pass

    def tearDownClass(self):
        pass

4.3効果のレベルを取る:テストモジュールを

我々は、単一のテストモジュールは、メソッドの前に1回だけ実行され、その後、すべてのクラスのすべてのテストでテストモジュールを実行し、最終的にクリーンアップ方法を実行したい場合は、テスト・モジュールを定義する必要があります(setUpModuleを)tearDownModule()

def setUpModule():
    pass

def tearDownModule():
    pass

第五に、テストが失敗したスキップすることが期待されます

unittest スキップしたり、条件付きテストをスキップサポートし、また、テスト失敗をサポートすることが期待されます。

class MyTestCase(unittest.TestCase):

    @unittest.skip("直接跳过")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "满足条件跳过")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "满足条件不跳过")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("跳过")
        # test code that depends on the external resource
        pass

    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "这个目前是失败的")

シックス・サブテスト

時には、あなたは、このようなテストを書きたいかもしれません:ロジックの同期間をテストするためのテスト方法で異なるパラメータを渡されたが、それは、テストと見なされますが、場合、子テスト(、Nとみなすことができますパラメータの数)試験です。次に例を示します。

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

例で使用with self.subTest(i=i)しても単一のサブテストが失敗したサブテストの定義、この場合には、それ以降のサブテストの実行には影響しません。このように、我々は、出力が通過しない三つのサブテストを持って見ることができます:

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

七つのテスト結果出力

例示するために、セクションで述べた例に基づいて簡単な例unittest完了までテスト実行の出力結果を表示します。

デフォルトの出力は非常に単純なケースでは、ショーは、ユースケースの数だけでなく、それは時間を実行します:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

指定することで-vパラメータを、デフォルトの出力の内容に加えて、詳細に出力され、さらに使用する名前の例を示しますすることができます:

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

仮定しtest_upper、テストが失敗し、詳細な出力モード、以下の結果:

test_isupper (tests.test.TestStringMethods) ... ok
test_split (tests.test.TestStringMethods) ... ok
test_upper (tests.test.TestStringMethods) ... FAIL

======================================================================
FAIL: test_upper (tests.test.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Uvsers/prodesire/projects/tests/test.py", line 6, in test_upper
    self.assertEqual('foo'.upper(), 'FOO1')
AssertionError: 'FOO' != 'FOO1'
- FOO
+ FOO1
?    +


----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=1)

私たちがした場合test_upperの方法をテストするself.assertEqual変更されたassert後、テスト結果の出力が役立つエラーのトラブルシューティングに少ないコンテキスト情報になります。

test_isupper (tests.test.TestStringMethods) ... ok
test_split (tests.test.TestStringMethods) ... ok
test_upper (tests.test.TestStringMethods) ... FAIL

======================================================================
FAIL: test_upper (tests.test.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/prodesire/projects/tests/test.py", line 6, in test_upper
    assert 'foo'.upper() == 'FOO1'
AssertionError

----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=1)

あなたがHTML形式でレポートを生成したい場合は、(のような余分な助けサードパーティのライブラリ必要HtmlTestRunnerを動作させるために)。

サードパーティのライブラリをインストールした後、あなたが直接することはできませんpython -m unittest同様の追加--html report.htmlHTMLレポートを生成する方法がありますが、実行し、HTML形式のレポートを取得するために、独自のテストケースを記述する必要が少量のコードを。
詳細については、HtmlTestRunner命令を

VIIIの概要

unittestの Pythonの標準ライブラリとしてユニットテストフレームワークを使用するのは簡単提供し、強力な、日常試験の要件は十分に満足させることができます。サードパーティのライブラリを導入することなく、ユニットテストは、最良の選択です。

次回の記事では、サードパーティのユニットテストフレームワークを紹介しますnoseと、nose2について話とは対照的に、それは、unittest非常に多くの開発者がそれを好むことに向上します。

技術と興味深い話題を議論するために、交換グループに参加する国民の関心番号

おすすめ

転載: www.cnblogs.com/xueweihan/p/11494418.html