2017 © Pedro Peláez
 

library specify

BDD code blocks for PHPUnit and Codeception

image

codeception/specify

BDD code blocks for PHPUnit and Codeception

  • Tuesday, March 13, 2018
  • by davert
  • Repository
  • 14 Watchers
  • 97 Stars
  • 2,074,267 Installations
  • PHP
  • 515 Dependents
  • 20 Suggesters
  • 17 Forks
  • 3 Open issues
  • 21 Versions
  • 9 % Grown

The README.md

Specify

BDD style code blocks for PHPUnit or Codeception, (*1)

Latest Stable Version Total Downloads Latest Unstable Version License StandWithUkraine, (*2)

Specify allows you to write your tests in more readable BDD style, the same way you might have experienced with Jasmine. Inspired by MiniTest of Ruby now you combine BDD and classical TDD style in one test., (*3)

Installation

Requires PHP >= 7.4, (*4)

  • Install with Composer:
composer require codeception/specify --dev
  • Include Codeception\Specify trait in your tests.

Usage

Specify $this->specify method to add isolated test blocks for your PHPUnit tests!, (*5)

public function testValidation()
{
    $this->assertInstanceOf('Model', $this->user);

    $this->specify('username is required', function() {
        $this->user->username = null;
        $this->assertFalse($this->user->validate(['username']));
    });

    $this->specify('username is too long', function() {
        $this->user->username = 'toolooooongnaaaaaaameeee';
        $this->assertFalse($this->user->validate(['username']));
    });
}

BDD Example

Specify supports describe-it and describe-should BDD syntax inside PHPUnit, (*6)

public function testValidation()
{
    $this->describe('user', function () {
        $this->it('should have a name', function() {
            $this->user->username = null;
            $this->assertFalse($this->user->validate(['username']));
        });
    });

    // you can use chained methods for better readability:
    $this->describe('user')
        ->should('be ok with valid name', function() {
            $this->user->username = 'davert';
            $this->assertTrue($this->user->validate(['username']));
        })
        ->shouldNot('have long name', function() {
            $this->user->username = 'toolooooongnaaaaaaameeee';
            $this->assertFalse($this->user->validate(['username']));
        })
        // empty codeblocks are marked as Incomplete tests
        ->it('should be ok with valid name') 
    ;
}

Specify + Verify Example

Use Codeception/Verify for simpler assertions:, (*7)

public function testValidation()
{
    $this->specify('username is too long', function() {
        $this->user->username = 'toolooooongnaaaaaaameeee';
        expect_not($this->user->validate(['username']));
    });

    $this->specify('username is ok', function() {
        $this->user->username = 'davert';
        expect_that($this->user->validate(['username']));
    });
}

Use Case

This tiny library makes your tests readable by organizing them in nested code blocks. This allows to combine similar tests into one but put them inside nested sections., (*8)

This is very similar to BDD syntax as in RSpec or Mocha but works inside PHPUnit:, (*9)

user = new User;
    }

    public function testValidation()
    {
        $this->user->name = 'davert';
        $this->specify('i can change my name', function() {
           $this->user->name = 'jon';
           $this->assertEquals('jon', $this->user->name);
        });
        // user name is 'davert' again
        $this->assertEquals('davert', $this->user->name);
    }
}
```

Each code block is isolated. This means call to `$this->specify` does not change values of properties of a test class.
Isolated properties should be marked with `@specify` annotation.

Failure in `specify` block won't get your test stopped.

```php
specify('failing but test goes on', function() {
    $this->fail('bye');
});
$this->assertTrue(true);

// Assertions: 2, Failures: 1
?>

If a test fails you will see specification text in the result., (*10)

Isolation

Isolation is achieved by cloning object properties for each specify block. Only properties marked with @specify annotation are cloned., (*11)

/** @specify */
protected $user; // cloning

/** 
 * @specify 
 **/
protected $user; // cloning

protected $repository; // not cloning

Objects are cloned using deep cloning method., (*12)

