SpecBDD Framework for PHP

Overview

phpspec

The main website with documentation is at http://www.phpspec.net.

Main Build Status Master Scrutinizer Quality Score AppVeyor build status Total downloads Latest stable version Latest unstable version Software license

Installing Dependencies

Dependencies are handled via composer:

wget -nc https://getcomposer.org/composer.phar
php composer.phar install

Developer's mailing list

For development discussion subscribe to [email protected].

Community

Check out #phpspec on irc.freenode.net.

Comments
  • [WIP] Fix instantiation for latest PHP versions.

    [WIP] Fix instantiation for latest PHP versions.

    PHP 5.4.29 and 5.5.13 introduced a BC break that prevents using serialization as a means for instantiating internal objects without calling their constructor (unless they implement Serializable) [1]. This issue is still evolving and workarounds are currently being discussed in the PHP internals mailing list [2].

    In the mean time, since many PHP libraries rely on this functionality which is becoming increasingly complicated to support, @Ocramius has created ocramius/instantiator [3]. This PR adds support for ocramius/instantiator so that phpspec can continue to support this feature and stay in sync with other PHP libraries which support this feature without having to duplicate logic/updates across multiple projects.

    Please note that switching to ocramius/instantiator doesn't immediately solve all problems related to this BC break. Right now some of our tests are still failing. Ideally, as workarounds become available, they will be added to ocramius/instantiator.

    bug 
    opened by whatthejeff 53
  • Trigger an error when expected spec class is not found in file

    Trigger an error when expected spec class is not found in file

    fixes #354

    First phpspec PR, please be gentle!

    I have often come across this issue when renaming/moving a spec file and forgetting to update the classname/namespace inside.

    I'm not sure throwing an exception is the correct thing to do here, if there is a more appropriate way to handle this a nudge in the right direction would be muchly appreciated.

    feature 
    opened by tomphp 47
  • allow parameters in extension

    allow parameters in extension

    This is a BC Break.

    You must change phpspec.yml accordingly:

    # before
    extensions:
        - Some\Extension
    
    # after:
    extensions:
        Some\Extension: ~
        # or, and that's why
        Some\Other\Extension:
            option1: ~
    

    I started to spec this until I realised this class is not speccable with current impl.

    We should extract this extension loading mechanism to its own class.

    feature 
    opened by docteurklein 38
  • Interface method generation

    Interface method generation

    This is an implementation for the discussion here: https://github.com/phpspec/phpspec/issues/998#issuecomment-246125287. It aims to cover the following scenario:

    1. Interface Foo already exists
    2. We create a new concrete type called Bar
    3. PhpSpec generates Bar for us
    4. We update our BarSpec so that it specifies it should be a Foo type
    5. PhpSpec then adds the implements based on whether Foo is an interface, and any method stubs.

    TODO:

    • [x] Create new generator for interfaces
    • [x] Add specs to cover edge cases (e.g. classes with existing interfaces, interfaces from other namespaces)
    • [x] Add more scenarios
    • [x] Add scenario to ensure that answering "N" to code generation does not generate interface methods
    • [x] Refactor ClassFileAnalyser methods (findEndOfImplementsDeclaration and getClassNamespace)
    • [x] Refactor InvalidTypeListener::afterSuite() method to improve grade
    • [x] Add support for type hinted arguments in interface methods
    • [x] Update docs
    • [ ] Fix method return type hint generation
    feature 
    opened by jameshalsall 36
  • add array() to newInstanceArgs doubles

    add array() to newInstanceArgs doubles

    Hey

    Sorry for the failure in running the specs before opening the pull request.

    Have added the missing argument to the reflection class doubles (is that the right name?) and the result after running bin/phpspec is now:

    67 specs
    384 examples (384 passed)
    744ms
    
    opened by henrikbjorn 36
  • Drop support for PHP 5.3.x

    Drop support for PHP 5.3.x

    Travis just failed one of my PRs because I used short array syntax. I was surprised that phpspec still tests against 5.3 because the version is completely obsolete and we should be discouraging its use.

    How do people feel about dropping support for 5.3.x?

    refactoring 
    opened by shanethehat 31
  • [Question] type hints for generated methods

    [Question] type hints for generated methods

    What do you think about type hints for generated methods ? I mean if i've in specification, for example construct behaviour:

    ->beConstructedWith(Foo $foo, $bar)
    

    generated __construct method should look like that:

    use Foo;
    ...
        public function __construct(Foo $foo, $bar);
    ...
    

    this solution should avoid some manual work...

    opened by kwreczycki 30
  • Added generating of not found interfaces and implementing

    Added generating of not found interfaces and implementing

    I was thinking that it would be cool if PHPSpec helped you with generating and implementing interfaces :)

    Generating interfaces

    so for example if I had a spec like this:

    <?php
    
    namespace spec\KingsLanding;
    
    use PhpSpec\ObjectBehavior;
    
    class KingSpec extends ObjectBehavior
    {
        function it_should_be_a_royalty()
        {
            $this->shouldImplement('Royal\RoyaltyInterface');
        }
    }
    

    Let's say the interface Royal\RoyaltyInterface didn't exist because I haven't done it yet. So when we distinguish the shouldImplement matcher, PHPSpec could ask me if I want to create the Royal\RoyaltyInterface - and if I said yes it could generate the file for me.

    Implementing interfaces

    Ok now when the interface is created we're not quite there yet. The interface is generated but the class still doesn't implement it. So I thought it could ask me if KingsLanding\King should implemented Royal\RoyaltyInterface and if I said yes it could add the implementation header to the class :)

    I think this could automate nicely a few things at least. The whole process in a console is illustrated in this screenshot: http://d.pr/i/Uefo

    Result

    So in the end I would end up with something like this:

    <?php
    //Royal/RoyalInterface.php
    namespace Royal;
    
    interface RoyaltyInterface
    {
    }
    
    //KingsLanding/King.php
    <?php
    
    namespace KingsLanding;
    
    class King implements \Royal\RoyaltyInterface
    {
    }
    
    
    opened by karolsojko 29
  • [WIP] Added the ability to skip examples

    [WIP] Added the ability to skip examples

    This is the first step of the topic related in the issue #119. Second step would be to introduce guards (through example annotations) that will check some conditions (php version, package version, extension avaibility, etc...) and throw SkippingException for the user.

    Dot formatter

    capture du 2014-02-27 12 20 47

    With the verbose option activated: capture du 2014-02-27 12 21 12

    Progress formatter

    capture du 2014-02-27 12 32 01

    With the verbose option activated: capture du 2014-02-27 12 32 18

    Pretty formatter

    capture du 2014-02-27 12 37 57

    With the verbose option activated: capture du 2014-02-27 12 38 20

    JUnit formatter

    <?xml version="1.0" encoding="UTF-8" ?>
    <testsuites time="0.067584991455078" tests="8" failures="0" errors="0">
        <testsuite name="PhpSpec\CodeGenerator\Generator\ClassGenerator" time="0.067502021789551" tests="8" failures="0" errors="0" skipped="1">
            <testcase name="it is a generator" time="0.014213800430298" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="it supports class generations" time="0.0051472187042236" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="skipped">
                <skipped><![CDATA[ skipped: This is incompatible for some reason ]]></skipped>
            </testcase>
            <testcase name="it does not support anything else" time="0.0057218074798584" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="its priority is 0" time="0.0049088001251221" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="it generates class from resource and puts it into appropriate folder" time="0.012134790420532" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="it uses template provided by templating system if there is one" time="0.0092339515686035" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="it creates folder for class if needed" time="0.0084249973297119" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
            <testcase name="it asks confirmation if class already exists" time="0.0066289901733398" classname="spec\PhpSpec\CodeGenerator\Generator\ClassGeneratorSpec" status="passed" />
        </testsuite>
    </testsuites>
    

    HTML formatter

    capture du 2014-02-27 14 37 21

    opened by gquemener 28
  • Converted PhpSpec to a single-command application

    Converted PhpSpec to a single-command application

    This makes running phpspec simpler: it is just 'phpspec' now instead of 'phpspec run'. The majority of commenters in https://github.com/phpspec/phpspec/issues/238 seemed to agree that it is better.

    I tend to think that a single-command app is far more logical in the case of PhpSpec.

    The second commit adds a BC layer, so that phpspec run still runs the full suite instead of an empty one, to avoid breaking the testing of libraries using PhpSpec on their CI server. It outputs a message instead to tell users to upgrade their command. this BC layer should be removed at some point in the future.

    opened by stof 27
  • Build phar using box

    Build phar using box

    Fixes #532

    $ ./bin/build_phar
    

    Trying to use the build phar in the phpspec directoy in which it was build will result in an redeclaration error, as it will try and load vendor/autoload.php and as the files in the phar and in the project are exactly the same, it will fail. So try it out in another project using phpspec :)

    opened by henrikbjorn 26
  • ObjectStateMatcher prevails over ScalarMatcher since PHP 8.0

    ObjectStateMatcher prevails over ScalarMatcher since PHP 8.0

    As pointed out in issue https://github.com/phpspec/phpspec/issues/1403 the matchers order changed since PHP 8.0.

    In our case a problem arises because ObjectStateMatcher takes precedence now over ScalarMatcher when we use $object->shouldNotBeNull().

    Then test breaks with the error method [array:2] not found. and phpspec prompts us to create a method with the message:

    Do you want me to create                                                      
      `OurClass::isNull()` for you?
    

    Our solution was simply to increment the ScalarMatcher priority to 51. If this is the best solution I can open a PR, otherwise depending of what the solution is I'l be glad if I can be of any help.

    opened by bsod85 0
  • PHPSpec does not find the right FQCN in some cases to generate doubles

    PHPSpec does not find the right FQCN in some cases to generate doubles

    I tried hard to debug this one (many times), but I have really no idea why I get it... Tried many versions of phpspec (from 6 to last). I can't stop thinking the issue is something stupid I missed, but well, I quadruple-checked everything... So here is my issue, and sorry in advance if it's stupid.

    Consider the following spec:

    namespace spec\App\MainApi\Domain\Player\Controller;
    
    use App\Exception\DomainException;
    use App\MainApi\Domain\Player\Controller\ConfirmationController;
    use App\MainApi\Domain\Player\Data\PlayerRepository;
    use Doctrine\ORM\EntityManagerInterface;
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    use Symfony\Component\Form\FormFactoryInterface;
    
    class ConfirmationControllerSpec extends ObjectBehavior
    {
        public function let(FormInterface $form, FormFactoryInterface $formFactory, PlayerRepository $playerRepository, EntityManagerInterface $entityManager)
        {
            $formFactory->createNamed(Argument::cetera())->willReturn($form);
            $this->beConstructedWith($formFactory, $playerRepository, $entityManager);
        }
    
        public function it_is_initializable()
        {
            $this->shouldHaveType(ConfirmationController::class);
        }
    }
    

    I end up with the following error, and I have no idea why:

    image

    I have a fix for it, but this code should works!

    Changing the let method to this fixes the problem:

        public function let(FormInterface $form, FormFactoryInterface $formFactory, PlayerRepository $playerRepository, EntityManagerInterface $entityManager)
        {
            $entityManager->beADoubleOf(EntityManagerInterface::class);
            $formFactory->createNamed(Argument::cetera())->willReturn($form);
            $this->beConstructedWith($formFactory, $playerRepository, $entityManager);
        }
    

    Do you have any idea why I have this issue? (I have this issue with some other interfaces/classes, but it seems connected to dependencies... I have no issues with classes living in the src folder)

    PHP Version:

    PHP 8.0.8 (cli) (built: Mar  3 2022 14:51:53) ( NTS )
    Copyright (c) The PHP Group
    Zend Engine v4.0.8, Copyright (c) Zend Technologies
        with Zend OPcache v8.0.8, Copyright (c), by Zend Technologies
    
    opened by Nek- 1
  • Remove supports/do pattern

    Remove supports/do pattern

    We have this in a lot of places (Generators, Matchers, Presenters) where we have an interface like:

    interface Foo
    {
        public function supports(mixed ...$values): bool;
        public function do(mixed ...$values): Result;
    }
    

    The problem is the concrete classes have to support(mixed) and callers have to 'remember' to call supports() first.

    Better might be a single method:

    interface Foo
    {
        public function doIfPossible(mixed ...$values): false|Result
    }
    
    opened by ciaranmcnulty 0
  • Better type safety in container

    Better type safety in container

    we retrieve services by string key, which is inherently type unsafe

    $foo = $container->get('my.service'); // what type is $foo?
    

    It would be good to migrate to PSR-style where class names are used:

    $foo = $container->get(Foo::class); // it is a Foo
    

    An intermediate step might be to add an (optional?) type check parameter

    $foo = $container->get('my.service', Foo::class); // error if the registered service is not Foo
    
    opened by ciaranmcnulty 0
