Metadata-Version: 2.4
Name: tryke
Version: 0.0.29
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Rust
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
License-File: LICENSE
Summary: Tryke - A Python testing tool
Keywords: testing,test,framework,runner,assertions
Home-Page: https://github.com/thejchap/tryke
Author-email: Justin Chapman <commonmodestudio@gmail.com>
Requires-Python: >=3.12
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Bug Tracker, https://github.com/thejchap/tryke/issues
Project-URL: Documentation, https://tryke.dev/
Project-URL: Homepage, https://github.com/thejchap/tryke
Project-URL: Repository, https://github.com/thejchap/tryke

<p align="center">
  <a href="https://tryke.dev">
    <img height="170" alt="tryke-small" src="https://github.com/user-attachments/assets/39a2521a-fe9a-4235-8bb8-97b9e4f68aa7" />
  </a>
</p>
<h1 align="center">Tryke</h1>

<p align="center"><a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="ruff" /></a> <a href="https://pypi.org/project/tryke/"><img src="https://img.shields.io/pypi/v/tryke" alt="PyPI" /></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license" /></a> <a href="https://python.org"><img src="https://img.shields.io/badge/python-3.12%20%7C%203.13%20%7C%203.14%20%7C%203.15-blue.svg" alt="python" /></a> <a href="https://github.com/thejchap/tryke/actions/workflows/release.yml"><img src="https://github.com/thejchap/tryke/actions/workflows/release.yml/badge.svg" alt="CI" /></a> <a href="https://tryke.dev/"><img src="https://img.shields.io/badge/docs-tryke.dev-blue" alt="docs" /></a></p>

<video src="https://github.com/user-attachments/assets/354e21a4-b49f-4e93-a052-df98c0dfc3ae" controls muted></video>

## Highlights

- [Fast](https://tryke.dev/concepts/discovery.html) Rust-powered test discovery
- Concurrent tests by default
- Pretty, per-assertion diagnostics
- [Soft assertions](https://tryke.dev/concepts/soft-assertions.html) (like [pytest-check](https://github.com/okken/pytest-check))
- Native `async` support — no plugin
- [Watch mode](https://tryke.dev/guides/watch-mode.html)
- [Changed mode](https://tryke.dev/guides/changed-mode.html) (like [pytest-picked](https://github.com/anapaulagomes/pytest-picked))
- [Client/server](https://tryke.dev/concepts/client-server.html) mode for fast editor integrations
- [Fixtures](https://tryke.dev/guides/writing-tests.html#fixtures) with setup / teardown and typed `Depends()` injection
- [Parametrized tests](https://tryke.dev/concepts/cases.html) via `@test.cases`
- [Grouping](https://tryke.dev/guides/writing-tests.html#grouping-tests-with-describe) with `describe()` blocks
- `skip`, `skip_if`, `xfail`, and `todo` markers
- [In-source testing](https://tryke.dev/guides/writing-tests.html#in-source-testing)
- Support for [doctests](https://docs.python.org/3/library/doctest.html)
- Filtering and marks
- [Reporters](https://tryke.dev/guides/reporters.html) — text, dot, json, junit, llm, [nextest](https://nexte.st)-style, and [pytest-sugar](https://github.com/Teemu/pytest-sugar)-style

## Getting started

For more information, see the [documentation](https://tryke.dev/).

Write a test.

```python
from typing import Annotated

import tryke as t


@t.fixture(per="scope")
def database():
    db = {}
    yield db
    db.clear()


with t.describe("users"):

    @t.fixture
    def users(database: Annotated[dict[str, dict[str, str]], t.Depends(database)]):
        database["users"] = {}

        return database["users"]

    with t.describe("get"):

        @t.test("returns a stored user")
        async def test_get(users: Annotated[dict[str, str], t.Depends(users)]):
            users["alice"] = "alice@example.com"

            t.expect(users["alice"], name="returns stored email").to_equal(
                "alice@example.com"
            )

    with t.describe("set"):

        @t.test("stores a new user")
        async def test_set(users: Annotated[dict[str, str], t.Depends(users)]):
            users["bob"] = "bob@example.com"

            t.expect(users["bob"], name="stores email under user key").to_equal(
                "bob@example.com"
            )

```

Run the tests:

```bash
uvx tryke test # run once
uvx tryke # watch mode
```

## Coming from pytest?

The [migration guide](https://tryke.dev/migration.html) has a side-by-side cheat
sheet and a
[copy-paste LLM prompt](https://tryke.dev/migration.html#migration-prompt).

## License

This repository is licensed under the [MIT License](LICENSE).

