PHPUnit 3.5 Upgrading Woes

Sebastian Bergmann » 22 October 2010 » in PHPUnit » 6 Comments

The issues related to upgrading from a previous version to PHPUnit 3.5 that I mentioned in the release announcement are more serious than I initially thought. Only today did I find the time to really investigate the root cause.

Here is the situation before the upgrade:

root@ubuntu:~# pear list
Installed packages, channel pear.php.net:
=========================================
Package          Version State
Archive_Tar      1.3.7   stable
Console_Getopt   1.2.3   stable
PEAR             1.9.1   stable
Structures_Graph 1.0.3   stable
XML_Util         1.2.1   stable
root@ubuntu:~# pear list -c phpunit
Installed packages, channel pear.phpunit.de:
============================================
Package Version State
PHPUnit 3.4.15  stable

As we can see, we have the latest version of PEAR (1.9.1) installed as well as PHPUnit 3.4.15.

Lets have a look at the installed files:

root@ubuntu:~# tree /usr/share/php/PHPUnit
/usr/share/php/PHPUnit
├── Extensions
│   ├── Database
│   │   ├── AbstractTester.php
│   │   ├── Constraint
│   │   │   ├── DataSetIsEqual.php
│   │   │   └── TableIsEqual.php
│   │   ├── DataSet
│   │   │   ├── AbstractDataSet.php
│   │   │   ├── AbstractTableMetaData.php
│   │   │   ├── AbstractTable.php
│   │   │   ├── AbstractXmlDataSet.php
│   │   │   ├── CompositeDataSet.php
│   │   │   ├── CsvDataSet.php
│   │   │   ├── DataSetFilter.php
│   │   │   ├── DefaultDataSet.php
│   │   │   ├── DefaultTableIterator.php
│   │   │   ├── DefaultTableMetaData.php
│   │   │   ├── DefaultTable.php
│   │   │   ├── FlatXmlDataSet.php
│   │   │   ├── IDataSet.php
│   │   │   ├── IPersistable.php
│   │   │   ├── ISpec.php
│   │   │   ├── ITableIterator.php
│   │   │   ├── ITableMetaData.php
│   │   │   ├── ITable.php
│   │   │   ├── Persistors
│   │   │   │   ├── Abstract.php
│   │   │   │   ├── Factory.php
│   │   │   │   ├── FlatXml.php
│   │   │   │   ├── Xml.php
│   │   │   │   └── Yaml.php
│   │   │   ├── QueryDataSet.php
│   │   │   ├── QueryTable.php
│   │   │   ├── ReplacementDataSet.php
│   │   │   ├── ReplacementTableIterator.php
│   │   │   ├── ReplacementTable.php
│   │   │   ├── Specs
│   │   │   │   ├── Csv.php
│   │   │   │   ├── DbQuery.php
│   │   │   │   ├── DbTable.php
│   │   │   │   ├── Factory.php
│   │   │   │   ├── FlatXml.php
│   │   │   │   ├── IFactory.php
│   │   │   │   ├── Xml.php
│   │   │   │   └── Yaml.php
│   │   │   ├── TableFilter.php
│   │   │   ├── TableMetaDataFilter.php
│   │   │   ├── XmlDataSet.php
│   │   │   └── YamlDataSet.php
│   │   ├── DB
│   │   │   ├── DataSet.php
│   │   │   ├── DefaultDatabaseConnection.php
│   │   │   ├── FilteredDataSet.php
│   │   │   ├── IDatabaseConnection.php
│   │   │   ├── IMetaData.php
│   │   │   ├── MetaData
│   │   │   │   ├── InformationSchema.php
│   │   │   │   ├── MySQL.php
│   │   │   │   ├── Oci.php
│   │   │   │   ├── PgSQL.php
│   │   │   │   └── Sqlite.php
│   │   │   ├── MetaData.php
│   │   │   ├── ResultSetTable.php
│   │   │   ├── TableIterator.php
│   │   │   ├── TableMetaData.php
│   │   │   └── Table.php
│   │   ├── DefaultTester.php
│   │   ├── IDatabaseListConsumer.php
│   │   ├── ITester.php
│   │   ├── Operation
│   │   │   ├── Composite.php
│   │   │   ├── DeleteAll.php
│   │   │   ├── Delete.php
│   │   │   ├── Exception.php
│   │   │   ├── Factory.php
│   │   │   ├── IDatabaseOperation.php
│   │   │   ├── Insert.php
│   │   │   ├── Null.php
│   │   │   ├── Replace.php
│   │   │   ├── RowBased.php
│   │   │   ├── Truncate.php
│   │   │   └── Update.php
│   │   ├── TestCase.php
│   │   └── UI
│   │       ├── Command.php
│   │       ├── Context.php
│   │       ├── IMedium.php
│   │       ├── IMediumPrinter.php
│   │       ├── IModeFactory.php
│   │       ├── IMode.php
│   │       ├── InvalidModeException.php
│   │       ├── Mediums
│   │       │   └── Text.php
│   │       ├── ModeFactory.php
│   │       └── Modes
│   │           ├── ExportDataSet
│   │           │   └── Arguments.php
│   │           └── ExportDataSet.php
│   ├── GroupTestSuite.php
│   ├── OutputTestCase.php
│   ├── PerformanceTestCase.php
│   ├── PhptTestCase
│   │   └── Logger.php
│   ├── PhptTestCase.php
│   ├── PhptTestSuite.php
│   ├── RepeatedTest.php
│   ├── SeleniumTestCase
│   │   ├── append.php
│   │   ├── Driver.php
│   │   ├── phpunit_coverage.php
│   │   └── prepend.php
│   ├── SeleniumTestCase.php
│   ├── Story
│   │   ├── Given.php
│   │   ├── ResultPrinter
│   │   │   ├── HTML.php
│   │   │   ├── Template
│   │   │   │   ├── scenario_header.html.dist
│   │   │   │   ├── scenario.html.dist
│   │   │   │   ├── scenarios.html.dist
│   │   │   │   └── step.html.dist
│   │   │   └── Text.php
│   │   ├── ResultPrinter.php
│   │   ├── Scenario.php
│   │   ├── SeleniumTestCase.php
│   │   ├── Step.php
│   │   ├── TestCase.php
│   │   ├── Then.php
│   │   └── When.php
│   ├── TestDecorator.php
│   ├── TicketListener
│   │   └── Trac.php
│   └── TicketListener.php
├── Framework
│   ├── AssertionFailedError.php
│   ├── Assert.php
│   ├── ComparisonFailure
│   │   ├── Array.php
│   │   ├── Object.php
│   │   ├── Scalar.php
│   │   ├── String.php
│   │   └── Type.php
│   ├── ComparisonFailure.php
│   ├── Constraint
│   │   ├── And.php
│   │   ├── ArrayHasKey.php
│   │   ├── Attribute.php
│   │   ├── ClassHasAttribute.php
│   │   ├── ClassHasStaticAttribute.php
│   │   ├── FileExists.php
│   │   ├── GreaterThan.php
│   │   ├── IsAnything.php
│   │   ├── IsEqual.php
│   │   ├── IsFalse.php
│   │   ├── IsIdentical.php
│   │   ├── IsInstanceOf.php
│   │   ├── IsNull.php
│   │   ├── IsTrue.php
│   │   ├── IsType.php
│   │   ├── LessThan.php
│   │   ├── Not.php
│   │   ├── ObjectHasAttribute.php
│   │   ├── Or.php
│   │   ├── PCREMatch.php
│   │   ├── StringContains.php
│   │   ├── StringEndsWith.php
│   │   ├── StringStartsWith.php
│   │   ├── TraversableContainsOnly.php
│   │   ├── TraversableContains.php
│   │   └── Xor.php
│   ├── Constraint.php
│   ├── Error
│   │   ├── Notice.php
│   │   └── Warning.php
│   ├── Error.php
│   ├── Exception.php
│   ├── ExpectationFailedException.php
│   ├── IncompleteTestError.php
│   ├── IncompleteTest.php
│   ├── MockObject
│   │   ├── Builder
│   │   │   ├── Identity.php
│   │   │   ├── InvocationMocker.php
│   │   │   ├── Match.php
│   │   │   ├── MethodNameMatch.php
│   │   │   ├── Namespace.php
│   │   │   ├── ParametersMatch.php
│   │   │   └── Stub.php
│   │   ├── Generator
│   │   │   ├── mocked_class.tpl.dist
│   │   │   ├── mocked_clone.tpl.dist
│   │   │   ├── mocked_method.tpl.dist
│   │   │   ├── unmocked_clone.tpl.dist
│   │   │   ├── wsdl_class.tpl.dist
│   │   │   └── wsdl_method.tpl.dist
│   │   ├── Generator.php
│   │   ├── InvocationMocker.php
│   │   ├── Invocation.php
│   │   ├── Invokable.php
│   │   ├── Matcher
│   │   │   ├── AnyInvokedCount.php
│   │   │   ├── AnyParameters.php
│   │   │   ├── Invocation.php
│   │   │   ├── InvokedAtIndex.php
│   │   │   ├── InvokedAtLeastOnce.php
│   │   │   ├── InvokedCount.php
│   │   │   ├── InvokedRecorder.php
│   │   │   ├── MethodName.php
│   │   │   ├── Parameters.php
│   │   │   └── StatelessInvocation.php
│   │   ├── Matcher.php
│   │   ├── MockObject.php
│   │   ├── Stub
│   │   │   ├── ConsecutiveCalls.php
│   │   │   ├── Exception.php
│   │   │   ├── MatcherCollection.php
│   │   │   ├── ReturnArgument.php
│   │   │   ├── ReturnCallback.php
│   │   │   └── Return.php
│   │   ├── Stub.php
│   │   └── Verifiable.php
│   ├── Process
│   │   └── TestCaseMethod.tpl.dist
│   ├── SelfDescribing.php
│   ├── SkippedTestError.php
│   ├── SkippedTest.php
│   ├── SkippedTestSuiteError.php
│   ├── TestCase.php
│   ├── TestFailure.php
│   ├── TestListener.php
│   ├── Test.php
│   ├── TestResult.php
│   ├── TestSuite
│   │   └── DataProvider.php
│   ├── TestSuite.php
│   └── Warning.php
├── Framework.php
├── Runner
│   ├── BaseTestRunner.php
│   ├── IncludePathTestCollector.php
│   ├── StandardTestSuiteLoader.php
│   ├── TestCollector.php
│   ├── TestSuiteLoader.php
│   └── Version.php
├── TextUI
│   ├── Command.php
│   ├── ResultPrinter.php
│   └── TestRunner.php
└── Util
    ├── Class.php
    ├── CodeCoverage.php
    ├── Configuration.php
    ├── Diff.php
    ├── ErrorHandler.php
    ├── Fileloader.php
    ├── File.php
    ├── Filesystem.php
    ├── FilterIterator.php
    ├── Filter.php
    ├── Getopt.php
    ├── GlobalState.php
    ├── InvalidArgumentHelper.php
    ├── Log
    │   ├── CodeCoverage
    │   │   ├── Database.php
    │   │   └── XML
    │   │       ├── Clover.php
    │   │       └── Source.php
    │   ├── CPD.php
    │   ├── Database
    │   │   ├── MySQL.sql
    │   │   └── SQLite3.sql
    │   ├── Database.php
    │   ├── GraphViz.php
    │   ├── JSON.php
    │   ├── JUnit.php
    │   ├── Metrics.php
    │   ├── PEAR.php
    │   ├── PMD
    │   │   ├── Rule
    │   │   │   ├── Class
    │   │   │   │   ├── DepthOfInheritanceTree.php
    │   │   │   │   ├── EfferentCoupling.php
    │   │   │   │   ├── ExcessiveClassLength.php
    │   │   │   │   ├── ExcessivePublicCount.php
    │   │   │   │   └── TooManyFields.php
    │   │   │   ├── Class.php
    │   │   │   ├── File.php
    │   │   │   ├── Function
    │   │   │   │   ├── CodeCoverage.php
    │   │   │   │   ├── CRAP.php
    │   │   │   │   ├── CyclomaticComplexity.php
    │   │   │   │   ├── ExcessiveMethodLength.php
    │   │   │   │   ├── ExcessiveParameterList.php
    │   │   │   │   └── NPathComplexity.php
    │   │   │   ├── Function.php
    │   │   │   ├── Project
    │   │   │   │   └── CRAP.php
    │   │   │   └── Project.php
    │   │   └── Rule.php
    │   ├── PMD.php
    │   └── TAP.php
    ├── Metrics
    │   ├── Class.php
    │   ├── File.php
    │   ├── Function.php
    │   └── Project.php
    ├── Metrics.php
    ├── PDO.php
    ├── PHP.php
    ├── Printer.php
    ├── Report
    │   ├── Node
    │   │   ├── Directory.php
    │   │   └── File.php
    │   ├── Node.php
    │   └── Template
    │       ├── butter.png
    │       ├── chameleon.png
    │       ├── close12_1.gif
    │       ├── container.css
    │       ├── container-min.js
    │       ├── directory.html.dist
    │       ├── directory_item.html.dist
    │       ├── file.html.dist
    │       ├── file_item.html.dist
    │       ├── file_no_yui.html.dist
    │       ├── glass.png
    │       ├── method_item.html.dist
    │       ├── scarlet_red.png
    │       ├── snow.png
    │       ├── style.css
    │       ├── yahoo-dom-event.js
    │       └── yui_item.js
    ├── Report.php
    ├── Skeleton
    │   ├── Class.php
    │   ├── Template
    │   │   ├── Class.tpl.dist
    │   │   ├── IncompleteTestMethod.tpl.dist
    │   │   ├── Method.tpl.dist
    │   │   ├── TestClass.tpl.dist
    │   │   ├── TestMethodBoolStatic.tpl.dist
    │   │   ├── TestMethodBool.tpl.dist
    │   │   ├── TestMethodExceptionStatic.tpl.dist
    │   │   ├── TestMethodException.tpl.dist
    │   │   ├── TestMethodStatic.tpl.dist
    │   │   └── TestMethod.tpl.dist
    │   └── Test.php
    ├── Skeleton.php
    ├── Template.php
    ├── TestDox
    │   ├── NamePrettifier.php
    │   ├── ResultPrinter
    │   │   ├── HTML.php
    │   │   └── Text.php
    │   └── ResultPrinter.php
    ├── Test.php
    ├── TestSuiteIterator.php
    ├── Timer.php
    ├── Type.php
    └── XML.php

