Download the PHP package jimdelois/context-specification without Composer

On this page you can find all versions of the php package jimdelois/context-specification. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package context-specification

Build Status

Context Specification Testing Framework

The Context Specification (CS) library is a PHPUnit wrapper intended to promote the use of a CS-style testing pattern. This approach offers the Test-Driven Developer a working syntax which more-closely aligns with how behavior is described in business terms, giving rise to the increasingly popular "Behavior-Driven Design (BDD)" paradigm.

When compared to "traditional" unit testing, Context Specification -style BDD seems negligibly different, if at all. While at first the only deviation appears to be in syntactic semantics, the subtle arrangement of the "different" methods plays a huge part in how functionality is logically organized... and tested.

Namely, this distinction is realized when describing and considering functionality as broken into three parts... (1) The starting point; an initial state; a "Context" in which a particular action is to be taken. (2) The action itself; the "state transition" from the initial state into a new one. (3) The new, final, or resultant state after the state transition is complete.

By testing only one single transitional event or method at a time, and then verifying that everything about the new state is sufficiently expected, in conjunction with having correctly provided an initial state, it can then be assumed that the state transition, itself, is operating correctly. Since a computer program operates by endlessly transitioning from one state to another, we can ensure that a library is operating correctly by testing each transition individually, and from all known initial states. Such a consideration of behavior/functionality will likely lead to greater code coverage, fewer bugs and, when requirements can be expressed in a similar fashion, a more accurately-modeled system.

It's true that the same type of BDD can be practiced with the similar granularity and behavioral coverage without any such wrapper. The hope, however, is that providing a lightweight library and suggesting that a few rules be followed, a developer's tests will read more clearly while also providing a more natural report of test failures (and successes!).

