Spec-Zone.ru › Polars

Тестирование

Модуль testing предоставляет ряд функций и вспомогательных средств для модульных тестов.

Примечание

Модуль testing не импортируется по умолчанию, чтобы оптимизировать скорость импорта основного модуля polars. Импортируйте polars.testing и затем используйте это пространство имён или импортируйте нужные функции из полного пути модуля, например:

from polars.testing import assert_frame_equal, assert_series_equal

Проверки

Polars предоставляет стандартные проверки для использования в модульных тестах:

testing.assert_frame_equal(left, right, *[, ...])

Проверяет, что левый и правый фреймы равны.

testing.assert_frame_not_equal(left, right, *)

Проверяет, что левый и правый фреймы не равны.

testing.assert_schema_equal(left_schema, ...)

Проверяет, что схемы левого и правого фреймов равны.

testing.assert_series_equal(left, right, *)

Проверяет, что левая и правая Series равны.

testing.assert_series_not_equal(left, right, *)

Проверяет, что левая и правая Series не равны.

Параметрическое тестирование

Дополнительные сведения о тестировании на основе свойств, стратегиях и интеграциях с библиотеками см. в документации библиотеки Hypothesis:

  • Обзор
  • Краткое руководство

Стратегии Polars

Polars предоставляет следующие стратегии тестирования hypothesis:

testing.parametric.dataframes([cols, lazy, ...])

Стратегия Hypothesis для создания DataFrames или LazyFrames Polars.

testing.parametric.dtypes(*[, ...])

Создаёт стратегию для генерации объектов DataType Polars.

testing.parametric.lists(inner_dtype, *[, ...])

Создаёт стратегию для генерации списков заданного типа данных.

testing.parametric.series(*[, name, dtype, ...])

Стратегия Hypothesis для создания Series Polars.

Вспомогательные средства для стратегий

testing.parametric.column([name, dtype, ...])

Определяет столбец для использования со стратегией dataframes.

testing.parametric.columns([cols, dtype, ...])

Определяет несколько столбцов для использования со стратегией @dataframes.

testing.parametric.create_list_strategy([...])

Создаёт стратегию для генерации данных Polars типа List.

Профили

Предоставляется несколько стандартных/именованных профилей hypothesis:

  • fast: выполняет 100 итераций.
  • balanced: выполняет 1 000 итераций.
  • expensive: выполняет 10 000 итераций.

Вспомогательные функции загрузки и установки позволяют напрямую обращаться к этим профилям, задавать предпочтительный профиль (по умолчанию — fast) или указывать пользовательское количество итераций.

testing.parametric.load_profile([profile, ...])

Загружает именованный (или пользовательский) профиль hypothesis для параметрических тестов.

testing.parametric.set_profile(profile)

Устанавливает для переменной окружения POLARS_HYPOTHESIS_PROFILE указанное имя/значение профиля.

Примерное время выполнения для профилей:

Запуск собственных параметрических модульных тестов polars для 0.17.6 в релизной и отладочной сборках на машине с 12 ядрами с использованием xdist -n auto даёт следующие результаты (эти значения приведены для справки и могут значительно различаться в зависимости от конфигурации вашего оборудования):

Профиль

Итерации

Релизная сборка

Отладочная сборка

fast

100

~6 сек.

~8 сек.

balanced

1 000

~22 сек.

~30 сек.

expensive

10 000

~3 мин. 5 сек.

~4 мин. 45 сек.

Примеры

Базовый уровень: Создайте параметрический модульный тест, который будет получать последовательность сгенерированных DataFrames, каждый из которых содержит 5 числовых столбцов с вероятностью 10% для любого сгенерированного значения быть null (это отличается от NaN).

import polars as pl
from polars.testing.parametric import dataframes
from polars import NUMERIC_DTYPES

from hypothesis import given