50 directories, 312 files

Pay particular attention to files such as MockObject/Generator.php that were part of the PHPUnit package in version 3.4, but have been moved to a separate package, PHPUnit_MockObject in this case, for version 3.5.

Now we perform the upgrade to PHPUnit 3.5

root@ubuntu:~# pear upgrade phpunit/PHPUnit
phpunit/PHPUnit can optionally use PHP extension "dbus"
phpunit/PHP_CodeCoverage can optionally use PHP extension "xdebug" (version >= 2.0.5)
downloading PHPUnit-3.5.2.tgz ...
Starting to download PHPUnit-3.5.2.tgz (114,862 bytes)
.........................done: 114,862 bytes
downloading DbUnit-1.0.0.tgz ...
Starting to download DbUnit-1.0.0.tgz (38,183 bytes)
...done: 38,183 bytes
downloading File_Iterator-1.2.3.tgz ...
Starting to download File_Iterator-1.2.3.tgz (3,406 bytes)
...done: 3,406 bytes
downloading Text_Template-1.0.0.tgz ...
Starting to download Text_Template-1.0.0.tgz (2,493 bytes)
...done: 2,493 bytes
downloading PHP_CodeCoverage-1.0.0.tgz ...
Starting to download PHP_CodeCoverage-1.0.0.tgz (109,022 bytes)
...done: 109,022 bytes
downloading PHP_Timer-1.0.0.tgz ...
Starting to download PHP_Timer-1.0.0.tgz (2,536 bytes)
...done: 2,536 bytes
downloading PHPUnit_MockObject-1.0.0.tgz ...
Starting to download PHPUnit_MockObject-1.0.0.tgz (17,287 bytes)
...done: 17,287 bytes
downloading PHPUnit_Selenium-1.0.0.tgz ...
Starting to download PHPUnit_Selenium-1.0.0.tgz (15,252 bytes)
...done: 15,252 bytes
downloading YAML-1.0.3.tgz ...
Starting to download YAML-1.0.3.tgz (9,794 bytes)
...done: 9,794 bytes
downloading ConsoleTools-1.6.1.tgz ...
Starting to download ConsoleTools-1.6.1.tgz (869,994 bytes)
...done: 869,994 bytes
downloading PHP_TokenStream-1.0.0.tgz ...
Starting to download PHP_TokenStream-1.0.0.tgz (7,240 bytes)
...done: 7,240 bytes
downloading Base-1.8.tgz ...
Starting to download Base-1.8.tgz (236,357 bytes)
...done: 236,357 bytes
upgrade ok: channel://pear.phpunit.de/File_Iterator-1.2.3
upgrade ok: channel://pear.phpunit.de/Text_Template-1.0.0
upgrade ok: channel://pear.phpunit.de/PHP_Timer-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit_Selenium-1.0.0
upgrade ok: channel://pear.symfony-project.com/YAML-1.0.3
upgrade ok: channel://components.ez.no/Base-1.8
upgrade ok: channel://pear.phpunit.de/DbUnit-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit_MockObject-1.0.0
upgrade ok: channel://components.ez.no/ConsoleTools-1.6.1
upgrade ok: channel://pear.phpunit.de/PHP_TokenStream-1.0.0
upgrade ok: channel://pear.phpunit.de/PHP_CodeCoverage-1.0.0
upgrade ok: channel://pear.phpunit.de/PHPUnit-3.5.2