Releases(7.3.0)
Owner
PHPSpec Framework
PHPSpec Framework
The modern, simple and intuitive PHP unit testing framework.

atoum PHP version atoum version 5.3 -> 5.6 1.x -> 3.x 7.2 -> 8.x 4.x (current) A simple, modern and intuitive unit testing framework for PHP! Just lik

atoum 1.4k Nov 29, 2022
Full-stack testing PHP framework

Codeception Modern PHP Testing for everyone Codeception is a modern full-stack testing framework for PHP. Inspired by BDD, it provides an absolutely n

Codeception Testing Framework 4.6k Jan 7, 2023
AST based PHP Mutation Testing Framework

Infection - Mutation Testing framework Please read documentation here: infection.github.io Twitter: @infection_php Discord: https://discord.gg/ZUmyHTJ

Infection - Mutation Testing Framework for PHP 1.8k Jan 2, 2023
:heavy_check_mark: PHP Test Framework for Freedom, Truth, and Justice

Kahlan is a full-featured Unit & BDD test framework a la RSpec/JSpec which uses a describe-it syntax and moves testing in PHP one step forward. Kahlan

Kahlan 1.1k Jan 2, 2023
Event driven BDD test framework for PHP

The highly extensible, highly enjoyable, PHP testing framework. Read more at peridot-php.github.io or head over to the wiki. Building PHAR Peridot's p

