定制 ahmed-bhs/pyra 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ahmed-bhs/pyra

最新稳定版本:v0.1.0-beta.2

Composer 安装命令:

composer require --dev ahmed-bhs/pyra

包简介

Standalone CLI that validates the shape of your test pyramid (unit/integration/e2e ratios) for any PHP project.

README 文档

README

PHP PHPUnit Gherkin License

Pyra looks at your tests and answers two questions: is the overall pyramid the right shape, and for the code you just changed on a branch, was it tested at the level it should be.

It works on any PHP project (Symfony, Laravel or plain PHP) as long as the tests are written with PHPUnit (methods test* / #[Test]) or Gherkin scenarios. Pest is not supported yet, so a project whose tests are written only in Pest will report zero tests.

It does not boot your app. It reads files and a YAML config, so it runs the same everywhere.

Why

The test pyramid (Mike Cohn) says: lots of small, fast, isolated unit tests at the bottom; fewer slow, costly end-to-end tests at the top. The Practical Test Pyramid boils it down to two rules worth keeping:

  • Write tests with different granularity
  • The more high-level you get the fewer tests you should have

Most teams agree with this and then drift away from it one change at a time: a feature ships with an end-to-end test and no unit test, a "unit" test quietly spins up the database. Pyra is there to notice.

Install

composer require --dev ahmed-bhs/pyra

The two commands

pyra check looks at the whole suite: how many tests live at each level, whether the ratios and ordering still make a pyramid, and whether any "unit" test is really an integration test in disguise (it depends on something like an EntityManager).

pyra diff looks at what changed on your branch against a base ref. For every class you changed, it checks the test levels that area is expected to have. It searches the whole test suite, not just the files in the diff, so a test you wrote three months ago still counts and you do not get nagged about a class that is already covered.

vendor/bin/pyra check --strict
vendor/bin/pyra diff --base origin/main --strict
vendor/bin/pyra diff --base origin/main --coverage build/clover.xml
vendor/bin/pyra diff --base origin/main --format=github   # inline annotations

--base is any git ref: a branch (origin/main), a tag, or a commit. You do not need an open pull request; a local branch is enough.

With --strict, a violation exits 1 (for CI). Without it, violations are printed but the command still exits 0. diff can render as a table (default), json, or github annotations. See docs/github-actions.md for a ready-to-use workflow.

Config

Pyra reads a pyra.yaml at the project root. The shortest config that does something useful:

pyra:
    levels:
        unit:
            paths: [tests/Unit]
            forbidden_dependencies:
                - Doctrine\ORM\EntityManagerInterface
        integration:
            paths: [tests/Integration]
        e2e:
            paths: [features]
            counter: gherkin

Every key (levels, percentages, counters, the diff block, ready-to-copy Symfony and Laravel examples) is documented in docs/configuration.md.

What it actually catches

  • A class you changed that has no test at the level its area expects.
  • A unit test that pulls in an integration-only dependency.
  • A pyramid that has tipped over (more integration than unit), compared within one counting style.
  • If you pass --coverage, the changed lines that no test executes.

Where it stops

A few things worth knowing before you trust the output:

  • Without a coverage file it can only tell you a test looks missing, never that coverage is low. "Coverage" is only ever reported from a clover/cobertura XML you pass in with --coverage.
  • There is no notion of a "feature": the unit of work is the changed class, summed up over the branch.
  • The class-to-test matching is by name. A test that mentions a class without really exercising it is a false positive; a class hit only through a collaborator (or reflection, or the container) without being named is a false negative. Coverage is how you close that gap.
  • A .feature file names no PHP class, so e2e cannot be name-matched. Only the path rules or coverage reach it.
  • Telling coverage apart per level needs one coverage run per suite; a single merged file cannot say which level hit a line.
  • It counts PHPUnit (test* / #[Test]) and Gherkin scenarios. Pest is not counted yet.
  • It classifies tests by directory. You map folders to levels; a folder that mixes unit and integration tests in the same place cannot be split (a project like api-platform/core, which groups tests by component rather than by level, is only as precise as your paths). Per-test level markers are a possible future addition.

License

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-09

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固