The new dependencies of the PHPUnit package, such as PHPUnit_MockObject for instance, are installed first. The PHPUnit package itself is installed last. And herein lies the problem: PHPUnit_MockObject installs the new version of MockObject/Generator.php before the PHPUnit package is upgraded. This upgrade deletes the MockObject/Generator.php file as it previously belonged to the PHPUnit package:

root@ubuntu:~# tree /usr/share/php/PHPUnit
/usr/share/php/PHPUnit
├── Autoload.php
├── Extensions
│   ├── Database
│   │   └── DataSet
│   │       ├── MysqlXmlDataSet.php
│   │       └── Persistors
│   │           └── MysqlXml.php
│   ├── GroupTestSuite.php
│   ├── OutputTestCase.php
│   ├── PhptTestCase
│   │   └── Logger.php
│   ├── PhptTestCase.php
│   ├── PhptTestSuite.php
│   ├── RepeatedTest.php
│   ├── Story
│   │   ├── Given.php
│   │   ├── ResultPrinter
│   │   │   ├── HTML.php
│   │   │   ├── Template
│   │   │   │   ├── scenario_header.html.dist
│   │   │   │   ├── scenario.html.dist
│   │   │   │   ├── scenarios.html.dist
│   │   │   │   └── step.html.dist
│   │   │   └── Text.php
│   │   ├── ResultPrinter.php
│   │   ├── Scenario.php
│   │   ├── Step.php
│   │   ├── TestCase.php
│   │   ├── Then.php
│   │   └── When.php
│   ├── TestDecorator.php
│   ├── TicketListener
│   │   ├── GitHub.php
│   │   └── GoogleCode.php
│   └── TicketListener.php
├── Framework
│   ├── Assert
│   │   └── Functions.php
│   ├── AssertionFailedError.php
│   ├── Assert.php
│   ├── ComparisonFailure
│   │   ├── Array.php
│   │   ├── Object.php
│   │   ├── Scalar.php
│   │   ├── String.php
│   │   └── Type.php
│   ├── ComparisonFailure.php
│   ├── Constraint
│   │   ├── And.php
│   │   ├── ArrayHasKey.php
│   │   ├── Attribute.php
│   │   ├── ClassHasAttribute.php
│   │   ├── ClassHasStaticAttribute.php
│   │   ├── FileExists.php
│   │   ├── GreaterThan.php
│   │   ├── IsAnything.php
│   │   ├── IsEmpty.php
│   │   ├── IsEqual.php
│   │   ├── IsFalse.php
│   │   ├── IsIdentical.php
│   │   ├── IsInstanceOf.php
│   │   ├── IsNull.php
│   │   ├── IsTrue.php
│   │   ├── IsType.php
│   │   ├── LessThan.php
│   │   ├── Not.php
│   │   ├── ObjectHasAttribute.php
│   │   ├── Or.php
│   │   ├── PCREMatch.php
│   │   ├── StringContains.php
│   │   ├── StringEndsWith.php
│   │   ├── StringMatches.php
│   │   ├── StringStartsWith.php
│   │   ├── TraversableContainsOnly.php
│   │   ├── TraversableContains.php
│   │   └── Xor.php
│   ├── Constraint.php
│   ├── Error
│   │   ├── Notice.php
│   │   └── Warning.php
│   ├── Error.php
│   ├── Exception.php
│   ├── ExpectationFailedException.php
│   ├── IncompleteTestError.php
│   ├── IncompleteTest.php
│   ├── MockObject
│   │   ├── Generator
│   │   │   ├── mocked_object_method.tpl.dist
│   │   │   └── mocked_static_method.tpl.dist
│   │   ├── Invocation
│   │   │   ├── Object.php
│   │   │   └── Static.php
│   │   └── MockBuilder.php
│   ├── Process
│   │   └── TestCaseMethod.tpl.dist
│   ├── SelfDescribing.php
│   ├── SkippedTestError.php
│   ├── SkippedTest.php
│   ├── SkippedTestSuiteError.php
│   ├── SyntheticError.php
│   ├── TestCase.php
│   ├── TestFailure.php
│   ├── TestListener.php
│   ├── Test.php
│   ├── TestResult.php
│   ├── TestSuite
│   │   └── DataProvider.php
│   ├── TestSuite.php
│   └── Warning.php
├── Framework.php
├── Runner
│   ├── BaseTestRunner.php
│   ├── IncludePathTestCollector.php
│   ├── StandardTestSuiteLoader.php
│   ├── TestCollector.php
│   ├── TestSuiteLoader.php
│   └── Version.php
├── TextUI
│   ├── Command.php
│   ├── ResultPrinter.php
│   └── TestRunner.php
└── Util
    ├── Class.php
    ├── Configuration.php
    ├── Diff.php
    ├── ErrorHandler.php
    ├── Fileloader.php
    ├── File.php
    ├── Filesystem.php
    ├── Filter.php
    ├── Getopt.php
    ├── GlobalState.php
    ├── InvalidArgumentHelper.php
    ├── Log
    │   ├── DBUS.php
    │   ├── JSON.php
    │   ├── JUnit.php
    │   ├── TAP.php
    │   └── XHProf.php
    ├── PHP.php
    ├── Printer.php
    ├── Skeleton
    │   ├── Class.php
    │   ├── Template
    │   │   ├── Class.tpl.dist
    │   │   ├── IncompleteTestMethod.tpl.dist
    │   │   ├── Method.tpl.dist
    │   │   ├── TestClass.tpl.dist
    │   │   ├── TestMethodBoolStatic.tpl.dist
    │   │   ├── TestMethodBool.tpl.dist
    │   │   ├── TestMethodExceptionStatic.tpl.dist
    │   │   ├── TestMethodException.tpl.dist
    │   │   ├── TestMethodStatic.tpl.dist
    │   │   └── TestMethod.tpl.dist
    │   └── Test.php
    ├── Skeleton.php
    ├── TestDox
    │   ├── NamePrettifier.php
    │   ├── ResultPrinter
    │   │   ├── HTML.php
    │   │   └── Text.php
    │   └── ResultPrinter.php
    ├── Test.php
    ├── TestSuiteIterator.php
    ├── Type.php
    └── XML.php

