更好用的 Python 任務自動化工具:nox 官方教程

語言: CN / TW / HK

本教程將引導你學會安裝、配置和執行 Nox。

安裝
Nox 可以通過pip輕鬆安裝:

python3 -m pip install nox
你可能希望使用使用者站點(user site)來避免對全域性的 Python install 造成混亂:

python3 -m pip install --user nox
或者,你也可以更精緻,使用pipx:

pipx install nox
無論用哪種方式,Nox 通常是要全域性安裝的,類似於 tox、pip和其它類似的工具。

如果你有興趣在docker 內執行 nox,可以使用 DockerHub 上的thekevjames/nox映象,它包含所有 nox 版本的構建與及所有支援的 Python 版本。

如果你想在GitHub Actions中執行 nox ,則可以使用Activatedleigh/setup-nox action,它將安裝最新的 nox,並令 GitHub Actions 環境提供的所有 Python 版本可用。

編寫配置檔案
Nox 通過專案目錄中一個名為 noxfile.py 的檔案作配置 。這是一個 Python檔案,定義了一組會話(sessions)。一個會話是一個環境和一組在這個環境中執行的命令。如果你熟悉 tox,會話就類似於它的環境。如果你熟悉 GNU Make,會話則類似於它的 target。

會話使用 @nox.session 裝飾器作宣告。這方式類似於 Flask 使用 @app.route。

下面是一個基本的 Nox 檔案,對 example.py 執行flake8(你可以自己建立example.py):

import nox

@nox.session
def lint(session):
    session.install("flake8")
    session.run("flake8", "example.py")

第一次執行 Nox
現在,你已經安裝了 Nox 並擁有一個配置檔案, 那就可以執行 Nox 了!在終端中開啟專案的目錄,然後執行nox 。你應該會看到類似這樣的內容:

$ nox
nox > Running session lint
nox > Creating virtualenv using python3.7 in .nox/lint
nox > pip install flake8
nox > flake8 example.py
nox > Session lint was successful.

✨現在你已第一次成功地使用 Nox 啦!✨

本教程的其餘部分將帶你學習其它可以用 Nox 完成的常見操作。如果需要的話,你還可以跳至命令列用法和配置&API文件。

安裝依賴項
Nox 基本上是將 session.install 傳遞給 pip ,因此你可以用通常的方式來安裝東西。這裡有一些例子:

(1)一次安裝一個或多個包:

@nox.session
def tests(session):
    # same as pip install pytest protobuf>3.0.0
    session.install("pytest", "protobuf>3.0.0")
    ...

(2)根據 requirements.txt 檔案安裝:

@nox.session
def tests(session):
    # same as pip install -r -requirements.txt
    session.install("-r", "requirements.txt")
    ...

(3)如果你的專案是一個 Python 包,而你想安裝它:

@nox.session
def tests(session):
    # same as pip install .
    session.install(".")
    ...

執行命令
session.run 函式可讓你在會話的虛擬環境的上下文中執行命令。以下是一些示例:

(1)你可以安裝和執行 Python 工具:

@nox.session
def tests(session):
    session.install("pytest")
    session.run("pytest")

(2)如果你想給一個程式傳遞更多的引數,只需給 run 新增更多引數即可:

@nox.session
def tests(session):
    session.install("pytest")
    session.run("pytest", "-v", "tests")

(3)你還可以傳遞環境變數:

@nox.session
def tests(session):
    session.install("black")
    session.run(
        "pytest",
        env={
            "FLASK_DEBUG": "1"
        }
    )

有關執行程式的更多選項和示例,請參見nox.sessions.Session.run()。

選擇要執行的會話
一旦你的 Noxfile 中有多個會話,你會注意到 Nox 將預設執行所有的會話。儘管這很有用,但是通常一次只需要執行一兩個。

你可以使用--sessions引數(或-s)來選擇要執行的會話。你可以使用--list引數顯示哪些會話可用,哪些將會執行。這裡有一些例子:

這是一個具有三個會話的 Noxfile:

import nox

@nox.session
def test(session):
    ...

@nox.session
def lint(session):
    ...

@nox.session
def docs(session):
    ...

如果你只執行nox --list ,則會看到所有會話都被選中:

Sessions defined in noxfile.py:

* test
* lint
* docs

sessions marked with * are selected,
sessions marked with - are skipped.

如果你執行nox --list --sessions lint,Nox 將只執行 lint 會話:

nox > Running session lint
nox > Creating virtualenv using python3 in .nox/lint
nox > ...
nox > Session lint was successful.

還有更多選擇和執行會話的方法!你可以在命令列用法中閱讀更多有關呼叫 Nox 的資訊。

針對不同的多個 Python 進行測試
許多專案需要支援一個特定的 Python 版本或者多個 Python 版本。你可以通過給 @nox.session 指定 Python,來使 Nox 針對多個直譯器執行會話。這裡有一些例子:

(1)如果你希望會話僅針對 Python 的單個版本執行:

@nox.session(python="3.7")
def test(session):
    ...

(2)如果你希望會話在 Python 的多個版本上執行:

@nox.session(python=["2.7", "3.5", "3.7"])
def test(session):
    ...

你會注意到,執行nox --list將顯示此會話已擴充套件為三個不同的會話:

Sessions defined in noxfile.py:

* test-2.7
* test-3.5
* test-3.7

你可以使用nox --sessions test執行所有 test 會話,也可以使用列表中顯示的全名來執行單個 test 會話,例如,nox --sessions test-3.5。有關選擇會話的更多詳細資訊,請參見命令列用法文件。

你可以在會話的virtualenv配置裡,閱讀到更多關於配置會話所用的虛擬環境的資訊。

與 conda 一起測試
一些專案,特別是在資料科學社群,需要在 conda 環境中測試其使用的情況。如果你希望會話在 conda 環境中執行:

@nox.session(venv_backend="conda")
def test(session):
    ...

使用 conda 安裝軟體包:

session.conda_install("pytest")

可以用 pip 安裝軟體包進 conda 環境中,但是最好的實踐是僅使用--no-deps 選項安裝。這樣可以避免 pip 安裝的包與 conda 安裝的包不相容,防止 pip 破壞 conda 環境。

session.install("contexter", "--no-deps")
session.install("-e", ".", "--no-deps")

引數化
就像 Nox 可以控制執行多個直譯器一樣,它也可以使用nox.parametrize()裝飾器,來處理帶有一系列不同引數的會話。

這是一個簡短示例,使用引數化對兩個不同版本的 Django 進行測試:

@nox.session
@nox.parametrize("django", ["1.9", "2.0"])
def test(session, django):
    session.install(f"django=={django}")
    session.run("pytest")

如果執行nox --list ,你將會看到 Nox 把一個會話擴充套件為了多個會話。每個會話將獲得你想傳遞給它的一個引數值:

Sessions defined in noxfile.py:

* test(django='1.9')
* test(django='2.0')

nox.parametrize() 的介面和用法特意類似於pytest的parametrize。這是 Nox 的一項極其強大的功能。你可以在引數化會話上,閱讀更多有關引數化的資訊與示例。

以上就是本次分享的所有內容,想要了解更多 python 知識歡迎前往公眾號:Python 程式設計學習圈 ,傳送 “J” 即可免費獲取,每日干貨分享