Top Banner
THE STATE OF PHPUNIT Volker Dusch / @__edorian
72

the state of phpunit - FrOSCon Program

Feb 11, 2022

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: the state of phpunit - FrOSCon Program

THE STATE OF PHPUNITVolker Dusch / @__edorian

Page 2: the state of phpunit - FrOSCon Program

ABOUT MEPHP since 10 yearsCICleanCodeDevOpsTDDShipping

Page 3: the state of phpunit - FrOSCon Program
Page 4: the state of phpunit - FrOSCon Program

GET IN TOUCH

stackoverflow: Twitter: @__edorianXing / G+: Volker DuschIRC: edorianMail: [email protected]

Page 5: the state of phpunit - FrOSCon Program

LET'S GO

Page 6: the state of phpunit - FrOSCon Program

Unit testing in PHP got mainstream

Page 7: the state of phpunit - FrOSCon Program

THAT'S A GOOD THING!Unit testing got "normal" in PHP

Even people that don't really know PHP or even the CLI know that theyshould write unit tests.

Page 8: the state of phpunit - FrOSCon Program

AGENDACurrent StatePHPUnit.nextThe EcoSystemAnnoying things we got rid ofFeatures you might have missedUpcoming stuffTest suite organizationDiscussion

Page 9: the state of phpunit - FrOSCon Program

CURRENT STATEVersion: 3.6.12Over 60 contributors since 3.6.0Deep into the 3.6 Bugfix cycle, no new features will be added. Thosego into .nextFrench docs thanks to @poum and still current Japanese docs thanksto @m-takagi!If you want to help out:https://github.com/sebastianbergmann/phpunit/#contributing

Page 10: the state of phpunit - FrOSCon Program

PHPUNIT.NEXTNext up: 3.715+ features10+ issues fixedDetails later

Page 11: the state of phpunit - FrOSCon Program

BCDid you like upgrading to PHPUnit 3.6?

Page 12: the state of phpunit - FrOSCon Program

BC FREE-ISHWe are trying really hard to not introduce any BC breaks.

Test listeners trigger one autoload callcwd gets restored after test caseparameter cloning behaviorRemoved deprecated OutputTestCaseand that's it

Page 13: the state of phpunit - FrOSCon Program

THE ECOSYSTEMhttp://phpqatools.org/ & friends

Page 14: the state of phpunit - FrOSCon Program

BDDUse Behat, It's great!

We're not going to remove the BDD stuff in PHPUnit but It's not beingworked on.

Page 15: the state of phpunit - FrOSCon Program

WEB INTERFACE?Not sure why you'd want that but someone solved that for you

https://github.com/NSinopoli/VisualPHPUnit

Page 16: the state of phpunit - FrOSCon Program

MOCKING IS UGLY!Real world problems and solutions:

http://stackoverflow.com/search?tab=votes&q=[phpunit] mock

Page 17: the state of phpunit - FrOSCon Program

MOCKERYTry it! It's great.

Afraid it might be hard to set up and use?

Look into https://github.com/etsy/phpunit-extensions/wiki/Mockery

Works with strict mode, leaves the old API intact and is as easy aswriting a comment:

class MyTest extends PHPUnit_Extensions_Mockery_TestCase {

/** @mockery Foo */ protected $foo;

}

Page 18: the state of phpunit - FrOSCon Program

LOTS OF LEGACY CODE?Or whatever "hard to test" is called these days.

https://github.com/lapistano/proxy-object

One of the main purpose of this library is to expose invisible (private orprotected) methods and properties to the SUT.

Page 19: the state of phpunit - FrOSCon Program

TESTING WEB SERVICESUnit and Integration test web services with the same code?

Try wsUnit https://github.com/lapistano/wsunit

Page 20: the state of phpunit - FrOSCon Program

IDE SUPPORTNetbeans support improved and they adopted the skeleton-generatorHonestly I have no clue about eclipsePHPStorm has really beautiful coverage support by nowvim user? :!phpunit --coverage-text

