Commit graph

129 commits

Author SHA1 Message Date
Thiemo Kreuz
e4272518f7 tests: Replace PHPUnit's loose assertEquals(false) with assertFalse()
assertEquals( false, … ) still succeeds when the actual value is 0, null,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.

Note this patch previously also touched assertSame( false ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertFalse()
and assertSame( false ) are functionally identical.

Change-Id: Ic5f1c7d504e7249002d3184520012e03313137b4
2019-10-04 00:30:36 +00:00
Petr Pchelko
49e2aec53a Move User::getAllRights to PermissionManager.
Bug: T220191
Change-Id: I7f4bf7f6a85b01ffd7f9ea3991597f1bd40ab1f6
2019-08-29 15:38:26 +02:00
Timo Tijhof
8199e028fd resourceloader: Remove slow structure test for checking getVersionHash
This isn't needed because the startup module validates this already.

The vast majority of modules are FileModule instances which can't be invalid,
because a separate test asserts that class already. This test existed for
validating the format of version hashes returned by a theoretical Module
sub class in an extension that (badly) overrides the getVersionHash method.

As of writing, no extension overrides that method. And more importantly,
the startup module already validates this at run-time, and logs a warning.
This commit turns that into an exception, which would get logged in a way
that Jenkins will fail the build if encountered.

This structure test, which computed the response for all registered modules,
previously took 3-5 seconds in CI.

Bug: T225730
Change-Id: Id2e37434b0ccd95dd2279f04e2230e9c06b09ccb
2019-08-01 15:33:23 +00:00
Timo Tijhof
a5a672b1a5 resourceloader: Speed up dependency checks in structure/ResourcesTest
Stats from wmf-quibble-core-vendor-mysql-php72-docker builds.
Before:
* testIllegalDependencies (+21ms)
* testMissingDependencies (+254ms)
After:
* testValidDependencies (+17ms)

Bug: T225730
Change-Id: Idf760a27c7ad16d4838ae82e7895b659934fbf93
2019-07-15 02:02:38 +00:00
Amir Sarabadani
16b82d0ef0 Run SpecialPageFatalTest with lang=qqx
SpecialPageFatalTest:testSpecialPageDoesNotFatal is one of the slowest
tests (specially running Special:Version) due to the fact that it needs
to translate so many message keys.

3206ms to run SpecialPageFatalTest:testSpecialPageDoesNotFatal with data set "Version"

Running with lang=qqx would ensure that the special doesn't fatal but also avoid
unnecessary message translations

Change-Id: I8ff715ac539e93915c98f7209523df1b3ea3a7e8
2019-07-08 14:52:06 +02:00
Timo Tijhof
c554ee8e64 resourceloader: Remove support for raw modules
Being a raw module means that when it is requested from load.php with
"only=scripts" set, then the output is *not* wrapped in an
'mw.loader.implement' closure *and* there no 'mw.loader.state()' appendix.
Instead, it is served "raw".

Before 2018, the modules 'mediawiki' and 'jquery' were raw modules.
They were needed before the client could define 'mw.loader.implement', and
could never be valid dependencies. Module 'mediawiki' merged to 'startup',
and 'jquery' became a regular module (T192623). Based on the architecture
of modules being deliverable bundles, it doesn't make sense for there to
ever be raw modules again. Anything that 'startup' needs should be bundled
with it. Anything else is a regular module.

On top of that, we never actually needed this feature because specifying
the 'only=scripts' and 'raw=1' parameters does the same thing.

The only special bit about marking modules (not requests) as "raw" was that
it allowed the client to forget to specify "raw=1" and the server would
automatically omit the 'mw.loader.state()' appendix based on whether the
module is marked as raw. As of Ie4564ec8e26ad53f2, the two remaining use
cases for raw responses now specify the 'raw=1' request parameter, and we
can get rid of the "raw module" feature and all the complexity around it.

== Startup module

In the startup module there was an interesting use of isRaw() that has
little to do with the above. The "ATTENTION" warning there applies to the
startup module only, not raw modules in general. This is now fixed by
explicitly checking for StartupModule.

Above that warning, it talked about saving bytes, which was an optimisation
given that "raw" modules don't communicate with mw.loader, they also don't
need to be registered there because even if mw.loader would try to load
them, the server would never inform mw.loader about the module having
arrived. There are now no longer any such modules.

Bug: T201483
Change-Id: I8839036e7b2b76919b6cd3aa42ccfde4d1247899
2019-06-27 00:08:14 +00:00
Timo Tijhof
e1c3b04267 resourceloader: Remove my @author comments from unit tests
Previously removed from includes/ already.

Also remove odd `@package`, which we never use.
And remove `@since` which doesn't make sense for test-only files.

Change-Id: Ib7265d39329ecadd5279b11820f77f54189b55d2
2019-06-20 01:24:50 +01:00
Timo Tijhof
8035a00e8c AutoLoader: Skip tokenizing of irrelevant lines in ClassCollector
This makes AutoLoaderStructureTest in PHPUnit and the
generateLocalAutoload.php maintenance script much faster.

On my machine, it made it 35X faster (or time spent reduced by 97%).

Bug: T225730
Change-Id: Ife959bd17ce9c2ae952dfbd158ddb3d8475e8cb2
2019-06-19 15:09:49 +00:00
Legoktm
4e35134f7a Revert "Separate MediaWiki unit and integration tests"
This reverts commit 0a2b996278.

Reason for revert: Broke postgres tests.

Change-Id: I27d8e0c807ad5f0748b9611a4f3df84cc213fbe1
2019-06-13 23:00:08 +00:00
Máté Szabó
0a2b996278 Separate MediaWiki unit and integration tests
This changeset implements T89432 and related tickets and is based on exploration
done at the Prague Hackathon. The goal is to identify tests in MediaWiki core
that can be run without having to install & configure MediaWiki and its dependencies,
and provide a way to execute these tests via the standard phpunit entry point,
allowing for faster development and integration with existing tooling like IDEs.

The initial set of tests that met these criteria were identified using the work Amir did in
I88822667693d9e00ac3d4639c87bc24e5083e5e8. These tests were then moved into a new subdirectory
under phpunit/ and organized into a separate test suite. The environment for this suite
is set up via a PHPUnit bootstrap file without a custom entry point.

You can execute these tests by running:
$ vendor/bin/phpunit -d memory_limit=512M -c tests/phpunit/unit-tests.xml

Bug: T89432
Bug: T87781
Bug: T84948
Change-Id: Iad01033a0548afd4d2a6f2c1ef6fcc9debf72c0d
2019-06-13 22:56:31 +02:00
Gergő Tisza
45d4e8d13a Exempt structure tests from @covers checks
@covers does not make any sense for structure tests, which either
do not cover any PHP lines (they test things like configuration or
messages), or cover lines which cannot be determined at the time
of writing the tests (e.g. they cover all classes implementing a
certain interface). Requiring @coversNothing to be manually added
for all of them is a waste of developer time.

tests/phpunit/suite.xml has forceCoversAnnotation=true so removing
the annotations will not change test coverage, these files will
still be skipped.

Change-Id: I27cb58e92341b9b1a76f109701f5bc843adbaa9b
2019-06-11 21:40:14 +00:00
Lucas Werkmeister
2744dbd9b7 Normalize dir path in AutoLoaderStructureTest
The file paths we inspect are always normalized (File_Iterator_Facade
applies realpath()), but the directory we compare against may not be,
depending on how wfLoadExtension() was called. Normalize the directory
before we remove the directory prefix from each file, so that we don’t
end up stripping away the wrong parts of the path.

Change-Id: Ib272fb892c18d989f8d439ed50c6a5a8fd542cc9
2019-06-07 12:53:31 +02:00
Aryeh Gregor
2e1ac38485 Mass conversion to NamespaceInfo
Change-Id: I2fef157ceec772f304c0923a1cd8c0eef2e82a0f
2019-05-07 22:44:56 +02:00
Umherirrender
7d7820fb4a Relax SpecialPageFatalTest about deprecation notices
Deprecation notice from SpecialPageFatalTest is the most merge blocker
since merge of I8fb26380724b6b12bf08458dbff2e00b759d219b
Deprecation can occur at any time and than break many extensions to
merge, even there are still working.
Ignore deprecation as before, but keep the error and notices

Change-Id: Idcbc38b662c569fbe8e778a6b1ab815db332dc08
2019-04-19 20:18:22 +02:00
Reedy
3ecbd79ebe Add test to check action- messages exist
Bug: T220779
Change-Id: Ide681e1f03957a8024f538ea6cac4e4396fef23e
2019-04-12 17:44:33 +00:00
Reedy
c13fee87d4 Collapse some nested if statements
Change-Id: I9a97325d738d09370d29d35d5254bc0dadc57ff4
2019-04-04 19:02:22 +00:00
jenkins-bot
f2b01310d9 Merge "Do not suppress php notices in SpecialPageFatalTest" 2019-03-23 21:20:04 +00:00
Thiemo Kreuz
8c33a391a0 Fix assertArrayEquals() calls with bogus 3rd parameter
This issue came up in I8a49143, see
https://integration.wikimedia.org/ci/job/mediawiki-quibble-vendor-postgres-php70-docker/2453/console
The third parameter of assertArrayEquals() is called $ordered and is
meant to take the order of elements into account. Providing a string sets
this to true. The SQL query in ChangesListSpecialPageTest seems to behave
a bit random in Postgres and does not always return the elements in the
same order. This is fine. It's just the assertion that was to strict, by
accident.

I found a few more instances of the same issue with a regular expression.
In most cases I intentionally changed it to assertSame() because the order
of elements is actually guaranteed by the code, and needs to be (e.g.
mixing width and height of an image would be fatal).

Change-Id: Ice66cab873a7271d55809a486ce28cf637e43e33
2019-03-14 18:02:08 +01:00
Dayllan Maza
4b39919c47 Add password policy setting suggestChangeOnLogin
Password policy checks that fail and have `suggestChangeOnLogin` set to true will
prompt for a password change on login.

Below are some rules that apply to this setting in different scenarios:

- If only one policy fails and has `suggestChangeOnLogin = false`, a password change will
  not be requested
- If more than one policy fails and one or more have `suggestChangeOnLogin` set to true`,
  a password change will be requested
- If `forceChange` is present in any of the failing policies, `suggestChangeOnLogin` value
  will be ignored and password change will be enforced
- if $wgInvalidPasswordReset is set to false `suggestChangeOnLogin` is ignored

IMPORTANT**
Before this patch, suggesting a password change was the default behavior (depending on
$wgInvalidPasswordReset), which means that the necessary changes to $wgPasswordPolicy
need to be in place before this patch is merged and gets to production.

Bug: T211621
Change-Id: I7a4a0a06273fa4e8bd0da3dac54cf5a1b78bb3fd
2019-03-09 14:59:02 -05:00
jenkins-bot
747bdd543d Merge "Show password policy flags on Special:PasswordPolicies" 2019-03-02 03:51:05 +00:00
Gergő Tisza
22c8cda841
Show password policy flags on Special:PasswordPolicies
Follow-up to I28c31fc4ea.

Also improves what policy values are considered disabled, documents
how to extend core checks/flags and adds a structure test for it.

Bug: T118774
Change-Id: I66bf396e8e8a8c310a47ba337abe9070e7e83ff6
2019-03-01 19:02:40 -08:00
Umherirrender
4743ab9efc Do not suppress php notices in SpecialPageFatalTest
When the php notice is converted to exception,
it is also from type Exception and currently ignored.
Catch the special phpunit exception type separated and rethrow.

This changed is in a structure test and can break other exceptions.

Change-Id: I8fb26380724b6b12bf08458dbff2e00b759d219b
2019-02-19 21:20:59 +01:00
Timo Tijhof
92d6be8a38 resourceloader: Require $context parameter for FileModule::readStyleFiles()
Deprecated since MW 1.27.

Also update ResourcesTest to use TestingAccessWrapper instead of long-form
object reflection, and also apply it to its call for this method given
its meant to be private.

Change-Id: I9cc1af93730f632e4f8bf3a16d514a51ee73cb03
2019-02-18 19:05:24 +00:00
Timo Tijhof
a186dc62fd resourceloader: Instantiate main class via ServiceWiring
It also removes some code duplication which is nice.

This unlocks various future changes, including:

* Making the `$config` parameter mandatory for the ResourceLoader class
  constructor, which currently falls back to global state.
  This should be deprecated and removed.

* Making it possible to instantiate the ResourceLoader class
  without all the default MW modules being registered from
  global state. E.g. move MW module registration from main class
  constructor to ServiceWiring, and remove the 'EmptyResourceLoader'
  class hack from unit tests, and use regular 'new ResourceLoader'
  instead.

* Making ResourceLoader a standalone library (some day),
  e.g. allowing it to be instantiated from a basic PHP script,
  in a way that is still useful and perhaps able to serve
  (most) RL modules without MW itself.

Bug: T32956
Change-Id: I4939f296c705b268e9cf8de635e923a739410470
2019-02-18 17:55:09 +00:00
Umherirrender
d28f315d24 Add @coversNothing for left over tests and enable sniff
LessFileCompilationTest is checking less files for valid syntax
doc test is checking xml file for valid syntax
MediaWikiTest is testing a complex situation with many functions involved
SideBarTest is self checking, needs no coverage
structure tests not covers functions, there are covers global structures

Change-Id: I3ac65db561cae0be8418aa9c830e7a9f46ad11fe
2019-02-02 21:53:40 -08:00
Alangi Derick
8221a7a4f2 Remove array_unique() on expected classes in checkAutoLoadConf()
Sometimes classes can be loaded via autoload (PSR-4) and class_aliasing
and due to this calling array_unique() on expected classes will remove
one of these classes due to them sharing the same file (and array_unique()
works on array values).

Also allow for ::class suffixed classes to be namespaced (ie look for \
in the regexes)

Cleanup some of the regexes, remove redunant code (don't need multi cased
letters when we have /i), simplify them

Bug: T206728
Change-Id: I235274d579b1bfd12a448448ddf020546c9aa89b
2018-11-30 00:22:06 +00:00
Brad Jorsch
ca3789a271 AutoloadGenerator: Filter PSR4-compliant classes instead of ignoring directories
Per discussion in T166010, we're going to handle class aliases (e.g. for
BC) by including the class_alias() call in the same file as the target
class. When the target class is a PSR4-compliant class, we still need to
pick up that alias for inclusion in autoload.php.

Thus, instead of excluding whole directories, we need to process the
files and filter out only those found classes that are PSR4 compliant.

Bug: T204983
Change-Id: I1c516998df368531c90ea54acc5be8be96e1db6c
2018-09-20 15:15:27 -04:00
Umherirrender
480b653720 StructureTest::testUnitTestFileNamesEndWithTest() should not shell out
Bug: T169005
Change-Id: I17b35f31c3989ca0b9056252866a45434c31a105
2018-09-18 20:34:28 +02:00
jenkins-bot
df76e044f5 Merge "Pass delimiter to preg_quote" 2018-09-10 23:55:19 +00:00
Tim Starling
5322107191 Reset services before every test
Trying to avoid resetting services introduces a lot of complexity and
several bugs. We were doing a reset for 70% of @group Database tests
anyway.

Instead:

* Reset services at the start of MediaWikiTestCase::run().
* Capture the actual original service container instead of making a
  special shared service container.
* The test-isolated local service container can now only be initialised
  non-statically. Revert the recent conversion of overrideMwServices()
  to static.
* Store a reference to the local service container in the test case
  object. In MediaWikiTestCase, always use the original or local service
  container directly, to avoid confusion about which one is active at
  the time.
* Remove a lot of unnecessary teardown
* Always call ServiceContainer::destroy() before forceGlobalInstance()
  since the memory is not otherwise freed.

Change-Id: I4a17c1c7ec92c14e3bc471f0216473ebe19477b9
2018-09-03 16:38:58 +00:00
Umherirrender
acb2e720d8 Pass delimiter to preg_quote
This ensure that the regex is escaped correctly,
even when the quoted value never contains the delimiter

Change-Id: I2dc93fa0154d4506c276a30cab008bc2ac5e0687
2018-09-01 14:52:16 +02:00
jenkins-bot
5354c219cd Merge "test: Assert that API generators have unique prefixes" 2018-08-18 01:04:31 +00:00
jenkins-bot
fd08137ebf Merge "Turn ApiPrefixUniquenessTest into a structure test" 2018-08-18 00:55:18 +00:00
Antoine Musso
821fbb27c4 test: Assert that API generators have unique prefixes
Signed-off-by: Brad Jorsch <bjorsch@wikimedia.org>
Change-Id: I30758f2ac95fd8ae361ef8079abdfb0a82d92e34
2018-08-17 17:31:22 -07:00
Kunal Mehta
72b4099727 Turn ApiPrefixUniquenessTest into a structure test
This way it gets run during extension test runs as well.

Temporarily add a hack allowing 'wbeu' duplicates until T196962 is fixed.

Change-Id: Ic89a22a2ff4525585de9e290a1d47d22cfaaac5e
2018-08-17 14:19:41 -07:00
Aryeh Gregor
e68fdb4065 Mass conversion to SpecialPageFactory service
Change-Id: Ia6e1e819ec6cbe8bf75b820109f51d47863e31fc
2018-08-17 12:03:12 -07:00
Aryeh Gregor
d4045035b0 Make SpecialPageFactory a service
Calling SpecialPageFactory methods statically is now soft-deprecated.

SpecialPageFactory::resetList() is a no-op, and I changed tests
in core to use overrideMwServices() instead.

Methods that fell back to $wgUser now require a User object being passed.

Depends-On: Ie1f80315871085b9fd4763a265b588849d94414d
Change-Id: Id8a92d57743f790b7d8c377c033cef38d1bb24de
2018-08-17 11:12:23 -07:00
addshore
b50c8848e6 Introduce SpecialPageFatalTest
This test makes sure that special pages do not fatal
in their most basic form (anon user viewing the page).

Depends-On: I3a9f5b315eb114cb12ea4071f8da9079f797fcf6
Change-Id: Ic675e92d8dd8f11fa67914d2ce1dc00a379106ca
2018-07-31 07:11:48 +00:00
Kunal Mehta
13b817d408 Check for right-* messages as a structure test
Structure tests run for extensions as well, which this test should. All
user rights should have right-* messages for display in the interface.

Bug: T143156
Change-Id: I23b8eb66bc68121b2ae17e73e705acd3e6f2d053
2018-07-26 14:14:54 -07:00
Timo Tijhof
b7b84d55d4 resourceloader: Embed 'mediawiki' directly in startup response
Embed the essential files to define mw.loader directly as part of
the startup module.

* This means the internal 'mediawiki' module no longer exists.
  This is safe to remove because:
  1) While registered server-side for loading from startup.js, a PHPUnit
     structure test disallowed being specified as a dependency.
  2) Anything that attempted to load it client-side failed because the
     module was marked in the registry as 'raw', thereby excluding it
     from the data sent to the client-side. As such, it was seen as an
     unknown module that the client refused to fetch from the server.

* Deprecate getStartupModules() and getLegacyModules().
  These are no longer needed. There are no known callers anywhere in
  Wikimedia Git or elsewhere indexed by Codesearch, but easy enough
  to leave as no-op for one release.

* Remove ResourceLoaderRawFileModule class.
  No longer needed. Was created as a hack specifically for the 'mediawiki'
  module so that it would not leak global variables in debug mode.
  It has no usage anywhere in Wikimedia Git, nor elsewhere in Codesearch.
  Remove without deprecation given this was meant to be a 'private' class.

* Introduce (private) getBaseModules(). Previously, this list only existed
  locally in getStartupModulesUrl() by merging getStartupModules() and
  getLegacyModules(). This value was factored out into its own method.

* Make getStartupModulesUrl() private and rename to getBaseModulesUrl().
  It is only used internally to export the 'baseModulesUri' value.
  Its name was already confusing before, but it would've been even more
  confusing now given it doesn't even call getStartupModules() any more.

Bug: T192623
Change-Id: I14ba282d7b65e99ca54b7c2f77ba6e1adaddd11c
2018-06-27 17:06:35 +00:00
Hashar
afb2269cb9 Revert "Use pathinfo() in AutoLoaderStructureTest::testPSR4Completeness"
This reverts commit 634c2ec2af.

Reason for revert: that strips the PSR4 directories from the class.

Example:
$dir BlueSpiceFoundation/src/"
$file BlueSpiceFoundation/src/ConfigDefinition/IntSetting.php

$abbrFileName: IntSetting
$expectedClassName: BlueSpice\IntSetting

$abbrFileName should be relative to $dir and not just the filename.

Bug: T198077
Change-Id: Ie934e309fee0392439b4e26d86249f0650e5ea67
2018-06-25 12:38:07 +00:00
Antoine Musso
634c2ec2af Use pathinfo() in AutoLoaderStructureTest::testPSR4Completeness
When setting AutoloadNamespaces to './' in extension.json, the test
AutoLoaderStructureTest::testPSR4Completeness would fail. The directory
path is not made canonical while the file is, which causes the substr()
call being used to strip too many characters. For example:

  $dir : /mediawiki/extensions/Wikidata.org/./
  $file: /mediawiki/extensions/Wikidata.org/Hooks.php

$abbrFileName = substr( substr( $file, strlen( $dir ) ), 0, -4 );
>>> oks

Use pathinfo() to parse the filename. Yields 'Hooks' as expected.

Bug: T198077
Change-Id: Ia8a11d87788b32ddb426a16a61b410b05ff5f15e
2018-06-25 11:47:52 +00:00
Kunal Mehta
4acb7ed51c Add @coversNothing to tests that don't cover specific PHP classes
Change-Id: Idbd364561bc28547e9fac20d7a80b9a44edf14a9
2018-06-12 13:27:40 -07:00
Kunal Mehta
b5e6da43e4 Don't autoload classes in AutoloadStructureTest
Autoloading classes is a 100% accurate way to ensure the autoloader
worked, but there are cases where if optional dependencies aren't
installed, then autoloading the class will fail. We can re-implement the
logic behind the PSR-4 autoloader, and ensure that classes will be
autoloadable by turning the filename into a class name, and making sure
that class name is the one we found in the file.

Bug: T195823
Change-Id: I5df378180e567c257386482383ef73812592f989
2018-05-29 11:09:57 -07:00
Kunal Mehta
e7ae019fc0 AutoLoaderStructureTest: Allow PSR-4 directories to have files with 0 classes
Files like ServiceWiring.php can be safely located in a PSR-4 autoloaded
directory, because they have no classes.

Change-Id: I359b305df9071d6bc5afe4b5f29e762041f4aaef
2018-05-26 16:51:56 -07:00
Kunal Mehta
e298f548f6 Split AutoloaderTest into a structure and class test
AutoloaderTest covers the AutoLoader class, and AutoLoaderStructureTest
covers the structure part of the test.

Change-Id: Ic4e7bfd670e1c3413631bda31260cc1cc825b1a2
2018-05-26 16:16:02 -07:00
Kunal Mehta
0e6f6b592d Add structure test to ensure PSR-4 autoloader covers everything
This ensures that there aren't any classes inside a PSR-4 autoloaded
directory that aren't being autoloaded properly.

Change-Id: I200a8535c2f47a6bf3287a7fe1182151493372f4
2018-05-24 18:57:42 -07:00
Brad Jorsch
78d1b8ebba API: Introduce "templated parameters"
With MCR coming up, ApiEditPage is going to need to be able to take
"text" and "contentmodel" parameters for each slot-role, and enumerating
such parameters for every possible slot would probably get rather
confusing as to what is required when, or at least long-winded in
repeating the exact same thing for every possible role.

So let's abstract it: we'll have an "editroles" parameter to specify which
slots are being edited, and ApiEditPage will just declare that
"text-{role}" and "contentmodel-{role}" parameters should exist for each
value of "editroles" in the submission.

Note this patch doesn't introduce anything that uses templated
parameters, just the functionality itself. For testing purposes you
might cherry pick I2d658e9a.

Bug: T174032
Change-Id: Ia19a1617b73067bfb1f0f16ccc57d471778b7361
2018-05-16 16:19:31 -04:00
Aryeh Gregor
4fe5d0dbaa Add more checks to ApiStructureTest.php
Depends-On: Ideca8903e4b529b7471ba81aa7dd3b01039ed2f9
Depends-On: I39b96ad0334a17fd50501e92b26f1d47ee4ccbba
Depends-On: Ied07ccfd7ff6db9d399eac3c8aab63993b91c1f4
Change-Id: I4a2505cfc8e86e73e46d40acffbf3cd8803458e2
2018-04-08 15:58:06 +03:00
Lucas Werkmeister
4a1e59b63d Accept non-fully qualified TestCase in StructureTest
This makes StructureTest also recognize test classes which look like

    use PHPUnit\Framework\TestCase;

    class FooTest extends TestCase {

instead of

    class FooTest extends \PHPUnit\Framework\TestCase {

This form is preferred, for instance, in Wikibase code.

Bug: T188276
Change-Id: I5bef035df33d317893ad3ba195ecb75f3b09a62f
2018-02-26 18:06:27 +01:00