Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Shipping Faster With Storyplayer

Shipping Faster With Storyplayer

Avoid costly rework and angry customers by validating your solution as you develop it.

This talk was given at PHP London on Thursday 5th May 2016.

Stuart Herbert

May 05, 2016
Tweet

More Decks by Stuart Herbert

Other Decks in Programming

Transcript

  1. @GanbaroDigital as a scheme user - using a HTTP request

    - I can generate a new auth token for the Notifications API
  2. @GanbaroDigital as a scheme user - using a HTTP request

    - I can generate a new auth token for the Notifications API
  3. @GanbaroDigital $story->addTestSetup(function() { $user = fromUsers() ->getUser('scheme_user'); if (isset($user->access_token)) {

    unset($user->access_token); } if (isset($user->token_expires)) { unset($user->token_expires); } });
  4. @GanbaroDigital $story->addTestSetup(function() { $user = fromUsers() ->getUser('scheme_user'); if (isset($user->access_token)) {

    unset($user->access_token); } if (isset($user->token_expires)) { unset($user->token_expires); } });
  5. @GanbaroDigital $story->addTestSetup(function() { $user = fromUsers() ->getUser('scheme_user'); if (isset($user->access_token)) {

    unset($user->access_token); } if (isset($user->token_expires)) { unset($user->token_expires); } });
  6. @GanbaroDigital as a scheme user - using a HTTP request

    - I can generate a new auth token for the Notifications API
  7. @GanbaroDigital $story->addAction(function() { // where is our API? $hostname =

    fromFirstHostWithRole(‘payment-api’)
 ->getHostname(); $url = “http://{$hostname}/api/token”; // get the token $result = usingHttp()->post(…); expectsHttpResponse($result)->hasStatusCode(200); });
  8. @GanbaroDigital $story->addAction(function() { // where is our API? $hostname =

    fromFirstHostWithRole(‘payment-api’)
 ->getHostname(); $url = “http://{$hostname}/api/token”; // get the token $result = usingHttp()->post(…); expectsHttpResponse($result)->hasStatusCode(200); });
  9. @GanbaroDigital $story->addAction(function() { // where is our API? $hostname =

    fromFirstHostWithRole(‘payment-api’)
 ->getHostname(); $url = “http://{$hostname}/api/token”; // get the token $result = usingHttp()->post(…); expectsHttpResponse($result)->hasStatusCode(200); });
  10. @GanbaroDigital as a scheme user - using a HTTP request

    - I can generate a new auth token for the Notifications API
  11. @GanbaroDigital as a scheme user - using a HTTP request

    - I can generate a new auth token for the Notifications API afterwards - the token will be in the database - I can access the Notifications API
  12. @GanbaroDigital $story->addAction(function() { // where is our API? $hostname =

    fromFirstHostWithRole(‘payment-api’)
 ->getHostname(); $url = “http://{$hostname}/api/token”; // get the token $result = usingHttp()->post(…); expectsHttpResponse($result)->hasStatusCode(200); // remember the result $checkpoint = getCheckpoint(); $checkpoint->httpResult = $result; });
  13. @GanbaroDigital $story->addPostTestInspection(function() { // get the result from the action

    $checkpoint = getCheckpoint(); $httpResult = $checkpoint->httpResult; // make sure it has an access token assertsString($httpResult->body)->isValidJson(); $data = json_decode($httpResult->body); assertsObject($data)->hasAttribute(‘access_token’); // get our access token $user = fromUsers()->getUser(‘scheme_user’); $user->access_token = $data->access_token; });
  14. @GanbaroDigital $story->addPostTestInspection(function() { // get the result from the action

    $checkpoint = getCheckpoint(); $httpResult = $checkpoint->httpResult; // make sure it has an access token assertsString($httpResult->body)->isValidJson(); $data = json_decode($httpResult->body); assertsObject($data)->hasAttribute(‘access_token’); // get our access token $user = fromUsers()->getUser(‘scheme_user’); $user->access_token = $data->access_token; });
  15. @GanbaroDigital $story->addPostTestInspection(function() { // where is our API? $hostname =

    fromFirstHostWithRole(‘payment-api’)
 ->getHostname(); $url = “http://{$hostname}/api/notifications”; // use the new access token $user = fromUsers()->getUser(‘scheme_user’); $result = fromHttp()->get( $url, [ ‘Authorization’ => $user->access_token] ); expectsHttpResponse($result)->hasStatusCode(200); });
  16. @GanbaroDigital Shipping Faster 1. Prove features work before you merge

    2. Use features in the same way as your end-user 3. Iterate, iterate, iterate before you merge 4. Ship and move on to the next feature!
  17. @GanbaroDigital Not a problem. With our growing test suite, we

    could prove that all of our work had been moved across after re-integration.
  18. @GanbaroDigital Representative 1. Comparable operating system 2. Comparable web server

    3. Right version of PHP! 4. Comparable network restrictions
  19. @GanbaroDigital Vagrant + Virtualbox 1. Slow to build on demand

    2. Can’t run a full cluster locally 3. Inbound network connections are painful 4. Still causes host OS crashes at times
  20. @GanbaroDigital Docker For Dev Environments 1. Very fast to build

    on demand 2. Can simulate multiple clusters locally 3. Inbound network connections are quick 4. Never had it cause a host OS crash
  21. @GanbaroDigital Test Environments • A list of host(s) in the

    environment • Hosts are tagged with one or more roles • Multiple hosts can have the same role(s) • Tests lookup hosts by role, not hostname
  22. @GanbaroDigital Run Your Tests … • Locally • Against dev

    VMs • From your CI pipeline • And anywhere else you want to
  23. @GanbaroDigital Productive Developers … 1. Question everything, so that they

    can 2. … ship working code 3. … that’s fit for purpose 4. avoiding costly rework
  24. Would you like to 
 know more? We can help.

    Stuart Herbert ~ @stuherbert Founder @GanbaroDigital