Automatically rerun PHPUnit tests when source code changes with phpunit-watcher

Nice new package by Freek from Spatie.be. Think of it like Jest, but for PHP:

Wouldn’t it be great if your PHPUnit tests would be automatically rerun whenever you change some code? This package can do exactly that.

By default it will watch all files in the src, app and tests subdirectories in the directory where it is started.

Installation per Composer, of course:

composer global require spatie/phpunit-watcher

spatie/phpunit-watcher introductory blogpost →
spatie/phpunit-watcher (GitHub) →

Sidenote: If you’re new to PHPUnit, Sitepoint has got you covered with a newly released (re-)introduction to PHPUnit. Also, the folks over at CxSocial (former Engagor) have written a nice post on how to write better tests in PHPUnit

Snapshot testing with PHPUnit

use Spatie\Snapshots\MatchesSnapshots;

class OrderTest
{
    use MatchesSnapshot;

    class test_it_casts_to_json()
    {
        $orderId = new Order(1);

        $this->assertMatchesJsonSnapshot($order->toJson());
    }
}

Again great work by the folks at Spatie:

The difference between a classic assertEquals and an assertMatchesSnapshot is that you don’t write the expectation yourself when snapshot testing. When a snapshot assertion happens for the first time, it creates a snapshot file with the actual output, and marks the test as incomplete. Every subsequent run will compare the output with the existing snapshot file to check for regressions.

A Package for Snapshot Testing in PHPUnit →
spatie/phpunit-snapshot-assertions (GitHub) →

Jest – Painless JavaScript Testing

jest

I’ve been hearing great things about Jest lately. It’s worth checking it out:

Jest is a JavaScript testing framework, used by Facebook to test all JavaScript code including React applications.

Install Jest using npm (along with some extra Babel presets if you’re writing ES2015 – Don’t forget to configure Babel using .babelrc to use the es2015 and react presets):

npm install --save-dev babel-jest babel-polyfill babel-preset-es2015 babel-preset-react jest

A simple – non-React – test is this (put it in a folder named __tests__):

describe('Addition', () => {
  it('knows that 2 and 2 make 4', () => {
    expect(2 + 2).toBe(4);
  });
});

As read in the description, you can also use it to test React components with it.

Jest – Painless JavaScript Testing →
Egghead: Getting started with Jest (Video) →
How to Test React Components Using Jest →
Jest 14.0: React Tree Snapshot Testing →

Extract Till You Drop

Under the pressure of deadlines and endless change requests, under the weight of years of legacy, code becomes unmaintainable. With the right tools, techniques, and mindset, any codebase can be brought under test, and be refactored towards a better architecture. Let’s skip the theory and dive straight into the spaghetti code. In a live coding session, I will demonstrate how you can start refactoring your way out of a mess today.

(via)

phpspec

phpspec

phpspec is a development tool, designed to help you achieve clean and working PHP code by using a technique derived from test-first development called (spec) behaviour driven development, or SpecBDD.

Example spec file:

<?php

namespace spec;

use PhpSpec\ObjectBehavior;

class MarkdownSpec extends ObjectBehavior {

    function it_converts_plain_text_to_html_paragraphs() {
        $this->toHtml("Hi, there")->shouldReturn("<p>Hi, there</p>");
    }

}

Running it is easy:

$ bin/phpspec run

> spec\Markdown

  ✔ it converts plain text to html paragraphs

1 examples (1 passed)
247ms

Installation via composer:

$ composer require phpspec/phpspec:~2.0

phpspec →

Huxley – Catching visual regressions in Web applications.

This content is quite old. You might want to check out this modern way of visual diffing, using Puppeteer instead

Watches you browse, takes screenshots, tells you when they change.

First you record a basic flow and take screenshots in between. Afterwards, when you’ve done some changes, you can let the flow play back again, and Huxley will re-take screenshots to compare with the ones from the first run. Video above shows how it works. By Facebook.

