Pytest 如何使用切換被測試環境

simonpatrick發表於2024-05-15

Pytest 如何使用切換被測試環境

  • Pytest 如何使用切換被測試環境
    • 0-問題: 如何讓同一份程式碼在不同環境執行
    • 1-dynaconf 管理所有環境資訊
    • 2. pytest- 透過命令列切換環境
    • 3. 命令列執行

被 pytest 的問題激發了一些,其實可能都是很多人知道的東西,不過看到論壇分享的理念東西比較多,具體東西少點,我就寫寫 pytest 相關的一些小東西吧.

下面介紹一個使用第三方庫結合 pytest 機制,給 pytest 新增一個命令列引數實現所有不同環境資訊在一個檔案並且可以切換被測試環境的例子,
程式碼量實際上非常少,但是起作用的.

0-問題: 如何讓同一份程式碼在不同環境執行

執行自動化測試的時候,最理想狀態就是同一份程式碼在不同的環境中執行,那麼如何讓 pytest 執行時候切換執行環境呢?
一般會想到的就是配置檔案,不同的配置檔案對應不同的環境,然後透過環境變數去切換使用不同的配置檔案.

這裡嘗試所有不同環境配置資訊都在一個檔案中,也可以在執行是切換環境的做法.

1-dynaconf 管理所有環境資訊

使用 dynaconf 管理環境資訊, 配置檔案在一份 toml 檔案中,示例如下:

[default]
db = { url = "postgresql://postgres:changeit@localhost:7432/test_hub" }
[dev]
db_url = "postgresql://postgres:changeit@localhost:7432/test_hub"
[test]
db_url = "postgresql://postgres:changeit@test:7432/test_hub"
[product]
db_url = "postgresql://postgres:changeit@prod:7432/test_hub"
[product_new]
db_url = "postgresql://postgres:changeit@prod_new:7432/test_hub"

上面檔案代表了四個環境的的 db_url 值,分別是dev/test/product/product_new

如何透過 dynaconf 獲取這些不同的環境資訊呢?

-
1. 首先獲取配置資訊, 所有在settings.toml檔案中的配置資訊都初始化載入

from dynaconf import Dynaconf

settings = Dynaconf(
    settings_file=["configs/settings.toml", "configs/.secrets.toml",
                   "settings.toml", ".secrets.toml"],
    environment=True,
    load_dotenv=True,
    dotenv_path="/.env",  # custom path for .env file to be loaded
    includes=["../config/custom_settings.toml"],
)

settings.validators.validate()

-
2. 獲取預設資訊:直接使用 settings.db_url 就可以獲取

@allure.feature("getting default db_url")
def test_get_default_settings():
    logging.info(settings.db_url)
    assert settings.db_url == "postgresql://postgres:changeit@default:7432/test_hub"

返回的是預設的 db_url: postgresql://postgres:changeit@default:7432/test_hub

-
3. 獲取其他環境的資訊:

切換獲取那個環境資訊

def ensure_env_settings(env_name: str):
    env_switcher_key = settings.ENV_SWITCHER_FOR_DYNACONF
    os.environ[env_switcher_key] = env_name
    settings.reload()

獲取新的環境變數:切換環境之後,再獲取 db_url,這個時候就變成了 test 環境的 db_url:postgresql://postgres:changeit@test:
7432/test_hub

@allure.feature("getting test env db_url")
def test_get_test_env_db_url():
    ensure_env_settings("test")
    print(settings.db_url)

2. pytest- 透過命令列切換環境

上面說明了環境配置切換的原理,那麼結合 pytest 就是接收一個名行行引數 env,然後根據這個命令列引數去獲取不同環境配置,
實現也算比較簡單,只要在 tests 目錄下的conftest.py檔案中實現:

  1. 定義新命令列引數
  2. 接收此命令列引數並進行切換環境引數
  3. 之後就可以直接使用此配套環境的引數了

定義新命令列引數:

## 定義新的命令列引數
def pytest_addoption(parser):
    parser.addoption("--env", action="store", default="dev",
                     help="Environment to run tests in")

接收命令列引數值到 request 並且實現切換環境引數:

@pytest.fixture(scope="session", autouse=True)
def setup_environment_setting(request):
    env_name = request.config.getoption("--env")
    ensure_env_settings(env_name)

3. 命令列執行

這個時候針對步驟 1 中的那個測試執行以下四個環境引數的命令,就會得到不同的測試結果了,
也就是這個環境變數生效了.

poetry run pytest tests/test_settings.py --evn default
poetry run pytest tests/test_settings.py --evn test
poetry run pytest tests/test_settings.py --evn product
poetry run pytest tests/test_settings.py --evn product_new

4. 小結和幾個衍生的問題

  • Dynaconf 第三方庫可以透過一個檔案就可以管理所以環境變數引數,同時支援直接透過屬性名訪問settings.db_url這種方式
  • pytest 建立一個新的引數的方法是什麼?
  • pytest fixture 的作用是什麼?
  • pytest fixture 裡面 request 指的是什麼?

相關文章