Lastly, there are several approaches that could tighten up the BDD paradigm substantially, similar to some other frameworks in other languages. However, this library is developed specifically for PHPUnit, with tooling in mind. That is to say, this library should work correctly in all extensions of PHPUnit (so long as they aren't explicitly removing default behavior), regardless of any customized TestRunners, Commands, etc, put in place by either a developer or an IDE.

Installation

It is recommended that the Context Specification library be installed via the Composer dependency management tool. Otherwise, the latest compressed file may be downloaded from Github at any time, and any PSR-4 autoloaders will work to include the files therein.

Composer Installation

To your composer.json file, add the following:

"require" : {
    "jimdelois/context-specification": "0.1.*@dev" ,
}

Once you've run composer install or composer update, you should have the right libraries available to you within the {vendordir}/jimdelois/context-specification/src/ContextSpecification/Framework/ directory.

Basic Usage

Depending on the need, simply extend the Concern or StaticConcern classes and begin testing as normal!

If global or isolated functionality is being tested where no state can be injected, inserted, or tracked, then the StaticConcern will be just enough of a harness for this. In either case, it is up to the developer to provide an implementation for the following two abstract methods:

abstract protected function context( );
abstract protected function because( );

The context method is where the starting point, or initial state is established. The because method will be called next, where the SUT or isolated functionality will have its one and only tested state change executed.

If there is a System Under Test (SUT) which requires some initial state, has dependencies which require state prior to injection, or has a resultant internal state that must be checked, then the developer should extend the Concern class and instantiate this system from within:

protected function createSUT( );

By returning the object or system under test from this method, it will automatically be available within the Concern class as $this->sut. It ought be on this object that a Context is set specific to the test, state changes are invoked (in the because method), and assertions are made in observations.

Such observations, whether or not there is a SUT, can be made in standard PHPUnit "test" methods. Any method prefixed with "test" will work, although it is a general recommendation to use the @test annotation built into PHPUnit and then name the observation methods in accordance with traditional CS language, such as should, etc. This will have benefits of a better report, e.g., a --testdox report will read like a regular CS report.

E.g., consider MyTest.php as:

Then, most reports will read like a traditional CS one (note the verbosity!):

$ ../vendor/bin/phpunit --testdox MyTest.php
PHPUnit 3.7.33 by Sebastian Bergmann.

When_attempting_to_do_something_awesome_given_a_specific_context
[x] should_really_be_awesome
[x] then_it_should_not_be_boring

Additionally, the method decontext is available for optionally "undoing" any of the context establishment. This method is called after each observation, balancing the calls to context. Note that reliance on this method to pass tests for true "units" of functionality is likely the result of a poor test approach or, worse, a bad design (globals?!). Depending on the code we're testing, we may not be able to get away from this, so this function provides an opportunity to "reset" anything between observations. In "integration" testing (not "unit"), the need to do this is more commonplace and arguably much more "acceptable".

Finally, the Context Specification library offers a small amount of extra functionality that is useful in dealing with Exceptions raised from state changes. Just as one should test for all possible positive-scenario contexts, a developer should also test for contexts in which state might be invalid... Typically the target functionality (in the SUT) will be coded to raise an exception in this case. If we provided an invalid input directly into our because method's state change:

protected function because( ) {
    $this->sut->setInteger( 'This is a string but the method expects an INT!' );
}

... The actual invocation of because would cause the Exception to be raised before we're prepared, and PHPUnit would fail immediately. The correct solution is NOT to leave the because method blank and move the state change to the observation! Doing so brings us further back to "standard" TDD practice, wherein the state change is invoked within the same method that asserts - this is precisely what we're trying to avoid. Rather, consider capturing the Exception from within the because method and then evaluating it later. Alternatively, try wrapping the state change in a lambda function and then invoke it later. While the latter approach is only a semantic difference from the "discouraged" one, it's an important distinction which helps to keep our tests consistent and well-organized.

As testing invalid states and ensuring correct Exceptions are raised is a very common occurrence (or should be), the Context Specification framework does the favor of minimizing the amount of work the testing developer has to do to deal with these nuances. By simply calling $this->becauseWillThrowException( );, the Concern will be configured to automatically wrap the because method contents in a lambda, meaning one can define the state change as per usual. Then, two additional methods become available which can be used from within observations to validate and assert the resultant Exceptions: releaseException and captureException.

Examples

Below are a couple of (silly) examples of how we might test a single method on a service using the Context Specification library.

Now, assuming that we've correctly implemented the functionality for the method getFirstAvailableAwesomenessForDate( ) on the MyAwesomeAppService object (only AFTER writing the test, of course!), then we should see something like the following:

$ ../vendor/bin/phpunit --testdox
PHPUnit 3.7.33 by Sebastian Bergmann.

When_loading_first_awesomeness_from_service_for_date
[x] should_call_appropriate_method_on_awesomeness_dao
[x] should_return_correct_awesomeness_object

That's pretty nice! Let's iterate on the functionality of our getFirstAvailableAwesomenessForDate method and ensure that an exception is raised is the input isn't a \DateTime object.

Note that the framework allowed us to keep a nice, clean because method regardless of the fact that invocation would cause a test-failing error.

Alternatively, one could call captureException which would avoid throwing it and then make it available from within $this->exception so that it may be inspected and used in assertions. It's also possible that one might want to make assertions on the state of $this->sut after having thrown the exception from within.

Ideally, correct implementation will then yield the following when the entire suite is run:

$ ../vendor/bin/phpunit --testdox
PHPUnit 3.7.33 by Sebastian Bergmann.

When_loading_first_awesomeness_from_service_for_date
[x] should_call_appropriate_method_on_awesomeness_dao
[x] should_return_correct_awesomeness_object

When_loading_first_awesomeness_from_service_for_non_date_input
[x] should_raise_invalid_argument_exception

There are some obvious flaws to these two trivial examples, and they are already screaming for a shared parent base Concern. However, the point of intended usage here is arguably more important than proper test design or architecture.

Issues

Next Steps

Questions/Feedback

Jim DeLois - %%PHPDOC_AUTHOR_EMAIL%%


All versions of context-specification with dependencies

PHP Build Version
Package Version
Requires php Version >=5.3.0
phpunit/phpunit Version ~4.5.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package jimdelois/context-specification contains the following files

Loading the files please wait ....