@given(
    dataframes(
        cols=5,
        allow_null=True,
        allowed_dtypes=NUMERIC_DTYPES,
    )
)
def test_numeric(df: pl.DataFrame):
    assert all(df[col].dtype.is_numeric() for col in df.columns)

    # Example frame:
    # ┌──────┬────────┬───────┬────────────┬────────────┐
    # │ col0 ┆ col1   ┆ col2  ┆ col3       ┆ col4       │
    # │ ---  ┆ ---    ┆ ---   ┆ ---        ┆ ---        │
    # │ u8   ┆ i16    ┆ u16   ┆ i32        ┆ f64        │
    # ╞══════╪════════╪═══════╪════════════╪════════════╡
    # │ 54   ┆ -29096 ┆ 485   ┆ 2147483647 ┆ -2.8257e14 │
    # │ null ┆ 7508   ┆ 37338 ┆ 7264       ┆ 1.5        │
    # │ 0    ┆ 321    ┆ null  ┆ 16996      ┆ NaN        │
    # │ 121  ┆ -361   ┆ 63204 ┆ 1          ┆ 1.1443e235 │
    # └──────┴────────┴───────┴────────────┴────────────┘

Средний уровень: Встройте стратегии, встроенные в hypothesis, в столбцы с конкретными именами и сгенерируйте последовательность LazyFrames с минимум пятью строками и значениями, соответствующими заданным стратегиям:

import polars as pl
from polars.testing.parametric import column, dataframes

import hypothesis.strategies as st
from hypothesis import given
from string import ascii_letters, digits

id_chars = ascii_letters + digits

@given(
    dataframes(
        cols=[
            column("id", strategy=st.text(min_size=4, max_size=4, alphabet=id_chars)),
            column("ccy", strategy=st.sampled_from(["GBP", "EUR", "JPY", "USD"])),
            column("price", strategy=st.floats(min_value=0.0, max_value=1000.0)),
        ],
        min_size=5,
        lazy=True,
    )
)
def test_price_calculations(lf: pl.LazyFrame):
    ...
    print(lf.collect())

    # Example frame:
    # ┌──────┬─────┬─────────┐
    # │ id   ┆ ccy ┆ price   │
    # │ ---  ┆ --- ┆ ---     │
    # │ str  ┆ str ┆ f64     │
    # ╞══════╪═════╪═════════╡
    # │ A101 ┆ GBP ┆ 1.1     │
    # │ 8nIn ┆ JPY ┆ 1.5     │
    # │ QHoO ┆ EUR ┆ 714.544 │
    # │ i0e0 ┆ GBP ┆ 0.0     │
    # │ 0000 ┆ USD ┆ 999.0   │
    # └──────┴─────┴─────────┘

Продвинутый уровень: Создайте и используйте стратегию типа данных List[UInt8] в качестве составной стратегии hypothesis, которая генерирует пары пар небольших целых чисел, где первое значение в каждой вложенной паре всегда меньше или равно второму:

import polars as pl
from polars.testing.parametric import column, dataframes, lists

import hypothesis.strategies as st
from hypothesis import given

@st.composite
def uint8_pairs(draw: st.DrawFn):
    uints = lists(pl.UInt8, size=2)
    pairs = list(zip(draw(uints), draw(uints)))
    return [sorted(ints) for ints in pairs]

@given(
    dataframes(
        cols=[
            column("colx", strategy=uint8_pairs()),
            column("coly", strategy=uint8_pairs()),
            column("colz", strategy=uint8_pairs()),
        ],
        min_size=3,
        max_size=3,
    )
)
def test_miscellaneous(df: pl.DataFrame): ...

    # Example frame:
    # ┌─────────────────────────┬─────────────────────────┬──────────────────────────┐
    # │ colx                    ┆ coly                    ┆ colz                     │
    # │ ---                     ┆ ---                     ┆ ---                      │
    # │ list[list[i64]]         ┆ list[list[i64]]         ┆ list[list[i64]]          │
    # ╞═════════════════════════╪═════════════════════════╪══════════════════════════╡
    # │ [[143, 235], [75, 101]] ┆ [[143, 235], [75, 101]] ┆ [[31, 41], [57, 250]]    │
    # │ [[87, 186], [174, 179]] ┆ [[87, 186], [174, 179]] ┆ [[112, 213], [149, 221]] │
    # │ [[23, 85], [7, 86]]     ┆ [[23, 85], [7, 86]]     ┆ [[22, 255], [27, 28]]    │
    # └─────────────────────────┴─────────────────────────┴──────────────────────────┘

© 2020 Ritchie Vink
© 2022 Polars contributors
Licensed under the MIT License.
https://docs.pola.rs/api/python/stable/reference/testing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API