Peridot 327 Jan 5, 2023
PHP Mocking Framework

Phake Phake is a framework for PHP that aims to provide mock objects, test doubles and method stubs. Phake was inspired by a lack of flexibility and e

Phake 469 Dec 2, 2022
BDD test framework for PHP

BDD test framework for PHP, inspired by Jasmine and RSpec. Features a familiar syntax, and a watch command to automatically re-run specs during develo

Daniel St. Jules 286 Nov 12, 2022
The PHP Unit Testing framework.

PHPUnit PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. Installat

Sebastian Bergmann 18.8k Jan 4, 2023
Highly opinionated mocking framework for PHP 5.3+

Prophecy Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking framework. Though initially it was created to fulfil phpsp

PHPSpec Framework 8.5k Jan 3, 2023
PHP unit testing framework with built in mocks and stubs. Runs in the browser, or via the command line.

Enhance PHP A unit testing framework with mocks and stubs. Built for PHP, in PHP! Quick Start: Just add EnhanceTestFramework.php and you are ready to

Enhance PHP 67 Sep 12, 2022
Pest is an elegant PHP Testing Framework with a focus on simplicity

Pest is an elegant PHP Testing Framework with a focus on simplicity. It was carefully crafted to bring the joy of testing to PHP. Explore the docs: pe