27 directories, 139 files

MockObject/Generator.php is missing (see above) but PEAR claims it is their as part of PHPUnit_MockObject:

root@ubuntu:~# pear list-files phpunit/PHPUnit_MockObject
Installed Files For phpunit/PHPUnit_MockObject
==============================================
Type Install Path
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Identity.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/InvocationMocker.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Match.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/MethodNameMatch.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Namespace.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/ParametersMatch.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Builder/Stub.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_class.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_clone.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_object_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/mocked_static_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/unmocked_clone.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/wsdl_class.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator/wsdl_method.tpl.dist
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation/Object.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation/Static.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/AnyInvokedCount.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/AnyParameters.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/Invocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedAtIndex.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedAtLeastOnce.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedCount.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/InvokedRecorder.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/MethodName.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/Parameters.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher/StatelessInvocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ConsecutiveCalls.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/Exception.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/MatcherCollection.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/Return.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ReturnArgument.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub/ReturnCallback.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Generator.php
php  /usr/share/php/PHPUnit/Framework/MockObject/InvocationMocker.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invocation.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Invokable.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Matcher.php
php  /usr/share/php/PHPUnit/Framework/MockObject/MockBuilder.php
php  /usr/share/php/PHPUnit/Framework/MockObject/MockObject.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Stub.php
php  /usr/share/php/PHPUnit/Framework/MockObject/Verifiable.php