Page 21: the state of phpunit - FrOSCon Program

JENKINSJenkins template: jenkins-php.orgclover php plugin

Page 22: the state of phpunit - FrOSCon Program

TRAVIS CIAwesome for GitHub and collaborationEveryone has the way to run their tests documented by nowNo really CI but a very cool test runnerUse --coverage-text if you want to show off :)

Page 23: the state of phpunit - FrOSCon Program

COMPOSERLast week:

When someone does the work it it will happenThis week:

Someone did.Current status at

https://github.com/sebastianbergmann/phpunit/issues/522

Page 24: the state of phpunit - FrOSCon Program
Page 25: the state of phpunit - FrOSCon Program

PHARThe PHP tool format

We still have issues with process-isolation and figuring out the nicestway to maintain and build the phars.

Hopefully the 3.7 alpha will also feature a 3.6 & 3.7 phar.

Page 26: the state of phpunit - FrOSCon Program

PHPUNIT-SELENIUMNow maintained by @giorgiosironiCode coverage support

If you ask me: Don't drive your web tests with phpunit.

Use Behat or something non php.

Page 27: the state of phpunit - FrOSCon Program

ANNOYING THINGS WE GOTRID OF

Page 28: the state of phpunit - FrOSCon Program

@ BLOCKWhen using process-isolation PHPUnit won't die silently when

unserializing of the test result fails.

Page 29: the state of phpunit - FrOSCon Program

CLI ARGUMENT PARSING

This only executed TestA. Now it gives you an error message that youare doing it wrong.

phpunit TestA TestA.php TestB TestB.php

Page 30: the state of phpunit - FrOSCon Program

HEY, LISTEN!Test listeners now trigger one autoload call instead of being silently

ignored when the class was not loaded.

Page 31: the state of phpunit - FrOSCon Program

EXCEPTIONALImproved reporting of exceptions...

because it only told you...

but now...

public function testNestedExceptions(){ $e3 = new Exception('Three'); $e2 = new InvalidArgumentException('Two', 0, $e3); $e1 = new Exception('One', 0, $e2); throw $e1;}

ExceptionStackTest::testNestedExceptionsException: One

[trace]

Page 32: the state of phpunit - FrOSCon Program

EXCEPTIONAL...we are printing out the previous exception names, messages and

traces.

ExceptionStackTest::testNestedExceptionsException: One

[trace]

Caused byInvalidArgumentException: Two

[trace]

Caused byException: Three

[trace]

Page 33: the state of phpunit - FrOSCon Program

?????????????????Fixed an annoying crash when using --process-isolation with PHP 5.3

and detect_unicode=on.

Page 34: the state of phpunit - FrOSCon Program

EVEN MORE EXCEPTIONAL

Works again!

@expectedException \Exception

Page 35: the state of phpunit - FrOSCon Program

ONE MORE THING

That one is still alive. Sorry ;)

It just means that PHPUnit can't find any tests.

Fatal error: Uncaught exception 'PHPUnit_Framework_Exception' with message 'Neither "tests.php" nor "tests.php" could be opened.' in ...

Page 36: the state of phpunit - FrOSCon Program

FEATURES YOU MIGHT HAVEMISSED

Page 37: the state of phpunit - FrOSCon Program

LINE ENDINGS MISMATCHIssue503Test::testCompareDifferentLineEndingsFailed asserting that two strings are identical.--- Expected+++ Actual@@ @@ #Warning: Strings contain different line endings! foo

Page 38: the state of phpunit - FrOSCon Program

IMPROVED THE JSON LOGIf tests produce output it is now properly included in the log.

Page 39: the state of phpunit - FrOSCon Program

BOOTSTRAP ORDERBootstrap script should be loaded before trying to load

testSuiteLoaderClass.

Page 40: the state of phpunit - FrOSCon Program