If object cloning affects performance, consider turning the clonning off., (*13)

Mocks are isolated by default., (*14)

A mock defined inside a specify block won't be executed inside an outer test, and mock from outer test won't be triggered inside codeblock., (*15)

createMock(Config::class);
$config->expects($this->once())->method('init');

$config->init();
// success: $config->init() was executed

$this->specify('this should not fail', function () {
    $config = $this->createMock(Config::class);
    $config->expects($this->never())->method('init')->willReturn(null);
    // success: $config->init() is never executed 
});
```

## Examples: DataProviders alternative

```php
specify('should calculate square numbers', function($number, $square) {
    $this->assertEquals($square, $number*$number);
}, ['examples' => [
        [2,4],
        [3,9]
]]);
```

You can also use DataProvider functions in `examples` param.

```php
specify('should calculate square numbers', function($number, $square) {
    $this->assertEquals($square, $number*$number);
}, ['examples' => $this->provider()]);
```

Can also be used with real data providers:

```php
specify('should assert data provider', function ($example) use ($param) {
        $this->assertGreaterThanOrEqual(5, $param + $example);
    }, ['examples' => [[4], [7], [5]]]);
}

public function someData()
{
    return [[1], [2]];
}
```

## Before/After

There are also before and after callbacks, which act as setUp/tearDown but for specify.

```php
beforeSpecify(function() {
    // prepare something;   
});
$this->afterSpecify(function() {
    // reset something
});
$this->cleanSpecify(); // removes before/after callbacks
?>

API

Available methods:, (*16)

// Starts a specify code block:
$this->specify(string $thing, callable $code = null, $examples = [])

// Starts a describe code block. Same as 'specify' but expects chained 'it' or 'should' methods.
$this->describe(string $feature, callable $code = null)

// Starts a code block. If 'code' is null, marks test as incomplete.
$this->it(string $spec, callable $code = null, $examples = [])
$this->its(string $spec, callable $code = null, $examples = [])

// Starts a code block. Same as 'it' but prepends 'should' or 'should not' into description.
$this->should(string $behavior, callable $code = null, $examples = [])
$this->shouldNot(string $behavior, callable $code = null, $examples = [])

Printer Options

For PHPUnit, add Codeception\Specify\ResultPrinter printer into phpunit.xml, (*17)

<phpunit colors="true" printerClass="Codeception\Specify\ResultPrinter">
</phpunit>

License: [MIT.][7], (*18)

The Versions

13/03 2018

dev-master

9999999-dev

BDD code blocks for PHPUnit and Codeception

  Sources   Download

MIT

The Requires

 

The Development Requires

13/03 2018

1.1

1.1.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

MIT

The Requires

 

13/03 2018

dev-DavertMik-patch-1

dev-DavertMik-patch-1

BDD code blocks for PHPUnit and Codeception

  Sources   Download

MIT

The Requires

 

21/11 2017

1.0

1.0.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

MIT

The Requires

 

21/10 2016

0.4.6

0.4.6.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

MIT

The Requires

 

The Development Requires

18/10 2016

0.4.5

0.4.5.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

13/10 2016

0.4.4

0.4.4.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

27/11 2015

0.4.3

0.4.3.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

26/09 2015

0.4.2

0.4.2.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

17/10 2014

0.4.1

0.4.1.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

15/10 2014

0.4.0

0.4.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

22/03 2014

0.3.6

0.3.6.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

22/03 2014

0.3.5

0.3.5.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

23/02 2014

0.3.4

0.3.4.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

 

The Development Requires

04/10 2013

0.3.3

0.3.3.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

03/10 2013

0.3.2

0.3.2.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

03/10 2013

0.3.1

0.3.1.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

03/10 2013

0.3.0

0.3.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

29/08 2013

0.2.1

0.2.1.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

29/08 2013

0.2.0

0.2.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires

25/07 2013

0.1.0

0.1.0.0

BDD code blocks for PHPUnit and Codeception

  Sources   Download

The Requires

  • php >=5.4.0

 

The Development Requires