## pytest-bdd 的文件的命名規范
pytest-bdd 是基于pytest 之上,所以需要遵循pytest 的命名規則才能進行測試,具體有:
1. 測試文件名必須以*_test.py或者test_*.py命名
2. 測試函數必須以 test_開頭
在pytest-bdd中存在兩類文件:
1. 以 .feature 結尾的用戶場景文件
2. 以 .py 結尾的測試代碼。這里又細分為兩類:
- 以 `@given`,`@when`,`@then` 注解的步驟函數,這些函數名沒有強制限制, 也可以借鑒beheave的寫法以 `step_`開頭。
- 以 `@scenario` 注解的測試場景函數,這個函數名需要以 `test_` 開頭, 因為這樣才會被pytest 識別。
舉例來看: `@given`,`@when`,`@then` 的步驟函數的示例:
```python
@pytest.fixture
@given("I have a calculator")
def calculator():
return Calculator()
@when(parsers.parse('I enter "{a}" and "{b}"'))
def enter_numbers(calculator, a, b):
calculator.a = int(a)
calculator.b = int(b)
@then(parsers.parse('the result should be "{result}"'))
def verify_result(calculator, result):
assert calculator.add(calculator.a, calculator.b) == int(result)
```
`@scenario` 注解的測試場景函數的示例:
```
@scenario('../features/calculator.feature','Add two numbers')
def test_add():
pass
```
* `@scenario` 本身沒有實際的內容,只是一個占位符,關聯場景和步驟,但是又不可少
### 關于 `@scenario`
`@scenario`是 pytest-bdd 框架中的一個裝飾器,用于標記一個 BDD 場景并將其與編寫的測試函數關聯起來。
`@scenario`裝飾器可以用來定義一個場景,并確定它所屬的 feature 和 scenario。其語法如下:
~~~python
@scenario('<feature_file_path>', '<scenario_name>')
def test_my_scenario():
pass
~~~
其中,`<feature_file_path>`是 feature 文件的路徑,`<scenario_name>`是場景的名稱。在測試方法中不需要任何具體的測試步驟。相反,pytest-bdd 將自動加載與場景匹配的步驟,并在執行測試時逐步執行它們。這意味著測試方法本身只是一個占位符,其定義的唯一目的是將場景與步驟關聯起來。
使用`@scenario`裝飾器需要遵循一定的規則,如下:
1. 一個`@scenario`裝飾器用于定義一個場景。
2. 必須指定該場景所屬的 feature 文件的路徑和場景名稱。
3. 測試函數的名稱必須與場景名稱匹配。
4. 測試函數的參數必須與場景步驟的參數名稱相匹配。
5. 測試函數必須使用 BDD 關鍵字來編寫場景步驟。
6. pytest-bdd 將自動加載與場景匹配的步驟,并在執行測試時逐步執行它們。
7. 可以將多個場景分組在同一個 feature 文件中,并在同一個測試類中執行它們。
## 使用pytest-bdd的項目的目錄結構
基于以上,目錄的設計如下:
1..feature 場景文件放置在項目根目錄的 features目錄中。[非強制]
2. 步驟函數和場景函數可以放在一個.py文件中, 也可以放在兩個 .py文件中。
3. 包含場景函數的.py 需要以test_ 開頭 [強制]
4. 測試步驟的文件放置在項目根目錄的steps 或step_defs 目錄中[非強制]
5. 場景函數如果分拆出來,放置在根目錄的 test_cases目錄中[非強制]
6. 在基于面向對象的設計中,可以一個類一個場景文件, 也可以一個功能一個場景文件。[非強制]
基于以上原則,提供的幾個目錄結構示例如下:
### 目錄結構1:
步驟函數和場景函數放在一起,一個功能一個場景文件:
```
├────features/ # 用戶場景
│ ├────user/
│ │ ├────create_user.feature
│ ├────login.feature
├────step_defs/ # 步驟函數和測試場景
│ ├────user/
│ │ ├────test_create_user.py
│ └────test_login.py
```
### 目錄結構2:
步驟函數和場景函數放在一起,一個類一個場景文件:
```
├────features/ # 用戶場景
│ ├────user.feature
│ ├────login.feature
├────step_defs/ # 步驟函數和測試場景
│ ├────user.feature
│ └────test_login.py
```
### 目錄結構3:
```
├────features/ # 用戶場景
│ ├────user/
│ │ ├────create_user.feature
│ ├────login.feature
├────step_defs/ # 步驟函數
│ ├────user/
│ │ ├────create_user_steps.py
│ └────login_steps.py
├────test_case/ # 測試場景
│ ├────test_user/
│ │ ├────test_create_user.py
│ └────test_login.py
```
其他還可以用 cases和 test_cases 來命名,類似如下:
```
├────cases/ # 用戶場景
│ ├────projects/
│ │ ├────create_project.features
│ ├────login.features
├────test_cases/ # 步驟函數和測試場景
│ ├────projects/
│ │ ├────test_create_project.py
│ └────test_login.py
```
```
├────test_cases/ # 測試用例
│ ├────features/ # 用戶場景
│ │ ├────login.features
│ ├────step_defs/ # 步驟函數和測試場景
│ │ ├────test_login.py
```
## 以測試角度出發的目錄
上面的目錄規范是將BDD的規范文件和測試作為獨立的部分, 也有的項目從測試角度出發,將BDD的文件作為測試的一部分, 統一放入項目的tests 目錄中,
```
|-- tests
| |-- features
| | |-- step_definitions
| | | |-- __init__.py
| | | |-- test_steps.py
| | |-- support
| | | |-- conftest.py
| | | |-- env.py
| | | |-- hooks.py
| | |-- feature1.feature
| | |-- feature2.feature
| |-- unit
| | |-- __init__.py
| | |-- test_module1.py
| | |-- test_module2.py
| |-- __init__.py
| |-- conftest.py
|-- setup.py
|-- requirements.txt
|-- README.md
```
* `tests`目錄包含所有測試相關文件,其中`features`目錄用于存放 BDD 測試用例和相關文件,`unit`目錄用于存放其他類型的測試用例。
* `step_definitions`目錄用于存放實現 BDD 測試用例步驟的 Python 腳本。每個 BDD 測試用例的步驟都應該在這里實現
* `support`目錄用于存放 BDD 測試用例所需的支持文件,比如環境設置、鉤子函數等。
* `conftest.py`文件放在`tests`目錄下,用于實現項目級別的配置和夾具設置。
* `setup.py`文件是一個 Python 包的安裝腳本。
* `requirements.txt`文件用于存儲項目依賴庫的清單。
* `README.md`文件是項目的說明文檔。
如果從BDD的定義和作用來看的話,這種目錄結構就有點混淆了 BDD和測試的概念,因為BDD是有終端用戶參與進來的部分, 目錄層級較深不利于使用,個人是比較不建議這種方式。
*****
*****
- 前言
- 1.入門篇
- Python介紹
- 安裝與使用
- Python開發利器之VS Code
- 模塊安裝
- 命令行
- 一次Python無法安裝模塊的問題探索與解決之旅
- 命令運行
- Conda
- 下載地址
- 2.基礎篇
- 基礎語法
- 輸入與輸出
- with as的用法
- 注釋
- Python命令行參數
- 編碼
- 變量類型
- 列表遍歷
- 運算符
- 表達式語句
- 條件
- 循環
- 日期和時間
- 函數
- 高級語法
- @符號-裝飾器
- 模塊和包
- name
- init.py
- 錯誤和異常
- 面向對象
- 3.專題篇
- 常用功能
- Python 字符串連接
- python web
- Python CGI編程
- Python OAuth2
- 認證 Flask-HTTPAuth
- 常用命令
- 內置函數
- dir()
- print(f)
- 標準模塊
- sys
- pickle-數據序列化
- os
- IO(輸入輸出)
- 鍵盤輸入
- 文件讀寫
- 測試
- Python測試框架之pytest快速入門
- pytest-bdd快速示例和問題解決
- 基于pytest-bdd的項目目錄結構和命名規范
- python BDD 的相關概念
- Behave介紹和快速示例
- Python BDD之Behave測試報告
- Python BDD 框架比較之 pytest-bdd vs behave
- pytest進階
- Flask + pytest測試
- 參考網址
- pytest-bdd進階
- hehave進階
- 測試路徑
- python + selunium
- HTML 根據多層CSS 查找元素
- 等待執行
- 使用text 查找 span
- pytest如何在控制臺輸出
- 4.問題篇
- pip pip3 及區別
- TypeError: can only concatenate str (not "NoneType") to str
- 5.實戰篇
- matplotlib-繪圖包
- 導入類
- 命名規范
- 模塊查找
- 6.進階篇
- Flask
- Flask介紹
- Flask擴展模塊
- Flask-Login
- 問題
- Jinja2
- Flask-RESTful
- Flask-JWT-Extended
- WSGI
- Flask-SQLAlchemy
- 部署
- Flask VS Django
- Flask Web
- Flask + Vue
- Flask實戰
- Flask 標準目錄結構
- Blueprints
- 參考
- FastAPI 測試
- https 證書 Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate