Pyodide使用的应用程序的pytest插件
项目描述
pytest-pyodide
Pyodide使用的应用程序的pytest插件
安装
pytest-pyodide需要Python 3.10+,可以使用以下命令进行安装
pip install pytest-pyodide
您还需要以下运行时之一
- Chrome和chromedriver
- Firefox和geckodriver
- Safari和safaridriver
- node v18+
Github可重用工作流程
pytest-pyodide还支持通过/.github/workflows/main.yml中的可重用工作流程在GitHub Actions上进行测试。这允许您在不安装所有测试工具的情况下在一系列浏览器/操作系统组合上进行测试,并轻松将其集成到您的CI过程中。
在您的GitHub Actions工作流程中,将其作为单独的工作调用。要传递构建的wheel,请在使用构建步骤时使用上传工件步骤。
这将运行给定浏览器/pyodide版本/操作系统配置的测试。它将在您的repo的根目录中运行pytest,这应该会捕获子文件夹中的任何test_*.py文件。
jobs:
# Build for pyodide 0.24.1
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.11
- uses: mymindstorm/setup-emsdk@v11
with:
version: 3.1.45
- run: pip install pyodide-build==0.24.1
- run: pyodide build
- uses: actions/upload-artifact@v3
with:
name: pyodide wheel
path: dist
# this is the job which you add to run pyodide-test
test:
needs: build
uses: pyodide/pytest-pyodide/.github/workflows/main.yaml@main
with:
build-artifact-name: pyodide wheel
build-artifact-path: dist
browser: firefox
runner: selenium
pyodide-version: 0.24.1
如果您想在多个浏览器/Pyodide版本等上运行,您可以使用矩阵策略运行上述main.yaml,或者使用testall.yaml。默认情况下,它将在所有浏览器(和node)上测试多个配置。如果您想减少配置,可以像下面那样使用浏览器、运行器、Pyodide版本列表进行过滤。
test:
needs: build
uses: pyodide/pytest-pyodide/.github/workflows/testall.yaml@main
with:
build-artifact-name: pyodide wheel
build-artifact-path: dist
pyodide-versions: "0.23.4, 0.24.1"
runners: "selenium, playwright"
browsers: "firefox, chrome, node"
os: "ubuntu-latest, macos-latest"
使用方法
-
首先,您需要一个兼容版本的Pyodide。您可以从releases下载Pyodide构建工件。
wget https://github.com/pyodide/pyodide/releases/download/0.24.1/pyodide-build-0.24.1.tar.bz2 tar xjf pyodide-build-0.24.1.tar.bz2 mv pyodide dist/
-
然后,您可以在测试中使用提供的固定值(
selenium
,selenium_standalone
),def test_a(selenium): selenium.run("assert 1+1 == 2") # run Python with Pyodide
您可以使用以下方法运行它们
pytest --dist-dir=./dist/
run_in_pyodide
一些测试只是简单地在一个代码块中运行Pyodide,并确保它不会出错。在这种情况下,可以使用pytest_pyodide
中的run_in_pyodide
装饰器,例如。
from pytest_pyodide import run_in_pyodide
@run_in_pyodide
def test_add(selenium):
assert 1 + 1 == 2
在这种情况下,函数的主体将自动在Pyodide中运行。装饰器也可以与packages
参数一起使用,以在运行测试之前加载包。例如
from pytest_pyodide import run_in_pyodide
@run_in_pyodide(packages = ["regex"])
def test_regex(selenium_standalone):
import regex
assert regex.search("o", "foo").end() == 2
您还可以使用@run_in_pyodide
与pytest.mark.parametrize
、hypothesis
等一起使用。@run_in_pyodide
必须是最内层的装饰器。任何在@run_in_pyodide
内部的装饰器都不会对测试行为产生影响。
from pytest_pyodide import run_in_pyodide
@pytest.mark.parametrize("x", [1, 2, 3])
@run_in_pyodide(packages = ["regex"])
def test_type_of_int(selenium, x):
assert type(x) is int
@run_in_pyodide
函数的第一个参数必须是浏览器运行器,通常是一个selenium
固定值。剩余的参数和@run_in_pyodide
函数的返回值必须是可序列化的。这些参数将在主机Python中序列化,并在Pyodide Python中反序列化。返回值将发生相反的操作。在函数体内,第一个selenium
参数将是None
(它由固定值内部使用)。请注意,这导致接收到的参数是副本。对参数所做的更改不会反映在主机Python中
@run_in_pyodide
def mutate_dict(selenium, x):
x["a"] = -1
return x
def test_mutate_dict():
d = {"a" : 9, "b" : 7}
assert mutate_dict(d) == { "a" : -1, "b" : 7 }
# d is unchanged because it was implicitly copied into the Pyodide runtime!
assert d == {"a" : 9, "b" : 7}
只要固定值的返回值是可序列化的(最常见的是如果它们是None
),您就可以使用固定值。作为一个特殊情况,函数将把selenium
固定值视为测试中的None
。
如果您需要返回Pyodide Python对象的持久引用,可以使用特殊的PyodideHandle
类
@run_in_pyodide
def get_pyodide_handle(selenium):
from pytest_pyodide.decorator import PyodideHandle
d = { "a" : 2 }
return PyodideHandle(d)
@run_in_pyodide
def set_value(selenium, h, key, value):
h[key] = value
@run_in_pyodide
def get_value(selenium, h, key):
return h[key]
def test_pyodide_handle(selenium):
h = get_pyodide_handle(selenium)
assert get_value(selenium, h, "a") == 2
set_value(selenium, h, "a", 3)
assert get_value(selenium, h, "a") == 3
这可以用来为与@run_in_pyodide
一起使用的固定值创建固定值。
您可以使用run_in_pyodide
作为内层函数
def test_inner_function(selenium):
@run_in_pyodide
def inner_function(selenium, x):
assert x == 6
return 7
assert inner_function(selenium_mock, 6) == 7
然而,函数将看不到任何闭包变量
def test_inner_function_closure(selenium):
x = 6
@run_in_pyodide
def inner_function(selenium):
assert x == 6
return 7
# Raises `NameError: 'x' is not defined`
assert inner_function(selenium_mock) == 7
因此,内层@run_in_pyodide
函数的唯一价值是限制函数定义的作用域。如果您需要一个闭包,您将不得不将其包装在第二个函数调用中。
将文件复制到Pyodide
您可以使用copy_files_to_pyodide
装饰器将文件复制到pyodide文件系统。这需要两个参数 - 一个(src,destination)
对的列表。这些可以是以下任何一种:1)一个文件名,2)一个文件夹名,它被复制到目标路径(如果recurse_directories
为True,则包括所有子目录),3)一个glob模式,它将获取与模式匹配的所有文件并将它们复制到目标目录,同时保留文件夹结构。
如果您将install_wheels
设置为True,任何.whl
文件都将安装在pyodide上。这对于安装您的包很有用。
from pytest_pyodide.decorator import copy_files_to_pyodide
@copy_files_to_pyodide(file_list=[(src,dest)],install_wheels=True,recurse_directories=True)
在Pyodide中运行非Pyodide测试
此插件还支持在浏览器中运行Pyodide的标准pytest测试。因此,如果您有一个现有的代码库并且您想检查您的Pyodide构建是否正常工作,只需像这样运行即可
# Make the emscripten/wasm32 wheel in the dist folder
pyodide build
# the following code
# a) copies the test_path directory and subfolders to a Pyodide instance, and
# b) installs any wheels in the dist subfolder so that this package is available on the Pyodide VM
pytest --run-in-pyodide test_path --runtime <runtime> --dist-dir=<pyodide/dist>
指定浏览器
您可以使用--runtime
(--rt
)命令行选项指定浏览器运行时。
--runtime
的可能选项是
- node(默认)
- firefox
- chrome
- safari
- host(不运行基于浏览器的测试)
pytest --runtime firefox
pytest --runtime firefox --runtime chrome
# Adding -no-host suffix will disable running host tests
pytest --runtime chrome-no-host
使用Playwright运行测试(可选)
默认情况下,测试将以Selenium运行。可以使用以下方式使用playwright运行测试。
首先安装playwright浏览器
python -m playwright install --with-deps
然后使用--runner
参数指定使用playwright运行测试。
pytest --runner playwright
自定义测试标记
pytest-pyodide
支持的自定义测试标记
pytest.mark.driver_timeout(timeout)
:设置WebDriver中的脚本超时。如果测试已知需要很长时间,可以使用此标记延长截止日期。
pytest.mark.xfail_browsers(chrome="why chrome fails")
:在特定浏览器中xfail测试。
示例
见examples
。
兼容的Pyodide版本
见兼容性表
。
许可证
pytest-pyodide使用Mozilla Public License Version 2.0。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分发
构建分发
pytest_pyodide-0.58.3.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0e3f6f9cffad4dee12c5a1a1df6179d24840d17601db2b29ee244cfd13e33401 |
|
MD5 | 146868d9ec0423511d5a55a90394bf75 |
|
BLAKE2b-256 | a25b305ae967e075455607dbcb286fd20b042a7a25f8c138386a8b9903f4c859 |
pytest_pyodide-0.58.3-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6425d8ac868090da70337bdef33bd8a082a353a4ecdb89f5371bcf58ac7390e7 |
|
MD5 | 14763bb217245a852818424d5196683d |
|
BLAKE2b-256 | cd987a2d160bd1a997c6fc422647ccf907fcc1b14b8e4a89790fa1427b8f4d16 |