The only way to fix this messed up situation is to force-install the new subpackages:

root@ubuntu:~# pear install -f phpunit/DbUnit
downloading DbUnit-1.0.0.tgz ...
Starting to download DbUnit-1.0.0.tgz (38,183 bytes)
...done: 38,183 bytes
upgrade ok: channel://pear.phpunit.de/DbUnit-1.0.0
root@ubuntu:~# pear install -f phpunit/PHPUnit_MockObject
downloading PHPUnit_MockObject-1.0.0.tgz ...
Starting to download PHPUnit_MockObject-1.0.0.tgz (17,287 bytes)
...done: 17,287 bytes
upgrade ok: channel://pear.phpunit.de/PHPUnit_MockObject-1.0.0
root@ubuntu:~# pear install -f phpunit/PHPUnit_Selenium
downloading PHPUnit_Selenium-1.0.0.tgz ...
Starting to download PHPUnit_Selenium-1.0.0.tgz (15,252 bytes)
...done: 15,252 bytes
upgrade ok: channel://pear.phpunit.de/PHPUnit_Selenium-1.0.0

Now we have all the files:

root@ubuntu:~# tree /usr/share/php/PHPUnit
/usr/share/php/PHPUnit
├── Autoload.php
├── Extensions
│   ├── Database
│   │   ├── AbstractTester.php
│   │   ├── Constraint
│   │   │   ├── DataSetIsEqual.php
│   │   │   └── TableIsEqual.php
│   │   ├── DataSet
│   │   │   ├── AbstractDataSet.php
│   │   │   ├── AbstractTableMetaData.php
│   │   │   ├── AbstractTable.php
│   │   │   ├── AbstractXmlDataSet.php
│   │   │   ├── CompositeDataSet.php
│   │   │   ├── CsvDataSet.php
│   │   │   ├── DataSetFilter.php
│   │   │   ├── DefaultDataSet.php
│   │   │   ├── DefaultTableIterator.php
│   │   │   ├── DefaultTableMetaData.php
│   │   │   ├── DefaultTable.php
│   │   │   ├── FlatXmlDataSet.php
│   │   │   ├── IDataSet.php
│   │   │   ├── IPersistable.php
│   │   │   ├── ISpec.php
│   │   │   ├── ITableIterator.php
│   │   │   ├── ITableMetaData.php
│   │   │   ├── ITable.php
│   │   │   ├── MysqlXmlDataSet.php
│   │   │   ├── Persistors
│   │   │   │   ├── Abstract.php
│   │   │   │   ├── Factory.php
│   │   │   │   ├── FlatXml.php
│   │   │   │   ├── MysqlXml.php
│   │   │   │   ├── Xml.php
│   │   │   │   └── Yaml.php
│   │   │   ├── QueryDataSet.php
│   │   │   ├── QueryTable.php
│   │   │   ├── ReplacementDataSet.php
│   │   │   ├── ReplacementTableIterator.php
│   │   │   ├── ReplacementTable.php
│   │   │   ├── Specs
│   │   │   │   ├── Csv.php
│   │   │   │   ├── DbQuery.php
│   │   │   │   ├── DbTable.php
│   │   │   │   ├── Factory.php
│   │   │   │   ├── FlatXml.php
│   │   │   │   ├── IFactory.php
│   │   │   │   ├── Xml.php
│   │   │   │   └── Yaml.php
│   │   │   ├── TableFilter.php
│   │   │   ├── TableMetaDataFilter.php
│   │   │   ├── XmlDataSet.php
│   │   │   └── YamlDataSet.php
│   │   ├── DB
│   │   │   ├── DataSet.php
│   │   │   ├── DefaultDatabaseConnection.php
│   │   │   ├── FilteredDataSet.php
│   │   │   ├── IDatabaseConnection.php
│   │   │   ├── IMetaData.php
│   │   │   ├── MetaData
│   │   │   │   ├── InformationSchema.php
│   │   │   │   ├── MySQL.php
│   │   │   │   ├── Oci.php
│   │   │   │   ├── PgSQL.php
│   │   │   │   └── Sqlite.php
│   │   │   ├── MetaData.php
│   │   │   ├── ResultSetTable.php
│   │   │   ├── TableIterator.php
│   │   │   ├── TableMetaData.php
│   │   │   └── Table.php
│   │   ├── DefaultTester.php
│   │   ├── IDatabaseListConsumer.php
│   │   ├── ITester.php
│   │   ├── Operation
│   │   │   ├── Composite.php
│   │   │   ├── DeleteAll.php
│   │   │   ├── Delete.php
│   │   │   ├── Exception.php
│   │   │   ├── Factory.php
│   │   │   ├── IDatabaseOperation.php
│   │   │   ├── Insert.php
│   │   │   ├── Null.php
│   │   │   ├── Replace.php
│   │   │   ├── RowBased.php
│   │   │   ├── Truncate.php
│   │   │   └── Update.php
│   │   ├── TestCase.php
│   │   └── UI
│   │       ├── Command.php
│   │       ├── Context.php
│   │       ├── IMedium.php
│   │       ├── IMediumPrinter.php
│   │       ├── IModeFactory.php
│   │       ├── IMode.php
│   │       ├── InvalidModeException.php
│   │       ├── Mediums
│   │       │   └── Text.php
│   │       ├── ModeFactory.php
│   │       └── Modes
│   │           ├── ExportDataSet
│   │           │   └── Arguments.php
│   │           └── ExportDataSet.php
│   ├── GroupTestSuite.php
│   ├── OutputTestCase.php
│   ├── PhptTestCase
│   │   └── Logger.php
│   ├── PhptTestCase.php
│   ├── PhptTestSuite.php
│   ├── RepeatedTest.php
│   ├── SeleniumTestCase
│   │   ├── append.php
│   │   ├── Driver.php
│   │   ├── phpunit_coverage.php
│   │   └── prepend.php
│   ├── SeleniumTestCase.php
│   ├── Story
│   │   ├── Given.php
│   │   ├── ResultPrinter
│   │   │   ├── HTML.php
│   │   │   ├── Template
│   │   │   │   ├── scenario_header.html.dist
│   │   │   │   ├── scenario.html.dist
│   │   │   │   ├── scenarios.html.dist
│   │   │   │   └── step.html.dist
│   │   │   └── Text.php
│   │   ├── ResultPrinter.php
│   │   ├── Scenario.php
│   │   ├── SeleniumTestCase.php
│   │   ├── Step.php
│   │   ├── TestCase.php
│   │   ├── Then.php
│   │   └── When.php
│   ├── TestDecorator.php
│   ├── TicketListener
│   │   ├── GitHub.php
│   │   └── GoogleCode.php
│   └── TicketListener.php
├── Framework
│   ├── Assert
│   │   └── Functions.php
│   ├── AssertionFailedError.php
│   ├── Assert.php
│   ├── ComparisonFailure
│   │   ├── Array.php
│   │   ├── Object.php
│   │   ├── Scalar.php
│   │   ├── String.php
│   │   └── Type.php
│   ├── ComparisonFailure.php
│   ├── Constraint
│   │   ├── And.php
│   │   ├── ArrayHasKey.php
│   │   ├── Attribute.php
│   │   ├── ClassHasAttribute.php
│   │   ├── ClassHasStaticAttribute.php
│   │   ├── FileExists.php
│   │   ├── GreaterThan.php
│   │   ├── IsAnything.php
│   │   ├── IsEmpty.php
│   │   ├── IsEqual.php
│   │   ├── IsFalse.php
│   │   ├── IsIdentical.php
│   │   ├── IsInstanceOf.php
│   │   ├── IsNull.php
│   │   ├── IsTrue.php
│   │   ├── IsType.php
│   │   ├── LessThan.php
│   │   ├── Not.php
│   │   ├── ObjectHasAttribute.php
│   │   ├── Or.php
│   │   ├── PCREMatch.php
│   │   ├── StringContains.php
│   │   ├── StringEndsWith.php
│   │   ├── StringMatches.php
│   │   ├── StringStartsWith.php
│   │   ├── TraversableContainsOnly.php
│   │   ├── TraversableContains.php
│   │   └── Xor.php
│   ├── Constraint.php
│   ├── Error
│   │   ├── Notice.php
│   │   └── Warning.php
│   ├── Error.php
│   ├── Exception.php
│   ├── ExpectationFailedException.php
│   ├── IncompleteTestError.php
│   ├── IncompleteTest.php
│   ├── MockObject
│   │   ├── Builder
│   │   │   ├── Identity.php
│   │   │   ├── InvocationMocker.php
│   │   │   ├── Match.php
│   │   │   ├── MethodNameMatch.php
│   │   │   ├── Namespace.php
│   │   │   ├── ParametersMatch.php
│   │   │   └── Stub.php
│   │   ├── Generator
│   │   │   ├── mocked_class.tpl.dist
│   │   │   ├── mocked_clone.tpl.dist
│   │   │   ├── mocked_object_method.tpl.dist
│   │   │   ├── mocked_static_method.tpl.dist
│   │   │   ├── unmocked_clone.tpl.dist
│   │   │   ├── wsdl_class.tpl.dist
│   │   │   └── wsdl_method.tpl.dist
│   │   ├── Generator.php
│   │   ├── Invocation
│   │   │   ├── Object.php
│   │   │   └── Static.php
│   │   ├── InvocationMocker.php
│   │   ├── Invocation.php
│   │   ├── Invokable.php
│   │   ├── Matcher
│   │   │   ├── AnyInvokedCount.php
│   │   │   ├── AnyParameters.php
│   │   │   ├── Invocation.php
│   │   │   ├── InvokedAtIndex.php
│   │   │   ├── InvokedAtLeastOnce.php
│   │   │   ├── InvokedCount.php
│   │   │   ├── InvokedRecorder.php
│   │   │   ├── MethodName.php
│   │   │   ├── Parameters.php
│   │   │   └── StatelessInvocation.php
│   │   ├── Matcher.php
│   │   ├── MockBuilder.php
│   │   ├── MockObject.php
│   │   ├── Stub
│   │   │   ├── ConsecutiveCalls.php
│   │   │   ├── Exception.php
│   │   │   ├── MatcherCollection.php
│   │   │   ├── ReturnArgument.php
│   │   │   ├── ReturnCallback.php
│   │   │   └── Return.php
│   │   ├── Stub.php
│   │   └── Verifiable.php
│   ├── Process
│   │   └── TestCaseMethod.tpl.dist
│   ├── SelfDescribing.php
│   ├── SkippedTestError.php
│   ├── SkippedTest.php
│   ├── SkippedTestSuiteError.php
│   ├── SyntheticError.php
│   ├── TestCase.php
│   ├── TestFailure.php
│   ├── TestListener.php
│   ├── Test.php
│   ├── TestResult.php
│   ├── TestSuite
│   │   └── DataProvider.php
│   ├── TestSuite.php
│   └── Warning.php
├── Framework.php
├── Runner
│   ├── BaseTestRunner.php
│   ├── IncludePathTestCollector.php
│   ├── StandardTestSuiteLoader.php
│   ├── TestCollector.php
│   ├── TestSuiteLoader.php
│   └── Version.php
├── TextUI
│   ├── Command.php
│   ├── ResultPrinter.php
│   └── TestRunner.php
└── Util
    ├── Class.php
    ├── Configuration.php
    ├── Diff.php
    ├── ErrorHandler.php
    ├── Fileloader.php
    ├── File.php
    ├── Filesystem.php
    ├── Filter.php
    ├── Getopt.php
    ├── GlobalState.php
    ├── InvalidArgumentHelper.php
    ├── Log
    │   ├── DBUS.php
    │   ├── JSON.php
    │   ├── JUnit.php
    │   ├── TAP.php
    │   └── XHProf.php
    ├── PHP.php
    ├── Printer.php
    ├── Skeleton
    │   ├── Class.php
    │   ├── Template
    │   │   ├── Class.tpl.dist
    │   │   ├── IncompleteTestMethod.tpl.dist
    │   │   ├── Method.tpl.dist
    │   │   ├── TestClass.tpl.dist
    │   │   ├── TestMethodBoolStatic.tpl.dist
    │   │   ├── TestMethodBool.tpl.dist
    │   │   ├── TestMethodExceptionStatic.tpl.dist
    │   │   ├── TestMethodException.tpl.dist
    │   │   ├── TestMethodStatic.tpl.dist
    │   │   └── TestMethod.tpl.dist
    │   └── Test.php
    ├── Skeleton.php
    ├── TestDox
    │   ├── NamePrettifier.php
    │   ├── ResultPrinter
    │   │   ├── HTML.php
    │   │   └── Text.php
    │   └── ResultPrinter.php
    ├── Test.php
    ├── TestSuiteIterator.php
    ├── Type.php
    └── XML.php