Huxley →

Related: Wraith, a likewise tool by the BBC.

Wraith – A responsive screenshot comparison tool

This content is quite old. You might want to check out this modern way of visual diffing, using Puppeteer instead

wraith

Wraith uses either PhantomJS, CasperJS or SlimerJS to create screen-shots of webpages on different environments and then creates a diff of the two images, the affected areas are highlighted in blue

By the folks over at the BBC. Video tutorial right here:

Wraith →

DummyJS – Smart Functional Testing extension for PhantomJS

open          http://my.test.site
type          :text                  John
click         "Say hi!"
assertText    .greeting              Hi, John!
$ dummyjs mytest.dummy

✓ open          http://my.test.site
✓ type          :text                  John
✓ click         "Say hi!"
✓ assertText    .greeting              Hi, John!

PASS: Executed 4 actions in 1s.

DummyJS makes writing and running automated functional tests for websites and webapps incredibly easy. Tests can be run in sequence or in parallel and accurately mimic human behavior for true user-like testing.

DummyJS →

PHP and Continuous Integration with Travis CI

travis-ci

Travis CI automatically sets up a CI environment and makes it simple for anyone to test and deploy their app. Their build system supports many different languages, you just have to define which language this project is and Travis CI will take care of the rest

Good article by Sitepoint on getting started with Travis CI. I’ve been using Travis CI myself for the PHP Router I wrote a while ago (See the build history here). Works like a charm 🙂

PHP and Continuous Integration with Travis CI →

bramus/router Updates

It’s been 4 months since I released bramus/router, the lightweight and object oriented PHP Router I wrote. Since then a few new features worth mentioning were added.

Subrouting Support

It’s now possible to mount several routes onto a base route. Think of creating a /movies route on which you attach a callable which in its turn adds subroutes onto the base route. The result is that all subroutes will get prefixed with that base route:

// Create a Router
$router = new \Bramus\Router\Router();

// Subrouting
$router->mount('/movies', function() use ($router) {

	// will result in '/movies'
	$router->get('/', function() {
		echo 'movies overview';
	});

	// will result in '/movies'
	$router->post('/', function() {
		echo 'add movie';
	});

	// will result in '/movies/id'
	$router->get('/(\d+)', function($id) {
		echo 'movie id ' . htmlentities($id);
	});

	// will result in '/movies/id'
	$router->put('/(\d+)', function($id) {
		echo 'Update movie id ' . htmlentities($id);
	});

});

// Thunderbirds are go!
$router->run();

You can of course mount any callable you like:

class MoviesController {

	public function __construct($router) {

		// will result in '/movies'
		$router->get('/', function() {
			echo 'movies overview';
		});

		// will result in '/movies'
		$router->post('/', function() {
			echo 'add movie';
		});

		// will result in '/movies/id'
		$router->get('/(\d+)', function($id) {
			echo 'movie id ' . htmlentities($id);
		});

		// will result in '/movies/id'
		$router->put('/(\d+)', function($id) {
			echo 'Update movie id ' . htmlentities($id);
		});

	}

}

$router->mount('/movies', function() use ($router) { new MoviesController($router); });

Support for HEAD requests

bramus/router will now properly respond to HEAD requests, as per RFC2616 (Hypertext Transfer Protocol — HTTP/1.1) Specification:

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request.

Internally the request method is overwritten to GET when a HEAD request is made. Output buffering then keeps output from trickling into the response.

Support for X-HTTP-Method-Override

It’s now also possible to use an X-HTTP-Method-Override header to override the HTTP Request Method.

Some HTTP clients can only work with simple GET and POST requests, or sometimes firewalls can spoil all the fun. Although there aren’t any hard standards here, the popular convention is to do a POST request and accept a request header X-HTTP-Method-Override with a string value containing one of PUT, PATCH or DELETE to override the method

bramus/router (GitHub) →
bramus/router on Packagist →
bramus/router Travis CI build status →