An inline method and doc comment test runner

Test Flight allows you to define unit tests inside your classes. There are two different types of tests available:

Inline methods , simple PHP methods annotated with @test Doc Comment , code examples in the method documentation wrapped into <code>...</code> Documentation , code snippets in Markdown documentation files wrapped in ```php ... ```

This project is inspired by

Rust's rustdoc which allows to run code examples defined in doc comments

which allows to run code examples defined in doc comments and the unit testing in D and Rust, where tests can be part of the actual implementation

The current implementation is in a very early stage. PHP 7 is required.

Goal Goal

Test Flight is not designed to replace popular test suites like PHPUnit or Codeception. It helps getting started with unit testing in small projects, removes boilerplate code and encourages to add usage examples to the documentation (and helps to avoid errors in those).

Criticism Criticism

In contrast to compiled languages where test methods can be removed during compilation, test methods for Test Flight will remain in deployed code. But due to Reflection test methods don't have to be public.

Installation Installation

composer.phar require cundd/test-flight

Create Tests Create Tests

Create DocComment tests

Provide a DocComment for your method and add a code example within <code>...</code> :

class Me { private $name = ''; function __construct($name) { $this->name = $name; } /** * The examples can be single line * * <code>test_flight_assert((new Me('Daniel'))->getName() === 'Daniel')</code> * * @return string */ public function getName() { return $this->name; } /** * ... and multi line * <code> * $instance = new Me('Daniel'); * test_flight_assert('Leinad' === $instance->getNameReversed()); * </code> * * @return string */ public function getNameReversed() { return ucfirst(strtolower(strrev($this->name))); } }

Create documentation tests

Every code snippet inside a Markdown file that is wrapped into a PHP code block is a documentation test:

```php assert(true); ```

Take a look at this file as an example.

Creating inline method tests

class MyClass { public function getName() { return 'Daniel'; } /** * @test */ protected function makeSureSomethingIsTrue() { // Non-static methods will be called on an instance of the class test_flight_assert('Daniel' === $this->getName()); } }

Method tests can also be static. This may be required if the creation of an instance requires arguments.

class ComplexClass { private $name = ''; function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } /** * @test */ protected static function makeSureSomethingIsTrue() { $instance = new ComplexClass('Daniel'); test_flight_assert('Daniel' === $instance->getName()); } }

Run Tests Run Tests

vendor/bin/test-flight path/to/source

You can also specify the type of tests to run:

# Run DocComment tests vendor/bin/test-flight path/to/source --type doccomment # Run documentation tests vendor/bin/test-flight path/to/source --type documentation # Run method tests vendor/bin/test-flight path/to/source --type method

More verbose output can be triggered with -v :

vendor/bin/test-flight path/to/source -v

Add a custom bootstrap file to be included before the tests are run:

vendor/bin/test-flight --bootstrap path/to/bootstrap.php path/to/source

Configuration Configuration

Test-Flight can be configured through command line arguments and JSON files.

The following examples showcase the configuration options for bootstrap :

Specify the bootstrap file as command line argument

vendor/bin/test-flight --bootstrap path/to/bootstrap.php path/to/source

Create a JSON file and pass it as argument

{ "path": "../../src/", "bootstrap": "test-bootstrap.php" }

vendor/bin/test-flight --configuration path/to/configuration.json

Create .test-flight.json in the current directory

{ "path": "src/", "bootstrap": "tests/resources/test-bootstrap.php" }

ls .test-flight.json; vendor/bin/test-flight

Assertions Assertions

Currently only a few assertions are built in. They always come in two flavours, a static method and a function (wrapping the method).

Test if the assertion is true

test_flight_assert($assertion, [string $message])

\Cundd\TestFlight\Assert::assert($assertion, [string $message])

Test if the callback throws an exception

test_flight_throws(callable $callback, [string $expectedException], [string $message])

\Cundd\TestFlight\Assert::throws(callable $callback, [string $expectedException], [string $message])

Test if the actual value matches the expected

test_flight_assert_same($expected, $actual, [string $message])

\Cundd\TestFlight\Assert::assertSame($expected, $actual, [string $message])

Test if the value is truthy

test_flight_assert_true($actual, [string $message])

\Cundd\TestFlight\Assert::assertTrue($actual, [string $message])

Test if the value is falsy

test_flight_assert_false($actual, [string $message])

\Cundd\TestFlight\Assert::assertFalse($actual, [string $message])

Test if the given object is an instance of the given class

test_flight_assert_instance_of($actual, string $className, [string $message])

\Cundd\TestFlight\Assert::assertInstanceOf($actual, string $className, [string $message])

Test if the given value is an instance of the given type

test_flight_assert_type($actual, string $type, [string $message])