40 directories, 266 files

I hope that this bug in the PEAR Installer will be fixed soon.

Defined tags for this entry:

Trackback specific URI for this entry

6 Comments to "PHPUnit 3.5 Upgrading Woes"

Display comments as (Linear | Threaded)
  1. kore
    22/10/2010 at 11:32 Permalink
    Or just execute: pear list -c phpunit | grep stable | awk '{print "phpunit/"$1}' | xargs pear uninstall ; pear install phpunit/phpunit

    Reply

  2. Chuck Burgess
    22/10/2010 at 16:18 Permalink
    It looks like the PEAR installer's expectation to clean up "removed files" from one version to another inadvertently collides with another package's installation of the file when the files in question are "the same" (same name and path). I suppose the only way to handle this would be for the file removal step to perform a lookup against *all* other installed packages in order to verify that no other package has registered a file of the same name&path, and only then do the actual file deletion cleanup for the original package that's being modified.

    Would an _uninstall_ of PHPUnit 3.4 as the first step, followed by an _install_ of PHPUnit 3.5 (which picks up its dependencies), work properly?

    Reply

  3. Sebastian Bergmann
    22/10/2010 at 16:19 Permalink
    I would assume (and hope) so. I did not try it, though.

    Reply

  4. Arlen
    28/02/2011 at 23:25 Permalink
    Maybe not. Or at least not in my case.

    I started out trying this, it didn't work for me. So I went back to the drawing board and uninstalled phpunit completely. I then tried:

    pear install --alldeps phpunit/PHPUnit

    and after that finished, I *still* had to do the three forced installs listed here.

    Reply

  5. Daniel O'Connor
    24/10/2010 at 06:17 Permalink
    I suppose pyrus is also affected. The last time I went into the installer code, I got scared.

    I don't suppose someone feels game enough to write a small unit test to cover this scenario?

    Reply

  6. Chris Baclig
    03/06/2011 at 00:51 Permalink
    I'm a little late to the party, but THANK YOU! I'm so glad I found this after 2 hours of banging my head as to why PHPUnit wasn't installing properly.

    Perhaps this is worth mentioning in the official documentation as well?
    http://www.phpunit.de/manual/current/en/installation.html

    Reply

1 Trackback to "PHPUnit 3.5 Upgrading Woes"

  1. Sebastian Bergmann 01/02/2012 at 07:34
    When Noah Sussman asked me to give a Code as Craft Technology Talk last week when I was consulting for Etsy I immediately said yes. However, I was a bit surprised when the talk was announced under the title "An Evening with Sebastian Bergmann". When I rea

Add Comment


To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Submitted comments will be subject to moderation before being displayed.