PHPackages                             neochrome/physalis - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. neochrome/physalis

ActiveLibrary[Testing &amp; Quality](/categories/testing)

neochrome/physalis
==================

An effort to make testing PHP code easy and fun

248PHP

Since Oct 9Pushed 10y ago4 watchersCompare

[ Source](https://github.com/neochrome/physalis)[ Packagist](https://packagist.org/packages/neochrome/physalis)[ RSS](/packages/neochrome-physalis/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

[![Build Status](https://camo.githubusercontent.com/f75d1fbc4798e4dd83dfa2fe85f33c00e56530bbe5933b333973694e736318fd/68747470733a2f2f7472617669732d63692e6f72672f6e656f6368726f6d652f70687973616c69732e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/neochrome/physalis)
[![endorse](https://camo.githubusercontent.com/02a90906b456f2610317145215445c92db7213e472b4c1730b76617191761dc9/68747470733a2f2f6170692e636f64657277616c6c2e636f6d2f6e656f6368726f6d652f656e646f727365636f756e742e706e67)](https://coderwall.com/neochrome)

Physalis
========

[](#physalis)

An effort to make testing PHP code as easy and fun as its JavaScript equivalent when using the excellent [Jasmine](https://github.com/pivotal/jasmine), from which syntax and general usage is shamelessly borrowed.

System Requirements
-------------------

[](#system-requirements)

Physalis requires PHP 5.4.x or later to run due to the heavy use of function closures.

Installation
------------

[](#installation)

### Using Composer

[](#using-composer)

Using [composer](http://getcomposer.org) is probably the easiest way. Just execute the following in your project folder:

```
$ composer require neochrome/physalis

```

or

```
$ php composer.phar require neochrome/physalis

```

if you don't have composer installed globally. This will pull the latest version from [packagist](https://packagist.org) and put it into your vendor folder. It will also create a symlink to the executable script as `vendor/bin/physalis`.

### From source

[](#from-source)

Clone the repo or download the latest source and put in into your vendor folder. The executable script is in `bin/`.

Basic usage
-----------

[](#basic-usage)

Start off by describing something with a set of specifications, i.e how it should behave:

```

```

By default Physalis will pick up specifications from files named `*.spec.php`in subfolder `spec`. This may be overridden from the command line using the `--specs` switch. To verify the specifications, execute:

```
$ vendor/bin/physalis --specs=path/to/my/specs/*.spec.php

```

Contexts
--------

[](#contexts)

Contexts contain specs and possible nested contexts. They are defined using the `describe` function with a description and a nested function scope/closure.

```
describe('a context', function () {
	// specs goes here
});
```

Specs
-----

[](#specs)

Specs are defined in a context using the `it` function with a description and a nested function/closure which sets up expectations.

```
it('has a certain behaviour', function () {
	// code setup and expectations goes here
});
```

Expectations
------------

[](#expectations)

Expectations are boolean assertions that are built using the `expect` function with an actual value and then chained with a matcher function that will perform the assertion. Expectations may be negated by chaining with the `not` property, in which case the outcome of the following matcher function will be inverted.

```
it('is negated', function () {
	expect(false)->not->toBe(true);
});
```

### Matchers

[](#matchers)

Matchers performs boolean comparisons of actual and expected values. Included matchers are:

#### toBe

[](#tobe)

Performs a strict comparison of actual and expected.

```
expect(42)->toBe(42);   // true
expect('42')->toBe(42); // false
```

#### toEqual

[](#toequal)

Performs a "loose" comparison of actual and expected.

```
expect(42)->toEqual(42);   // true
expect('42')->toEqual(42); // true
```

#### toMatch

[](#tomatch)

Assumes expected to be a perl regular expression and tests if actual is a match.

```
expect('aBBa')->toMatch('/B+/'); // true
```

#### toContain

[](#tocontain)

Assumes actual to be either a string or an array. Checks if it contains expected as a substring or an element respectively.

```
expect('hello world')->toContain('hello'); // true
expect([1, 2, 3])->toContain(2);           // true
```

#### toBeEmpty()

[](#tobeempty)

Assumes actual to be either a string or an array. Checks if it's empty.

```
expect('')->toBeEmpty(); // true
expect([])->toBeEmpty(); // true
```

#### toBeOfType

[](#tobeoftype)

Checks if the type of actual is of the expected type (standard type or class).

```
expect(13)->toBeOfType('integer');                // true
expect(new Exception())->toBeOfType('Exception'); // true
```

#### toThrow

[](#tothrow)

Assumes actual to be callable, i.e function closure. Verifies that an exception is thrown when calling actual. If expected is given, checks that the thrown exception matches the expected.

```
expect(function () { throw new Exception(); })->toThrow('Exception'); // true
```

### Custom matchers

[](#custom-matchers)

Custom matchers may be created and registered in `beforEach` blocks by calling the `$this->addMatchers` function with an associative array where the keys are the matcher name and the values are the matcher function implementation.

Matcher functions should return true if a match, otherwise false. Actual and expected values are available through the properties `$this->actual` and `$this->expected`. By default a failing expectation will construct a message from the current actual and expected values together with the matcher name.

Custom messages may be specified by setting the property `$this->message` to an array with two functions returning strings. The first is the regular message and the second is the inverted message (when the expectation is negated).

An example:

```
beforeEach(function () {
	$this->addMatchers([
		'toBeGreaterThan' => function () {
			$actual = static::pp($this->actual);
			$expected = static::pp($this->expected);
			$this->message = [
				function () { return "Expected {$actual} to be greater than {$expected}"; },
				function () { return "Expected {$actual} not to be greater than {$expected}"; }
			];
			return $this->actual > $this->expected;
		}
	]);
});
```

beforeEach / afterEach
----------------------

[](#beforeeach--aftereach)

Each context may specify any number of `beforeEach` and `afterEach` function blocks. All before blocks are executed in order (outside and in) before each spec and may be used to perform common setup and or register new matchers. After blocks are executed in opposite order (inside and out) after each spec and may be used to perform common teardown etc.

Excluding contexts and specs
----------------------------

[](#excluding-contexts-and-specs)

By using the `xdescribe` and `xit` functions, contexts and specs may be excluded (ignored) and won't affect the result.

Reporting results
-----------------

[](#reporting-results)

By default Physalis will make use of the `ProgressReporter` which will output progress in a condensed form. Besides the `ProgressReporter` Physalis comes with a `DocumentReporter` which will output the full structure of all contexts and specs, as well as any failing expectations. To specify which reporter to use, supply the `--reporter` command line switch:

```
$ vendor/bin/physalis --reporter=DocumentReporter

```

Integration with other tools
----------------------------

[](#integration-with-other-tools)

Physalis will return an exit code of zero when all specs has passed, otherwise non-zero. This may be used as a step in a CI build to execute the specs continuously on each commit.

Final notes
-----------

[](#final-notes)

If you find the tool useful, please feel free to star the repo, fork it and create pull requests or register issues with new ideas or things to fix. Most important however - have fun testing your PHP code!

###  Health Score

23

—

LowBetter than 26% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1c64e06b8cf47943d7e09d2404bcedbcf3690d31d71c001ba3da89546f8280d3?d=identicon)[neochrome](/maintainers/neochrome)

---

Top Contributors

[![neochrome](https://avatars.githubusercontent.com/u/335698?v=4)](https://github.com/neochrome "neochrome (8 commits)")[![orthographic-pedant](https://avatars.githubusercontent.com/u/14522744?v=4)](https://github.com/orthographic-pedant "orthographic-pedant (1 commits)")

### Embed Badge

![Health badge](/badges/neochrome-physalis/health.svg)

```
[![Health](https://phpackages.com/badges/neochrome-physalis/health.svg)](https://phpackages.com/packages/neochrome-physalis)
```

###  Alternatives

[dms/phpunit-arraysubset-asserts

This package provides ArraySubset and related asserts once deprecated in PHPUnit 8

14228.7M340](/packages/dms-phpunit-arraysubset-asserts)[orchestra/workbench

Workbench Companion for Laravel Packages Development

8219.1M69](/packages/orchestra-workbench)[phpbenchmark/phpbenchmark

Easy to use benchmark toolkit for your PHP-application. This library contains classes for comparing algorithms as well as benchmarking application responses

8011.5k2](/packages/phpbenchmark-phpbenchmark)[kunicmarko/graphql-test

GraphQL Test Cases

1359.0k](/packages/kunicmarko-graphql-test)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
