Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Releasing Your Open Source
Project
How to write libraries people won't
(completely) hate
By @thomas_shone
WARNING
●
Opinionated
●
Rambling
●
Foul-Mouthed
●
Ugly Slides
●
Don't feed after midnight
00. Introduction
●
No formal education in PHP
●
Learnt PHP the hard way
●
This talk is about the process
●
Connect with pe...
00. Introduction
00. Introduction
<?php
function isUrlSafe($api_key, $url) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
throw new Except...
10. Security
●
Shouldn't be left till last
●
Unsure of how to do it properly
●
Worst thing that can happen to insecure ope...
10. Security
●
Shouldn't be left till last
●
Unsure of how to do it properly
●
Worst thing that can happen to insecure ope...
01. Security
●
Shouldn't be left till last
●
Unsure of how to do it properly
●
Worst thing that can happen to insecure ope...
01. Security
●
Joomla!
– 5/133 versions secure
– 85 vulnerabilities
– 0/322 of scanned sites secured
●
WordPress
– 2/322 v...
01. Secure Communication
What questions do we need to ask to ensure our
communication is secure?
01. Secure Communication
1. Can C overhear what A and B are saying?
BA
C
01. Secure Communication
2. Is A sure s/he is talking to B and C isn't
standing in the middle?
BA C
01. Secure Communication
3. Does A trust B not to tell C?
BA C
01. Secure Communication
● Certificate file sourced from https://github.com/guzzle/guzzle/blob/master/src/cacert.pem
● dis...
01. Personality
Daniel Lowrey (@rdlowrey)
PHP SSL/TLS Contributor
Saving us from ourselves
Itotallygotpermissiontousethisp...
02. Hosting
●
phpclasses.org
●
sourceforge.net
●
pear.php.net
●
bitbucket.org
●
github.com
02. Hosting
●
phpclasses.org - FUCK NO!
●
sourceforge.net - HELL NO!
●
pear.php.net - No
●
bitbucket.org - No
●
github.com...
03. Managing your source
●
Source control (already determined)
●
Version
●
License
03. Credentials
●
.gitignore to exclude sensitive data
●
If you've pushed sensitive data to github,
change your credential...
03. Licensing
●
MIT
– Do whatever you want with it
– Must attribute
– Don't blame me if it causes a zombie outbreak
●
Apac...
03. Versioning
MAJOR.MINOR.PATCH-STABILITY
●
Breaking backward compatibility? Increase MAJOR
●
Adding backwards compatible...
04. Package Management
04. Package Management
●
PEAR
– No space for alternatives
– High requirement levels
– Package signing
●
Composer
– Easy to...
04. Package Management
●
PEAR - NO
– No space for alternatives
– High requirement levels
– Package signing
●
Composer - YE...
04. Composer
$ mkdir safebrowser && cd safebrowser
$ curl -s http://getcomposer.org/installer | php
#!/usr/bin/env php
All...
04. Composer
$ php composer.phar init
Welcome to the Composer config generator
This command will guide you through creatin...
04. Composer
{
"name": "xsist10/safebrowser",
"description": "Google SafeBrowser Client",
"license": "MIT",
"authors": [
{...
04. Composer
$ php composer.phar install
Loading composer repositories with package
information
Installing dependencies (i...
04. Don't commit vendor/
# Your code
src/[Your Library]
vendor/[Dependencies]
$ echo "vendor" >> .gitignore
# Someone usin...
04. Composer
$ mkdir src
$ vi src/SafeBrowsing.php
<?php
namespace xsist10SafeBrowsing;
class SafeBrowsing {
public functi...
04. Composer
<?php
require 'vendor/autoload.php';
use xsist10SafeBrowsingSafeBrowsing;
$safeBrowsing = new SafeBrowsing($a...
04. List on Packagist
04. List on Packagist
$ php composer.phar require xsist10/safebrowser=dev-master
04. Setup Webhook
04. Setup Webhook
04. Setup Webhook
04. Setup Webhook
04. Package Signing
●
Currently being implemented in Composer
– https://github.com/composer/composer/pull/2814
●
Ensure th...
04. Package Signing
# When you first setup your project
$ php composer.phar create-keys --directory /path/
--prefix=mykey ...
04. Version
04. Personality
Pádraic Brady (@padraicb)
Zend Framework / Composer contributor
Working on the signing code
Thisguyissoawe...
05. Design Patterns
●
Increase flexibility without having to modify
the library code
●
Provide rules on how to extend
05. Strategy
05. Strategy
<?php
namespace xsist10SafeBrowsingStrategy;
interface Strategy
{
public function execute($url, $param);
}
ht...
05. Strategy
<?php
namespace xsist10SafeBrowsingStrategy;
class Get implements Strategy {
public function execute($url, $p...
05. Strategy
<?php
namespace xsist10SafeBrowsingStrategy;
class Post implements Strategy {
public function execute($url, $...
05. Strategy
<?php
require 'vendor/autoload.php';
use xsist10SafeBrowsingSafeBrowsing;
use xsist10SafeBrowsingStrategyGet;...
05. Chain of Responsibility
05. Chain of Responsibility
<?php
namespace xsist10SafeBrowsingStrategy;
use Exception;
class UnavailableException extends...
05. Chain of Responsibility
<?php
namespace xsist10SafeBrowsingStrategy;
class Get implements Strategy {
public function e...
05. Chain of Responsibility
<?php
namespace xsist10SafeBrowsingStrategy;
class Post implements Strategy {
public function ...
05. Chain of Responsibility
<?php
namespace xsist10SafeBrowsing;
use xsist10SafeBrowsingStrategyStrategy;
class Chain impl...
05. Put the chain links together
<?php
// ...
use xsist10SafeBrowsingChain;
$chain = new Chain();
$chain->append(new Post(...
05. The start of something
beautiful
<?php
// ...
use SomeOtherGuySomeOtherPackageCache;
$chain = new Chain();
$chain->app...
05. Personality
Martin Fowler (@martinfowler)
Design Pattern Tamer
http://www.martinfowler.com/
Hegetssuperpowersfromhishat
So what next?
Shamelessly copied from http://thephpleague.com/
●
Follow PSR-2, we use League as our PSR-0 namespace.
●
Lis...
06. Why Tests?
●
You will always find bugs
●
Confidence in libraries
●
Prevent regressions
●
Ensure new features have been...
06. PHPUnit
$ php composer.phar require --dev phpunit/phpunit=4.0.*@dev
./composer.json has been updated
Loading composer ...
06. PHPUnit
$ vi phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
convertErrorsToExceptio...
06. PHPUnit
$ vi phpunit.xml$ ./vendor/bin/phpunit
PHPUnit 4.0.13 by Sebastian Bergmann.
Configuration read from /path/to/...
06. First Tests
use xsist10SafeBrowsingSafeBrowsing;
use xsist10SafeBrowsingStrategyChain;
class SafeBrowsingTest extends ...
06. First Tests
public function testSecure()
{
$mock = $this->getMockBuilder(
'xsist10SafeBrowsingStrategyChain',
['execut...
06. First Tests
$ vi phpunit.xml$ ./vendor/bin/phpunit
PHPUnit 4.0.13 by Sebastian Bergmann.
Configuration read from /path...
06. Testing Resources
●
Can't mock out resources
●
Wrap resources in class and mock the class
●
Wait! Don't write from scr...
06. cURL wrapper
$ ./composer.phar search curl
ext-curl The curl PHP extension
lib-curl The curl PHP library
kdyby/curl Cu...
06. cURL wrapper
$ php composer.phar require shuber/curl=dev-master
./composer.json has been updated
Loading composer repo...
06. Personality
Chris Hartjes (@grmpyprogrammer)
Testing advocate
Being grumpy... so we don't have to
Itotallydidn'tgetper...
06. Personality
Howhereactstoalackoftests.
07. Code Coverage
●
Ensure you test all use cases
●
Useful to spot code smell
●
Helpful in identifying dead/unreachable co...
07. Coverage Report
<phpunit ...>
...
<logging>
<log type="coverage-html" target="build/report"
charset="UTF-8" highlight=...
07. Coverage Report
07. Coverage Report
07. Coverage Report
07. Ignore coverage
●
Ignore whole class/function
– @codeCoverageIgnore
●
Ignore certain lines of code
– // @codeCoverageI...
08. Continuous Integration
●
Make sure your development branch is always
in a deployable state.
●
Ingredients: Tests, High...
08. Travis-CI
language: php
before_script:
- wget http://getcomposer.org/composer.phar
- php composer.phar install --dev
p...
08. CLI Tools
●
Copy paste detector
●
Code Sniffer
●
Mess Detector
●
And lots more at http://phpqatools.org/
07 – Copy/paste detector
$ php composer.phar require --dev sebastian/phpcpd=dev-master
./composer.json has been updated
Lo...
08. Code Sniffer
$ php composer.phar require --dev
squizlabs/php_codesniffer=dev-master
./composer.json has been updated
L...
08. Select a Standard
$ ./vendor/bin/phpcs --standard=PSR2 src/
FILE: /path/to/project/SafeBrowsing/src/SafeBrowsing.php
-...
08. Custom Standard
$ ./vendor/bin/phpcs --standard=/path/to/own/standard src/
FILE: /path/to/project/SafeBrowsing/src/Saf...
08. Mess Detector
$ php composer.phar require --dev phpmd/phpmd=1.4.*
./composer.json has been updated
Loading composer re...
08. Taking it further
●
Jenkins
– http://jenkins-ci.org/
– Automate all the things
●
Behat
– http://behat.org/
– Cucumber ...
08. Behat and Mink
Feature: Test the login page
In order to ensure that customer can use our system
I need to make sure th...
09. Flair
●
General badges (versions, license, etc)
– https://poser.pugx.org/
●
Build status
– https://travis-ci.org
●
Cod...
10. Engage
●
Write a useful README.md
– First thing you see on Github
– How to install
– How to use
10. Engage with developers
●
Encourage fork/pull requests
– Make sure they add tests
– Make sure the old tests still pass
...
10. Engage with developers
●
Promote your library
– Twitter?
– Google Plus?
– I have no idea. I'm still figuring this out....
Homework
●
Docblocks
●
phing/ant to automate CLI tools
●
Git pre-commit hooks to run tests
Social Awareness
Too many pasty white guys
@phpwomen
http://phpwomen.org/
Questions?
Twitter: @thomas_shone
Github: https://github.com/xsist10
https://github.com/xsist10/SafeBrowsing
Nächste SlideShare
Wird geladen in …5
×

PHP SA 2014 - Releasing Your Open Source Project

1.668 Aufrufe

Veröffentlicht am

Learn about how to write open source libraries people won't (completely) hate.

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

PHP SA 2014 - Releasing Your Open Source Project

  1. 1. Releasing Your Open Source Project How to write libraries people won't (completely) hate By @thomas_shone
  2. 2. WARNING ● Opinionated ● Rambling ● Foul-Mouthed ● Ugly Slides ● Don't feed after midnight
  3. 3. 00. Introduction ● No formal education in PHP ● Learnt PHP the hard way ● This talk is about the process ● Connect with personalities
  4. 4. 00. Introduction
  5. 5. 00. Introduction <?php function isUrlSafe($api_key, $url) { if (!filter_var($url, FILTER_VALIDATE_URL)) { throw new Exception('Invalid URL specified.') } $api_uri = 'https://sb-ssl.google.com/' . 'safebrowsing/api/lookup?client=api&apikey=' . $api_key . '&appver=1.0&pver=3.0&url=' . urlencode($url); $result = file_get_contents($api_uri); return strpos($result, 'malware') === false && strpos($result, 'phishing') === false; } When you've finished reading this code, touch your nose so I know when everyone is done.
  6. 6. 10. Security ● Shouldn't be left till last ● Unsure of how to do it properly ● Worst thing that can happen to insecure open source code is it becomes popular
  7. 7. 10. Security ● Shouldn't be left till last ● Unsure of how to do it properly ● Worst thing that can happen to insecure open source code is it becomes popular
  8. 8. 01. Security ● Shouldn't be left till last ● Unsure of how to do it properly ● Worst thing that can happen to insecure open source code is it becomes popular
  9. 9. 01. Security ● Joomla! – 5/133 versions secure – 85 vulnerabilities – 0/322 of scanned sites secured ● WordPress – 2/322 versions secure – 54 vulnerabilities – 313/589 of scanned sites secure
  10. 10. 01. Secure Communication What questions do we need to ask to ensure our communication is secure?
  11. 11. 01. Secure Communication 1. Can C overhear what A and B are saying? BA C
  12. 12. 01. Secure Communication 2. Is A sure s/he is talking to B and C isn't standing in the middle? BA C
  13. 13. 01. Secure Communication 3. Does A trust B not to tell C? BA C
  14. 14. 01. Secure Communication ● Certificate file sourced from https://github.com/guzzle/guzzle/blob/master/src/cacert.pem ● disable_compression only available in PHP 5.4.13+ (prevents CRIME/BREACH attacks) ● Not required with PHP 5.6+ thanks to this guy... $context = stream_context_create([ 'ssl' => [ 'verify_peer' => true, 'verify_depth' => 5, 'cafile' => 'cacert.pem', 'CN_match' => 'sb-ssl.google.com', 'disable_compression' => true, ] ]); $result = file_get_contents($api_uri, false, $context);
  15. 15. 01. Personality Daniel Lowrey (@rdlowrey) PHP SSL/TLS Contributor Saving us from ourselves Itotallygotpermissiontousethisphoto
  16. 16. 02. Hosting ● phpclasses.org ● sourceforge.net ● pear.php.net ● bitbucket.org ● github.com
  17. 17. 02. Hosting ● phpclasses.org - FUCK NO! ● sourceforge.net - HELL NO! ● pear.php.net - No ● bitbucket.org - No ● github.com - Yes
  18. 18. 03. Managing your source ● Source control (already determined) ● Version ● License
  19. 19. 03. Credentials ● .gitignore to exclude sensitive data ● If you've pushed sensitive data to github, change your credentials asap https://help.github.com/articles/remove-sensitive-data Don't be that guy
  20. 20. 03. Licensing ● MIT – Do whatever you want with it – Must attribute – Don't blame me if it causes a zombie outbreak ● Apache – Same as MIT – contributors grants patent rights to users ● GPL – Must release any changes or improvements – Can't change license – Ditto with the zombies http://choosealicense.com/
  21. 21. 03. Versioning MAJOR.MINOR.PATCH-STABILITY ● Breaking backward compatibility? Increase MAJOR ● Adding backwards compatible feature? Increase MINOR ● Adding bugfix? Increase PATCH ● Not production ready? Add stability value (alpha, beta, preview) http://semver.org/
  22. 22. 04. Package Management
  23. 23. 04. Package Management ● PEAR – No space for alternatives – High requirement levels – Package signing ● Composer – Easy to install/update dependencies – Version locking – Autoloading – Your package becomes smaller – Package signing (almost) – Doubles as a distribution platform (https://packagist.org )
  24. 24. 04. Package Management ● PEAR - NO – No space for alternatives – High requirement levels – Package signing ● Composer - YES – Easy to install/update dependencies – Version locking – Autoloading – Your package becomes smaller – Package signing (almost) – Doubles as a distribution platform (https://packagist.org )
  25. 25. 04. Composer $ mkdir safebrowser && cd safebrowser $ curl -s http://getcomposer.org/installer | php #!/usr/bin/env php All settings correct for using Composer Downloading... Composer successfully installed to: /home/project/composer.phar Use it: php composer.phar
  26. 26. 04. Composer $ php composer.phar init Welcome to the Composer config generator This command will guide you through creating your composer.json config. Package name (<vendor>/<name>) [thomas/project]:xsist10/SafeBrowsing Description []: Google Safe Browsing Client Author [Thomas Shone <xsist10@gmail.com>]: Minimum Stability []: License []: MIT
  27. 27. 04. Composer { "name": "xsist10/safebrowser", "description": "Google SafeBrowser Client", "license": "MIT", "authors": [ { "name": "Thomas Shone", "email": "xsist10@gmail.com" } ], "require": { }, "autoload": { "psr-4": { "xsist10SafeBrowsing": "src/" } } }
  28. 28. 04. Composer $ php composer.phar install Loading composer repositories with package information Installing dependencies (including require-dev) Nothing to install or update Generating autoload files $ vi index.php <?php require 'vendor/autoload.php';
  29. 29. 04. Don't commit vendor/ # Your code src/[Your Library] vendor/[Dependencies] $ echo "vendor" >> .gitignore # Someone using your library src/[Their Project Code] vendor/xsist10/SafeBrowsing/[Your Library] vendor/[Your Library Dependencies] vendor/[Their Dependencies] Some of these might be the same # You don't want this vendor/xsist10/SafeBrowsing/[Your Library]/vendor/
  30. 30. 04. Composer $ mkdir src $ vi src/SafeBrowsing.php <?php namespace xsist10SafeBrowsing; class SafeBrowsing { public function __construct($api_key) { $this->api_key = $api_key; } public function isUrlSafe($url) { // ... } }
  31. 31. 04. Composer <?php require 'vendor/autoload.php'; use xsist10SafeBrowsingSafeBrowsing; $safeBrowsing = new SafeBrowsing($api_key); $safeBrowsing->isUrlSafe('www.example.com');
  32. 32. 04. List on Packagist
  33. 33. 04. List on Packagist $ php composer.phar require xsist10/safebrowser=dev-master
  34. 34. 04. Setup Webhook
  35. 35. 04. Setup Webhook
  36. 36. 04. Setup Webhook
  37. 37. 04. Setup Webhook
  38. 38. 04. Package Signing ● Currently being implemented in Composer – https://github.com/composer/composer/pull/2814 ● Ensure that the package you're installing hasn't been tampered with, like: – Ruby Gem installs – PEAR libraries – Linux packages (deb, rpm, yum) – Windows binaries
  39. 39. 04. Package Signing # When you first setup your project $ php composer.phar create-keys --directory /path/ --prefix=mykey --passphrase passphrase to encrypt the private key: $ php composer.phar add-dev-key /path/mykey-private.pem $ php composer.phar sign-dev-keys /path/mykey-private.pem # Last thing you do before you release a new version $ php composer.phar sign /path/mykey-private.pem Enter a passphrase if the private key is encrypted: $ git commit -m “Updated keys” keys.json manifest.json $ git push # Tag you release immediately
  40. 40. 04. Version
  41. 41. 04. Personality Pádraic Brady (@padraicb) Zend Framework / Composer contributor Working on the signing code Thisguyissoawesomethattheinternetcan't containpicturesofhim.
  42. 42. 05. Design Patterns ● Increase flexibility without having to modify the library code ● Provide rules on how to extend
  43. 43. 05. Strategy
  44. 44. 05. Strategy <?php namespace xsist10SafeBrowsingStrategy; interface Strategy { public function execute($url, $param); } https://en.wikipedia.org/wiki/Strategy_pattern
  45. 45. 05. Strategy <?php namespace xsist10SafeBrowsingStrategy; class Get implements Strategy { public function execute($url, $param) { $context = stream_context_create([ 'ssl' => [ 'verify_peer' => true, 'cafile' => 'path/to/cafile', 'CN_match' => 'sb-ssl.google.com' ] ]); $query = $url . '?' . http_build_query($param); return file_get_contents($query, false, $context); } }
  46. 46. 05. Strategy <?php namespace xsist10SafeBrowsingStrategy; class Post implements Strategy { public function execute($url, $param) { // Do some curl init stuff ... // Do your security! curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl, CURLOPT_CAINFO, 'path/to/cafile'); $result = curl_exec($curl); $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); // check some result checks first ... return $result; } }
  47. 47. 05. Strategy <?php require 'vendor/autoload.php'; use xsist10SafeBrowsingSafeBrowsing; use xsist10SafeBrowsingStrategyGet; $sb = new SafeBrowsing($api_key, new Get()); $sb->isUrlSafe('www.example.com'); use xsist10SafeBrowsingStrategyPost; $sb = new SafeBrowsing($api_key, new Post()); $sb->isUrlSafe('www.example.com');
  48. 48. 05. Chain of Responsibility
  49. 49. 05. Chain of Responsibility <?php namespace xsist10SafeBrowsingStrategy; use Exception; class UnavailableException extends Exception {} https://en.wikipedia.org/wiki/Strategy_pattern
  50. 50. 05. Chain of Responsibility <?php namespace xsist10SafeBrowsingStrategy; class Get implements Strategy { public function execute($url, $param) { if (!ini_get('allow_url_fopen')) { throw new UnavailableException(); } // ... } }
  51. 51. 05. Chain of Responsibility <?php namespace xsist10SafeBrowsingStrategy; class Post implements Strategy { public function execute($url, $param) { if (!function_exists('curl_init')) { throw new UnavailableException(); } // ... } }
  52. 52. 05. Chain of Responsibility <?php namespace xsist10SafeBrowsing; use xsist10SafeBrowsingStrategyStrategy; class Chain implements Strategy { public function append(Strategy $strat) { $this->chain[] = $strat; } public function execute($url, $param) { foreach ($this->chain as $strategy) { try { return $strategy->get($url, $param); } catch (UnavailableException $exception) { // We can ignore and move to the next } } throw new Exception('No available strategy.'); } }
  53. 53. 05. Put the chain links together <?php // ... use xsist10SafeBrowsingChain; $chain = new Chain(); $chain->append(new Post()); $chain->append(new Get()); $sb = new SafeBrowsing($api_key, $chain); $sb->isUrlSafe('www.example.com'); // This still works $sb = new SafeBrowsing($api_key, new Get()); $sb->isUrlSafe('www.example.com');
  54. 54. 05. The start of something beautiful <?php // ... use SomeOtherGuySomeOtherPackageCache; $chain = new Chain(); $chain->append(new Cache()); $chain->append(new Post()); $chain->append(new Get()); $sb = new SafeBrowsing($api_key, $chain); $sb->isUrlSafe('www.example.com');
  55. 55. 05. Personality Martin Fowler (@martinfowler) Design Pattern Tamer http://www.martinfowler.com/ Hegetssuperpowersfromhishat
  56. 56. So what next? Shamelessly copied from http://thephpleague.com/ ● Follow PSR-2, we use League as our PSR-0 namespace. ● List on Packagist, we list with league as the vendor namespace. ● Shove code in a src folder. ● Write unit tests. Aim for at least 80% coverage for v1.0. ● DocBlock all the things. ● Semantic versioning must be used to manage version numbers. ● Use Travis-CI to automatically check coding standards and run tests. ● Have an extensive README.
  57. 57. 06. Why Tests? ● You will always find bugs ● Confidence in libraries ● Prevent regressions ● Ensure new features have been thoroughly vetted
  58. 58. 06. PHPUnit $ php composer.phar require --dev phpunit/phpunit=4.0.*@dev ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) ... - Installing phpunit/phpunit (4.0.x-dev fca5bc6) Cloning fca5bc6a50d09b26db280c5cc3c84978c9cace3f phpunit/phpunit suggests installing phpunit/php-invoker (~1.1) Writing lock file Generating autoload files
  59. 59. 06. PHPUnit $ vi phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" convertErrorsToExceptions="true" convertWarningsToExceptions="true" convertNoticesToExceptions="true" mapTestClassNameToCoveredClassName="true" bootstrap="vendor/autoload.php" strict="true" verbose="true" colors="true"> <testsuites> <testsuite> <directory>./tests</directory> </testsuite> </testsuites> </phpunit> $ mkdir tests $ vi phpunit.xml
  60. 60. 06. PHPUnit $ vi phpunit.xml$ ./vendor/bin/phpunit PHPUnit 4.0.13 by Sebastian Bergmann. Configuration read from /path/to/project/phpunit.xml Time: 116 ms, Memory: 2.00Mb No tests executed!
  61. 61. 06. First Tests use xsist10SafeBrowsingSafeBrowsing; use xsist10SafeBrowsingStrategyChain; class SafeBrowsingTest extends PHPUnit_Framework_TestCase { public function testInvalidUrl() { $chain = new Chain(); $safeBrowsing = new SafeBrowsing('', $chain); $message = 'Invalid URL specified.'; $this->setExpectedException('Exception', $message); $safeBrowsing->isUrlSafe('invalid-url'); } } $ vi tests/SafeBrowsingTest.php
  62. 62. 06. First Tests public function testSecure() { $mock = $this->getMockBuilder( 'xsist10SafeBrowsingStrategyChain', ['execute'] )->getMock(); // API returns an empty result if the site is secure $mock->expects($this->once()) ->method('execute') ->will($this->returnValue('')); $safeBrowsing = new SafeBrowsing('', $mock); $url = 'http://www.google.com'; $response = $safeBrowsing->isUrlSafe($url); $this->assertTrue($response); }
  63. 63. 06. First Tests $ vi phpunit.xml$ ./vendor/bin/phpunit PHPUnit 4.0.13 by Sebastian Bergmann. Configuration read from /path/to/project/phpunit.xml ..... Time: 568 ms, Memory: 4.00Mb OK (5 tests, 9 assertions)
  64. 64. 06. Testing Resources ● Can't mock out resources ● Wrap resources in class and mock the class ● Wait! Don't write from scratch. Use your package manager!
  65. 65. 06. cURL wrapper $ ./composer.phar search curl ext-curl The curl PHP extension lib-curl The curl PHP library kdyby/curl Curl wrapper for Nette Framework shuber/curl PHP Wrapper for Curl comvi/curl Work with remote servers via cURL much easier than using the native PHP bindings. anlutro/curl Simple OOP cURL wrapper. jyggen/curl A simple and lightweight cURL library with support for multiple requests in parallel. bca/curl cURL wrapper for PHP applications. unikent/curl Laravel Curl Helper Library. mogetutu/curl Simple Curl PHP Helper Library sweelix/curl PHP 5.3+ simple curl requestor lib/curl A simple cURL wrapper for PHP dvelopment/curl PHP OOP wrapper for cURL requests php-curl-class/php-curl-class PHP Curl Class is an object-oriented wrapper of the PHP cURL extension.
  66. 66. 06. cURL wrapper $ php composer.phar require shuber/curl=dev-master ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing shuber/curl (dev-master 6624992) Cloning 6624992df201f9fd7262080117385dd09b0ecd2b Writing lock file Generating autoload files
  67. 67. 06. Personality Chris Hartjes (@grmpyprogrammer) Testing advocate Being grumpy... so we don't have to Itotallydidn'tgetpermissiontousethisphoto
  68. 68. 06. Personality Howhereactstoalackoftests.
  69. 69. 07. Code Coverage ● Ensure you test all use cases ● Useful to spot code smell ● Helpful in identifying dead/unreachable code ● Improves confidence in library
  70. 70. 07. Coverage Report <phpunit ...> ... <logging> <log type="coverage-html" target="build/report" charset="UTF-8" highlight="false" LowUpperBound="35" HighLowerBound="70" /> </logging> <filter> <whitelist> <directory>src</directory> </whitelist> </filter> </phpunit> $ echo “build” >> .gitignore $ vi phpunit.xml
  71. 71. 07. Coverage Report
  72. 72. 07. Coverage Report
  73. 73. 07. Coverage Report
  74. 74. 07. Ignore coverage ● Ignore whole class/function – @codeCoverageIgnore ● Ignore certain lines of code – // @codeCoverageIgnoreStart – // @codeCoverageIgnoreEnd ● Use responsibly
  75. 75. 08. Continuous Integration ● Make sure your development branch is always in a deployable state. ● Ingredients: Tests, High Coverage, Automation
  76. 76. 08. Travis-CI language: php before_script: - wget http://getcomposer.org/composer.phar - php composer.phar install --dev php: - 5.5 - 5.4 - hhvm script: phpunit $ vi .travis.yml
  77. 77. 08. CLI Tools ● Copy paste detector ● Code Sniffer ● Mess Detector ● And lots more at http://phpqatools.org/
  78. 78. 07 – Copy/paste detector $ php composer.phar require --dev sebastian/phpcpd=dev-master ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing sebastian/phpcpd (dev-master a946215) Cloning a9462153f2dd90466a010179901d31fbff598365 Writing lock file Generating autoload files $ ./vendor/bin/phpcpd src/ phpcpd 2.0.1 by Sebastian Bergmann. 0.00% duplicated lines out of 195 total lines of code. Time: 32 ms, Memory: 2.75Mb
  79. 79. 08. Code Sniffer $ php composer.phar require --dev squizlabs/php_codesniffer=dev-master ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing squizlabs/php_codesniffer (dev-master 623905c) Cloning 623905ce571d64a8cb873826d47b81321cd55011 Writing lock file Generating autoload files $ ./vendor/bin/phpcs -i The installed coding standards are PSR1, PHPCS, Squiz, PEAR, Zend, MySource and PSR2 $ ./vendor/bin/phpcs --standard=PSR2 src/ [WALL OF TEXT]
  80. 80. 08. Select a Standard $ ./vendor/bin/phpcs --standard=PSR2 src/ FILE: /path/to/project/SafeBrowsing/src/SafeBrowsing.php ------------------------------------------------------------------- FOUND 3 ERROR(S) AFFECTING 2 LINE(S) ------------------------------------------------------------------- 17 | ERROR | Opening brace should be on a new line 22 | ERROR | Visibility must be declared on method "isUrlSafe" 22 | ERROR | Opening brace should be on a new line ------------------------------------------------------------------- [WALL OF TEXT OMITTED]
  81. 81. 08. Custom Standard $ ./vendor/bin/phpcs --standard=/path/to/own/standard src/ FILE: /path/to/project/SafeBrowsing/src/SafeBrowsing.php ------------------------------------------------------------------- FOUND 1 ERROR(S) AFFECTING 1 LINE(S) ------------------------------------------------------------------- 1 | ERROR | Homage to Cthulhu missing from doc header -------------------------------------------------------------------
  82. 82. 08. Mess Detector $ php composer.phar require --dev phpmd/phpmd=1.4.* ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing phpmd/phpmd (1.4.1) Downloading: 100% Writing lock file Generating autoload files $ ./vendor/bin/phpmd src text codesize,unusedcode,naming,design Strategy/Get.php:9 Classes should not have a constructor method with the same name as the class
  83. 83. 08. Taking it further ● Jenkins – http://jenkins-ci.org/ – Automate all the things ● Behat – http://behat.org/ – Cucumber syntax – Mink extension for website testing – Write human-readable use cases
  84. 84. 08. Behat and Mink Feature: Test the login page In order to ensure that customer can use our system I need to make sure that they can log in successfully Scenario: Can I log in with valid details Given I am on the “www.mywebsite.com” When I click on “Login” And I fill “username” with “bob” And I fill “password” with “Password1” And I press “Login” Then I should see “Login Successful”
  85. 85. 09. Flair ● General badges (versions, license, etc) – https://poser.pugx.org/ ● Build status – https://travis-ci.org ● Code Coverage – https://coveralls.io ● Code Analysis – https://insight.sensiolabs.com/analyses – https://scrutinizer-ci.com/
  86. 86. 10. Engage ● Write a useful README.md – First thing you see on Github – How to install – How to use
  87. 87. 10. Engage with developers ● Encourage fork/pull requests – Make sure they add tests – Make sure the old tests still pass – Travis-CI makes this simple
  88. 88. 10. Engage with developers ● Promote your library – Twitter? – Google Plus? – I have no idea. I'm still figuring this out. I'm a developer dammit!
  89. 89. Homework ● Docblocks ● phing/ant to automate CLI tools ● Git pre-commit hooks to run tests
  90. 90. Social Awareness Too many pasty white guys @phpwomen http://phpwomen.org/
  91. 91. Questions? Twitter: @thomas_shone Github: https://github.com/xsist10 https://github.com/xsist10/SafeBrowsing

×