九色91_成人精品一区二区三区中文字幕_国产精品久久久久一区二区三区_欧美精品久久_国产精品99久久久久久久vr_www.国产视频

Hello! 歡迎來到小浪云!


如何在 Flask 中執(zhí)行單元測試


avatar
小浪云 2025-01-16 136

測試對于軟件開發(fā)過程至關(guān)重要,可確保代碼按預期運行且無缺陷。在Python中,pytest是一種流行的測試框架,與標準單元測試模塊相比,它具有多種優(yōu)勢,標準單元測試模塊是內(nèi)置的Python測試框架,并且是標準庫的一部分。 pytest 包括更簡單的語法、更好的輸出、強大的裝置和豐富的插件生態(tài)系統(tǒng)。本教程將指導您設置 flask 應用程序、集成 pytest 固定裝置以及使用 p

如何在 Flask 中執(zhí)行單元測試

第 1 步 – 設置環(huán)境

Ubuntu 24.04 默認情況下附帶 Python 3。打開終端并運行 使用以下命令來仔細檢查 Python 3 安裝:

root@Ubuntu:~# Python3 --versionPython 3.12.3

如果 Python 3 已經(jīng)安裝在你的機器上,上面的命令將 返回 Python 3 安裝的當前版本。如果不是 安裝完畢后,您可以運行以下命令并獲取Python 3 安裝:

root@ubuntu:~# sudo apt install python3

接下來,您需要在系統(tǒng)上安裝 pip 軟件包安裝程序:

root@ubuntu:~# sudo apt install python3-pip

安裝 pip 后,讓我們安裝 Flask。

第 2 步 – 創(chuàng)建 Flask應用程序

讓我們從創(chuàng)建一個簡單的 Flask 應用程序開始。為您的項目創(chuàng)建一個新目錄并導航到其中:

root@ubuntu:~# mkdir flask_testing_approot@ubuntu:~# cd flask_testing_app

現(xiàn)在,讓我們創(chuàng)建并激活一個虛擬環(huán)境來管理依賴項:

root@ubuntu:~# python3 -m venv venvroot@ubuntu:~# source venv/bin/activate

使用以下命令安裝 Flask pip:

root@ubuntu:~# pip install Flask

現(xiàn)在,讓我們創(chuàng)建一個簡單的 Flask 應用程序。創(chuàng)建一個名為 app.py 的新文件并添加以下代碼:

app.py
from flask import Flask, jsonify  app = Flask(__name__)@app.route('/')def home():     return jsonify(message="Hello, Flask!")@app.route('/about')def about():     return jsonify(message="This is the About page")@app.route('/multiply/<int:x>/<int:y>')def multiply(x, y):     result = x * y    return jsonify(result=result)if __name__ == '__main__':     app.run(debug=True)

此應用程序有三個路由:

  • /:返回一個簡單的“Hello, Flask!”
  • /about:返回一個簡單的“這是關(guān)于頁面”消息。
  • /multiply//:將兩個整數(shù)相乘并返回result.

要運行應用程序,請執(zhí)行以下命令命令:

root@ubuntu:~# flask run
output* Serving Flask app "app" (lazy loading)  * Environment: production    WARNING: This is a development server. Do not use it in a production deployment.    Use a production WSGI server instead.  * Debug mode: on  * Running on http://127.0.0.1:5000/ (Press CTRL C to quit)

從上面的輸出中,您可以注意到服務器正在 http://127.0.0.1 上運行并偵聽端口 5000。打開另一個Ubuntu控制臺并一一執(zhí)行以下cURL命令:

  • GET:curl http://127.0.0.1:5000/:5000/
  • GET:卷曲http://127.0.0.1:5000/about:5000/約
  • GET:卷曲http://127.0.0.1:5000/multiply/10/20:5000/乘/10/20

讓我們了解一下這些 GET 請求是什么做:

  1. 卷曲http://127.0.0.1:5000/::5000/: 這將向 Flask 應用程序的根路由(‘/’)發(fā)送 GET 請求。服務器響應一個包含消息“Hello, Flask!”的 JSON 對象,演示了我們的主路由的基本功能。

  2. curl http://127.0.0.1:5000/about::5000/about: 這將向 /about 路由發(fā)送 GET 請求。服務器使用包含消息“這是關(guān)于頁面”的 JSON 對象進行響應。這表明我們的路線運行正常。

  3. curl http://127.0.0.1:5000/multiply/10/20::5000/multiply/10/20: 這會向 /multiply 路由發(fā)送一個 GET 請求,其中包含兩個參數(shù):10 和 20。服務器將這些參數(shù)相乘 數(shù)字并以包含結(jié)果 (200) 的 JSON 對象進行響應。 這說明我們的multiply路由可以正確處理URL 參數(shù)并執(zhí)行計算。