PROCESS ISOLATION FOR EVERYONEProcess Isolation did not work when PHPUnit is invoked through

Apache Ant, for instance, due to PHP binary detection issues.

Page 41: the state of phpunit - FrOSCon Program

@EXPECTEDEXCEPTIONCODENow can be 0 or a string.

Useful for PDO

Page 42: the state of phpunit - FrOSCon Program

BINARY MESSBefore it broke your terminal and BEEPed at you

Now it shows a hex dump:

1) FooTest::testFooFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@-+ ☺☻♥♦+♂♀+♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼

Binary String: 0x000102030405.........

Page 43: the state of phpunit - FrOSCon Program

ONE LINE ANNOTATIONSYou can use:

/** @expectedException \FubarException */

Page 44: the state of phpunit - FrOSCon Program

COUNTING ON ITNow working with Countable and Iterator Interfaces:

assertCount()assertAttributeCount()assertNotCount()assertAttributeNotCount()assertSameSize()assertNotSameSize()

Page 45: the state of phpunit - FrOSCon Program

FLUENT INTERFACESA little mock improvement:

->will($this->returnSelf());

Page 46: the state of phpunit - FrOSCon Program

@REQUIRES/** * @requires PHP 5.4 */public function testTrait(){}

Page 47: the state of phpunit - FrOSCon Program

REQUIRES<file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>

Page 48: the state of phpunit - FrOSCon Program

MAGIC SUPPORTassertEquals() now looks for (and invokes) a __toString() method when

an object and string are compared.

Page 49: the state of phpunit - FrOSCon Program

PERFORMANCEsetUpBeforeClass() and tearDownAfterClass() are no longer invoked

when all tests of the class are skipped

Page 50: the state of phpunit - FrOSCon Program

UPCOMING STUFF

Page 51: the state of phpunit - FrOSCon Program

LESS MAGIC NUMBERS@expectedException* now works with constants:

Reduce copy paste testing.

/** * @expectedException Class * @expectedExceptionCode @Class::TEAPOT_MISSING * @expectedExceptionMessage @Class::TEAPOT_MISSING_MESSAGE */

Page 52: the state of phpunit - FrOSCon Program

*TEST.PHP IS TOO MAINSTREAMAdded --test-suffix that allows specifying which filename suffixes are

recognised by PHPUnit.

Helps out some projects with their CI.

I don't see a general use case.

Page 53: the state of phpunit - FrOSCon Program

{"JSON": "YES PLEASE"}We added assertJson* functions that work like the existing assertXml*

functions.

assertJsonFileEqualsJsonFile() assertJsonStringEqualsJsonFile() assertJsonStringEqualsJsonString()

Page 54: the state of phpunit - FrOSCon Program

CALLBACK MATCHERHelps with complex assertions on mocks

It's not pretty but it might solve that one annoying problem:

public function send($message, EndpointConfig $config)

$foo->expects($this->once()) ->method('send') ->with( $this->equalTo('syn'), $this->callback( function ($config) { $url = $config->getUrl(); if(!$url) { throw new Exception('....'); } return $url->getHost() === 'http://example.com'; } ) );

Page 55: the state of phpunit - FrOSCon Program

OO-ARRAYS

Now work with objects that implement ArrayAccess.

assertArrayHasKey()assertArrayNotHasKey()

Page 56: the state of phpunit - FrOSCon Program

PHPUNIT.XSDPHPUnit now provides a configuration.xsd schema file.

http://schema.phpunit.de/configuration.xsd

Useful to validate your phpunit.xml and phpunit.xml.dist configurationfiles.

<?xml version="1.0" encoding="UTF-8"?><phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation ="http://schema.phpunit.de/configuration.xsd" [...]>

Page 57: the state of phpunit - FrOSCon Program

MORE @REQUIRES

Require functions, methods and extensionsMerges Class & Method doc blocksPHP & PHPUnit version get override