PEST 5.9k Dec 27, 2022
PHP Mocking Framework

Phake Phake is a framework for PHP that aims to provide mock objects, test doubles and method stubs. Phake was inspired by a lack of flexibility and e

Phake 469 Dec 2, 2022
SimpleTest is a framework for unit testing, web site testing and mock objects for PHP

SimpleTest SimpleTest is a framework for unit testing, web site testing and mock objects for PHP. Installation Downloads All downloads are stored on G

SimpleTest 147 Jun 20, 2022
Humbug - a Mutation Testing framework for PHP

Humbug is a Mutation Testing framework for PHP to measure the real effectiveness of your test suites and assist in their improvement. It eats Code Coverage for breakfast.

Humbug 1.1k Dec 28, 2022
Essence is a very flexible BDD style assertion framework for PHP that fits into existing PHPUnit projects nicely

Essence 1.5.1 Essence is a very flexible BDD style assertion framework for PHP that fits into existing PHPUnit projects nicely. Installation composer

bound1ess 2 Apr 7, 2015
The most powerful and flexible mocking framework for PHPUnit / Codeception.

AspectMock AspectMock is not an ordinary PHP mocking framework. With the power of Aspect Oriented programming and the awesome Go-AOP library, AspectMo

Codeception Testing Framework 777 Dec 12, 2022
vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.

vfsStream vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with

null 1.4k Dec 23, 2022
Wraps your Pest suite in a Laravel application instance, allowing global use of the framework in tests.

Pest Larastrap Plugin This is currently a highly experimental project and is subject to large pre-release changes. Pest PHP is an awesome PHP testing

Luke Downing 3 Jan 6, 2022
A drop in fake logger for testing with the Laravel framework.

Log fake for Laravel A bunch of Laravel facades / services are able to be faked, such as the Dispatcher with Bus::fake(), to help with testing and ass

Tim MacDonald 363 Dec 19, 2022