這些 GET 請求允許我們與 Flask 交互 應用程序的 API 端點,檢索信息或觸發(fā) 在服務器上執(zhí)行操作而不修改任何數(shù)據(jù)。它們對于 獲取數(shù)據(jù)、測試端點功能并驗證我們的 路由按預期響應。

讓我們看看其中的每個 GET 請求操作:

root@ubuntu:~# curl root@ubuntu:~# curl http://127.0.0.1:5000/:5000/
Output{"message":"Hello, Flask!"}
root@ubuntu: ?#卷曲root@ubuntu:~# curl http://127.0.0.1:5000/about:500 0/關(guān)于
Output{"message":"This is the About page"}
root@ubuntu:~# curl root@ubuntu:~# curl http://127.0.0.1:5000/multiply/10/20:5000/multiply/10/20
Output{"result":200}

步驟3 – 安裝 pytest 并編寫您的第一個測試

現(xiàn)在您已經(jīng)有了一個基本的 Flask 應用程序,讓我們安裝 pytest 并編寫一些單元測試。

使用 pip 安裝 pytest:

root@ubuntu:~# pip install pytest

創(chuàng)建一個測試目錄來存儲您的測試files:

root@ubuntu:~# mkdir tests

現(xiàn)在,讓我們創(chuàng)建一個名為 test_app.py 的新文件并添加以下代碼:

test_app.py
# Import sys module for modifying Python's runtime environmentimport sys# Import os module for interacting with the operating systemimport os# Add the parent directory to sys.pathsys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))# Import the Flask app instance from the main app filefrom app import app  # Import pytest for writing and running testsimport pytest@pytest.fixturedef client():     """A test client for the app."""     with app.test_client() as client:         yield clientdef test_home(client):     """Test the home route."""     response = client.get('/')     assert response.status_code == 200     assert response.json == {"message": "Hello, Flask!"}def test_about(client):     """Test the about route."""     response = client.get('/about')     assert response.status_code == 200     assert response.json == {"message": "This is the About page"}def test_multiply(client):     """Test the multiply route with valid input."""     response = client.get('/multiply/3/4')     assert response.status_code == 200     assert response.json == {"result": 12}def test_multiply_invalid_input(client):     """Test the multiply route with invalid input."""     response = client.get('/multiply/three/four')     assert response.status_code == 404def test_non_existent_route(client):     """Test for a non-existent route."""     response = client.get('/non-existent')     assert response.status_code == 404

我們來分解一下這個測試中的功能文件:

  1. @pytest.fixture def client(): 這是一個 pytest 夾具,為我們的 Flask 應用程序創(chuàng)建一個測試客戶端。它使用 app.test_client() 方法創(chuàng)建一個客戶端,該客戶端可以向我們的應用程序發(fā)送請求,而無需運行實際的服務器。 Yield 語句允許客戶端在測試中使用,然后在每次測試后正確關(guān)閉。

  2. def test_home(client): 此函數(shù)測試我們應用程序的主路由 (/)。它發(fā)送 使用測試客戶端向路由發(fā)出 GET 請求,然后斷言 響應狀態(tài)代碼為 200(正常)并且 JSON 響應與 預期消息。

  3. def test_about(client): 與test_home類似,該函數(shù)測試about路由(/about)。它檢查 200 狀態(tài)代碼并驗證 JSON 響應內(nèi)容。

  4. def test_multiply(client): 此函數(shù)使用有效輸入 (/multiply/3/4) 測試乘法路由。它檢查狀態(tài)代碼是否為 200 并且 JSON 響應是否包含正確的乘法結(jié)果。

  5. def test_multiply_invalid_input(client): 此函數(shù)測試具有無效輸入的乘法路徑(乘法/三/四)。 它檢查狀態(tài)代碼是否為 404(未找到),這是 當路由無法匹配字符串輸入時的預期行為 必需的整數(shù)參數(shù)。

  6. def test_non_existent_route(client): 該函數(shù)測試當訪問不存在的路由時應用程序的行為。它向 /non-existent 發(fā)送 GET 請求, 我們的 Flask 應用程序中沒有定義它。測試斷言 響應狀態(tài)代碼為 404(未找到),確保我們的應用程序正確 處理對未定義路由的請求。

這些測試涵蓋了 Flask 應用程序的基本功能,確保 每條路線都能正確響應有效輸入,并且乘法 路由適當?shù)靥幚頍o效輸入。通過使用 pytest,我們可以輕松運行這些測試來驗證我們的應用程序是否按預期工作。