/** * @requires PHP 5.4-dev * @requires PHPUnit 3.7-dev * @requires function someFunc * @requires function Class::foo * @requires extension apc * @requires extension mysqli */

Page 58: the state of phpunit - FrOSCon Program

.PHPT IMPROVEMENTS--TEST--

GH-503: assertEquals() Line Ending Differences Are Obscure

--FILE--<?php

$_SERVER['argv'][1] = '--no-configuration';$_SERVER['argv'][2] = 'Issue503Test';$_SERVER['argv'][3] = __DIR__).'/503/Issue503Test.php';

require_once __DIR__ . '/../../../PHPUnit/Autoload.php';PHPUnit_TextUI_Command::main();?>

Page 59: the state of phpunit - FrOSCon Program

.PHPT IMPROVEMENTS--EXPECTF--PHPUnit %s by Sebastian Bergmann.

F

Time: %i %s, Memory: %sMb

There was 1 failure:

1) Issue503Test::testCompareDifferentLineEndingsFailed asserting that two strings are identical.--- Expected+++ Actual@@ @@ #Warning: Strings contain different line endings! foo

%s:%i

FAILURES!Tests: 1, Assertions: 1, Failures: 1.

Page 60: the state of phpunit - FrOSCon Program

.PHPT IMPROVEMENTSBefore 3.7 diffs where really hard to read.

Now the diff will be processed line by line.

Page 61: the state of phpunit - FrOSCon Program

LISTS AND COLLECTIONS

Helper for checking Collection objects and arrays.

Descriptive assertion and error message.

public function testAssertContainsOnlyInstancesOf(){ $library = array( new Book(), new Book() ); $this->assertContainsOnlyInstancesOf( 'Book', $library );}

Page 62: the state of phpunit - FrOSCon Program

FAILED @EXPECTEDEXCEPTION ANNOTATIONSBefore:

Now:

Failed asserting that exception of type "ErrorException" matches expected exception "MyException".

Failed asserting that exception of type "ErrorException" matches expected exception "MyException". Message from "ErrorException" was "undefined variable $htis".

Page 63: the state of phpunit - FrOSCon Program

LESS REQUIRES, LESS CRASHES

People seem to constantly run into issues with code coverage

When enabled, uncovered whitelisted files are processed to properlycalculate the number of executable lines.

If not we take a quite ok guess to get the number of ELOC.

<whitelist addUncoveredFilesFromWhitelist="true">

<whitelist processUncoveredFilesFromWhitelist="true">

Page 64: the state of phpunit - FrOSCon Program

MORE USEFUL GROUPS

Now works as expected

$ phpunit --group FlakyTests

<phpunit> <groups> <exclude> <group>FlakyTests</group> </exclude> </groups> <testsuites ... /></phpunit>

Page 65: the state of phpunit - FrOSCon Program

TEST SUITE ORGANIZATION

Page 66: the state of phpunit - FrOSCon Program

FOLDER LAYOUT?project/ phpunit.xml.dist src/ tests/ bootstrap.php unit/ integation/ functional/ (or system/) helpers/

Page 67: the state of phpunit - FrOSCon Program

TEST DISTRIBUTIONhttp://elblinkin.info/2012/03/goldilocks-on-test-sizes/

Page 68: the state of phpunit - FrOSCon Program

SMALL HINTSUse the xml configuration for pretty much everythingSeparate unit and integration testsYour unit test folders should mirror your applications folderstructureTo only execute specific tests use phpunit --filter or phpunittests/unit/module1Use the strict mode from the get go and never turn it off.Imho: Don't have a test namespace. Nicer to read and showsproduction usage.

Page 69: the state of phpunit - FrOSCon Program

DISCUSSIONIssues?

Feature requests?

Anything I missed?

Page 70: the state of phpunit - FrOSCon Program

THANK YOU

Page 71: the state of phpunit - FrOSCon Program
Page 72: the state of phpunit - FrOSCon Program