ホワイトボックステストFlask追加ユニットテスト

4706 ワード

もとの場所
目次
前言概要unittest
pytest
nose
Flaskにnoseを加えた単一測定例収穫について話します
参考文献
    


ユニットテストの重要性は言うまでもなく、古典的なテストピラミッドのように、最下位はユニットテストであり、コード層に近づくほど収益が大きくなる.
Flaskがマイクロサービスを記述する過程で、ユニットテストに注意したことがなく、最近コードを再構築する準備をしている過程で、以前のコードにはまだ大きな最適化空間があり、しかもユニットテストに適していないことに気づき、ユニットテストの展開を便利にするために、以前のフレームワークを再構築する必要があり、自分が非常に損をしていると感じた.
テスト出身だが、自分はユニットテストを実際に実践したことがない.本当に罪悪感がいっぱいです.
最近ユニットテストの知识をたくさん见て、一つの言叶が印象的で、皆さんと一绪に勉强しています.
Martin Fowler氏は、「コードをテストする方法が分からない前に、プログラムを書くべきではない」と述べた.プログラムが完了したら、テストコードも完了する必要があります.テストに成功しない限り、仕事ができるプログラムを書いたとは思えません.」

概要


まずPythonのユニットテストの常用フレームワークを紹介します
  • unittest
  • pytest
  • nose

  • unittest
    unittestはPython内蔵の標準クラスライブラリです.そのAPIとJavaのJUnit、.NetのNUnit,C++のCppUnitは似ています.
    unittestの最も核心的な4つの概念はtest case,test suite,test runner,test fixtureである.unittestを継承する.TestCaseはテスト例を作成します.
    unittestの使用にはいくつかの潜在的なルールがあります
  • 各テストファイルにはクラスを書く必要があります.set_が必要です.upとtear_downの方法は、テストファイルごとにset_を追加する必要があります.upとtear_down
  • unittestのデフォルトはアルファベットと数字の順序で実行され、私たちが指定した順序で実行する必要がある場合はsuitを使用します.addTestの方式は
  • を指定します
    pytest
    pytestは機能が豊富で柔軟なテストフレームワークですが、文法は簡単です.モジュールを記述するように、ユニットテストを作成します.unittestと比較して、同じテスト機能を実現します.py.testがやったことはもっと少ない.
    pytestにはいくつかの特徴があります.
  • pytestコマンドラインにカラー出力
  • がある
  • 特定クラステンプレート
  • を使用する必要はない.
  • setup/teardown構文とunittestの互換性はnoseほど高くなく、実現方式もnose直観
  • に及ばない.
    nose
    noseはunittestの拡張でありpythonのテストをより簡単にする.noseは自動的にテストコードを発見して実行し、noseは大量のプラグインを提供しています.例えば、テスト出力のxUnitcompatible、レポートの上書きなどです.
    noseは特定のフォーマットを使用せず、クラスコンテナを必要とせず、import nose~(これは、テスト例を書くときに追加のapiを使用する必要がないことを意味する).
    Noseの使用は非常に簡単で、輪を持っています.
  • は、すぐにクラスを書くのではなく、テスト関数を書くだけです.
  • 自動検索と収集テストは、自分で手動でテストセットを構築する必要はありません.
  • はプラグインをサポートし、他の非常に実用的な標準化プラグイン(coverage,output capture,drop into debugger on errors,doctests support,profiler)
  • を組み合わせることができます.
  • は、テストにラベルを付け、ラベルに基づいて非常に柔軟なテストセットを選択することができる.
  • 並列テスト;
  • より良いサポートfixtures;
  • ジェネレータテスト.

  • noseの宣言を粉にする
    nose extends unittest to make testing easier.

    Flaskにnoseを加えた単一測定例


    まず私のFlaskのサービスを簡単に見てみましょう.
    appの中にはメインフレームワークがあり、mainの中にはapiとagent、scheduleがあり、agentはメール送信をカプセル化した非同期操作であり、scheduleはタイミング実行のバックグラウンド実行操作をカプセル化し、appの下のmodelsはデータベース関連のテーブル構造であり、appと同級のtestsの下には、私が追加した単測用例ファイルがあります.
    まずtestsのパッケージ構造を新規作成し、init.pyではsetupのような動作を追加し、
    from app import create_app, db

    app = create_app(‘testing’) app_ctx = app.app_context() app_ctx.push()
    test_app = app.test_client() db.drop_all() db.create_all()
    def tearDown(): app_ctx.pop()
    ランニングユニットテストでは、testing構成のmockサービスを開始し、データベースを削除して新しいデータベースを初期化し、テストが終了した後、pushを初期化するapp_を解放する必要があります.context.
    一般に、Flaskサービスがテストを必要とする注目点は主にmodels、functions、viewsである.もちろんviewsはいくつかのページのテストであり、seleniumで実現するのと似ています.
    まずapiとmodelsのテストについて簡単に紹介します.
    def test_logs_api(): 
    resp = tests.test_app.get('/api/test')
    assert_equal(resp.status_code, 200)
    def test_log(): 
    log = models.Log(
    date_created=datetime.datetime.now(),
    result=111,
    job_name=111,
    )
    db.session.add(log)
    db.session.commit()
    log_id =models.Log.query.filter(models.Log.result ==
    111).first()
    assert log_id is not None
    

    すべてとても簡単で一目瞭然で、私の経験は1つの方法あるいは実例に対してテストを行う時、1つのテストだけを使います.これにより、後でメンテナンスが容易になり、論理がより明確になります.
    コマンドラインでnose呼び出しを使用して実行します.
    nosetests -v --with-coverage --cover-package=app 

    テスト結果とオーバーライド率の結果が表示されます

    Name Stmts Miss Cover


    app/init.py 44 0 100% app/config.py 58 3 95% app/main/init.py 3 0 100% app/main/agent.py 37 16 57% app/main/api.py 135 53 61% app/main/schedule.py 37 25 32% app/models.py 84 13 85% app/util/init.py 0 0 100%

    app/util/util.py 130 33 75%


    TOTAL 528 143 73%


    Ran 6 tests in 6.905s
    OK

    収穫について話す


    本当にユニットテストを書くとき、自分が以前業務を実現するために働いていたことに気づき、基本的に業務を実現したが、多くのfunctionはユニットテストを展開することができず、本当に解結合、関数式プログラミングを理解した.
    私たちはプログラミングの中でテストの思想で設計構造に影響を与えるべきで、私たちがよく言うテスト駆動開発であり、テストの思想が欠けているとソフトウェアプロジェクトに巨大な潜在的な隠れた危険をもたらす.
    もちろんテストは万霊薬ではなく、ソフトウェア開発は難しい仕事です.成功を勝ち取るためには、真の目標を常に覚えなければならない.問題を解決するだけでなく、簡潔で、効率的で、優雅に実現しなければならない.

    参考文献


    nose公式サイト
    pytest公式サイト
    コード複雑度の監視
    Python高品質コードの作成