第 4 步 – 運行測試

要運行測試,請執(zhí)行以下命令:

root@ubuntu:~# pytest

默認情況下,pytest發(fā)現(xiàn)過程將遞歸掃描當前文件夾及其子文件夾對于名稱以“test_”開頭或以“_test”結(jié)尾的文件。然后執(zhí)行位于這些文件中的測試。您應該看到類似以下內(nèi)容的輸出:

Outputplatform Linux -- Python 3.12.3, pytest-8.3.2, pluggy-1.5.0 rootdir: /home/user/flask_testing_app collected 5 items                                                                                                                  tests/test_app.py ....                                                                                                     [100%]======================================================= 5 passed in 0.19s ========================================================

這表明所有測試均已成功通過。

第 5 步:在 pytest 中使用 Fixtures

夾具是用于提供數(shù)據(jù)或資源的函數(shù) 測試。它們可用于設置和拆除測試環(huán)境、加載 數(shù)據(jù),或執(zhí)行其他設置任務。在 pytest 中,裝置是使用 @pytest.fixture 裝飾器定義的。

以下是如何增強現(xiàn)有裝置。更新客戶端固定裝置以使用安裝和拆卸邏輯:

test_app.py
@pytest.fixturedef client():     """Set up a test client for the app with setup and teardown logic."""     print("nSetting up the test client")     with app.test_client() as client:         yield client  # This is where the testing happens     print("Tearing down the test client")def test_home(client):     """Test the home route."""     response = client.get('/')     assert response.status_code == 200     assert response.json == {"message": "Hello, Flask!"}def test_about(client):     """Test the about route."""     response = client.get('/about')     assert response.status_code == 200     assert response.json == {"message": "This is the About page"}def test_multiply(client):     """Test the multiply route with valid input."""     response = client.get('/multiply/3/4')     assert response.status_code == 200     assert response.json == {"result": 12}def test_multiply_invalid_input(client):     """Test the multiply route with invalid input."""     response = client.get('/multiply/three/four')     assert response.status_code == 404def test_non_existent_route(client):     """Test for a non-existent route."""     response = client.get('/non-existent')     assert response.status_code == 404

這個 setup 添加了打印語句來演示安裝和拆卸 測試輸出中的階段。這些可以替換為實際資源 如果需要的話,管理代碼。

讓我們嘗試再次運行測試:

root@ubuntu:~# pytest -vs

-v 標志增加了詳細程度,而 -s 標志允許打印語句將顯示在控制臺輸出中。

您應該看到以下內(nèi)容輸出:

Outputplatform linux -- Python 3.12.3, pytest-8.3.2, pluggy-1.5.0 rootdir: /home/user/flask_testing_app  cachedir: .pytest_cache        collected 5 items                                                                                            tests/test_app.py::test_home  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_about  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_multiply  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_multiply_invalid_input  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_non_existent_route  Setting up the test client PASSED Tearing down the test client============================================ 5 passed in 0.35s =============================================

第 6 步:添加失敗測試用例

讓我們向現(xiàn)有測試文件添加一個失敗測試用例。修改 test_app.py 文件并在失敗的測試用例末尾添加以下函數(shù)以獲得不正確的結(jié)果:

test_app.py
def test_multiply_edge_cases(client):     """Test the multiply route with edge cases to demonstrate failing tests."""     # Test with zero     response = client.get('/multiply/0/5')     assert response.status_code == 200     assert response.json == {"result": 0}      # Test with large numbers (this might fail if not handled properly)     response = client.get('/multiply/1000000/1000000')     assert response.status_code == 200     assert response.json == {"result": 1000000000000}      # Intentional failing test: incorrect result     response = client.get('/multiply/2/3')     assert response.status_code == 200     assert response.json == {"result": 7}, "This test should fail to demonstrate a failing case"

讓我們休息一下分析 test_multiply_edge_cases 函數(shù)并解釋每個部分的含義執(zhí)行:

  1. 使用零進行測試:此測試檢查乘法函數(shù)是否正確處理 乘以零。我們期望相乘時結(jié)果為0 任意數(shù)為零。這是一個需要測試的重要邊緣情況,因為一些 實現(xiàn)可能存在零乘法問題。

  2. 大數(shù)測試:此測試驗證乘法函數(shù)是否可以處理大數(shù) 沒有溢出或精度問題。我們乘以二百萬 值,預計結(jié)果為一萬億。這項測試至關(guān)重要,因為 它檢查函數(shù)能力的上限。請注意,這 如果服務器的實現(xiàn)不能處理大量數(shù)據(jù),則可能會失敗 正確地,這可能表明需要大量的庫或 不同的數(shù)據(jù)類型

  3. 故意失敗測試:此測試被故意設置為失敗。它檢查 2 * 3 是否等于 7, 這是不正確的。該測試旨在演示失敗的測試如何 查看測試輸出。這有助于理解如何識別 并調(diào)試失敗的測試,這是測試驅(qū)動的一項基本技能 開發(fā)和調(diào)試過程。

通過包含這些邊緣情況和故意失敗,您可以 不僅測試多重路由的基本功能,還測試 極端條件下的行為及其錯誤報告 能力。這種測試方法有助于確保穩(wěn)健性和 我們應用程序的可靠性。

讓我們嘗試再次運行測試:

root@ubuntu:~# pytest -vs

您應該看到以下輸出:

Outputplatform linux -- Python 3.12.3, pytest-8.3.2, pluggy-1.5.0 rootdir: /home/user/flask_testing_app  cachedir: .pytest_cache          collected 6 items                                                                                                                             tests/test_app.py::test_home  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_about  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_multiply  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_multiply_invalid_input  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_non_existent_route  Setting up the test client PASSED Tearing down the test client  tests/test_app.py::test_multiply_edge_cases  Setting up the test client FAILED Tearing down the test client================================================================= FAILURES ==================================================================_________________________________________________________ test_multiply_edge_cases __________________________________________________________  client = <FlaskClient <Flask 'app'>>      def test_multiply_edge_cases(client):        """Test the multiply route with edge cases to demonstrate failing tests."""        # Test with zero         response = client.get('/multiply/0/5')         assert response.status_code == 200         assert response.json == {"result": 0}              # Test with large numbers (this might fail if not handled properly)         response = client.get('/multiply/1000000/1000000')         assert response.status_code == 200         assert response.json == {"result": 1000000000000}              # Intentional failing test: incorrect result         response = client.get('/multiply/2/3')         assert response.status_code == 200>       assert response.json == {"result": 7}, "This test should fail to demonstrate a failing case"E       AssertionError: This test should fail to demonstrate a failing caseE       assert {'result': 6} == {'result': 7}E          E         Differing items: E         {'result': 6} != {'result': 7}E          E         Full diff: E           {E         -     'result': 7,... E          E         ...Full output truncated (4 lines hidden), use '-vv' to show  tests/test_app.py:61: AssertionError========================================================== short test summary info ==========================================================FAILED tests/test_app.py::test_multiply_edge_cases - AssertionError: This test should fail to demonstrate a failing case======================================================== 1 failed, 5 passed in 0.32s ========================================================

上面的失敗消息表明測試 test_multiply_edge_cases 中測試/test_app.py 文件失敗。具體來說,此測試函數(shù)中的最后一個斷言導致了失敗。

這種故意失敗對于演示如何測試非常有用 報告故障以及故障中提供了哪些信息 信息。它顯示了發(fā)生故障的確切行, 預期值和實際值,以及兩者之間的差異。

在現(xiàn)實場景中,您將修復代碼以進行測試 如果預期結(jié)果不正確,則通過或調(diào)整測試。然而, 在這種情況下,失敗是出于教育目的而故意發(fā)生的。

相關(guān)閱讀

主站蜘蛛池模板: 精品一区二区三区免费视频 | 亚洲精品在线免费观看视频 | 亚洲国产成人精品女人久久久 | 中文字幕视频一区 | 日韩视频在线播放 | 精品久久久久久久久久久 | 国产精品一区久久久 | 国产精品一级 | 午夜视频一区二区三区 | 日韩欧美在线视频播放 | 国产精品久久久久一区二区三区 | 日韩成人影院在线观看 | 亚洲欧美中文字幕在线观看 | 精品久久影院 | 青青草综合网 | 亚洲精品欧美 | 精品国产免费一区二区三区五区 | 一区二区三区精品视频 | 亚洲激情av| 欧美一区视频 | 国产精品色婷婷久久58 | 九九热在线视频 | 免费在线观看av片 | 91精品国产一二三 | 久久国内精品 | 夜夜操av| 91资源在线 | aaaaa毛片 | 观看av | 久久综合久色欧美综合狠狠 | 欧美日韩在线一区二区三区 | 中文字幕一区二区三区四区五区 | 成人午夜在线 | 久久久久久久久久久久91 | 一区二区视频在线观看 | 日韩一区二区三区在线观看 | 亚洲欧美v | 国产精品免费小视频 | 在线成人免费视频 | 国产乱码精品1区2区3区 | 99视频免费在线 |