-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate assertArraySubset() #3494
Comments
Ah, we use |
For |
@sebastianbergmann maybe will be better to improve this method or refactor instead of remove? I think this method really useful if I can help somehow, tell me about it |
I find it really useful to assert that an array has a set of keys/values instead of asserting one by one. for example:
|
We were using it a lot. Decided to copy this code to our codebase after upgrading to PHPUnit 8.0 since no alternative has been suggested. |
What is this replaced by? |
Laravel is using this too. |
As suggested by @sebastianbergmann I have moved this to a separate package and added a thin layer for ease of use. If you are in need: https://packagist.org/packages/dms/phpunit-arraysubset-asserts Will explore what we can do to make it clearer and more flexible as well, any input is welcome. |
We use that method in every single test!! we need it!! We are going to use the @rdohms package, if not all our tests will be destroyed. |
Well, PHPUnit 9 hasn't even been released yet and PHPUnit 8 will still be around for a while. Your tests are going to be fine. |
Removing it will break backwards compatibility, might as well take the hit and use that BC break to remove the confusion. I find this method really useful. It helps us clearly show intent on what the actual test scenario really cares about. Without that function I can see some developers reverting back to assertEquals() by copy pasting entire arrays of data that is not relevant to the test's scenario intention. |
@derrabus depends on your config, mine for example break on deprecated warning. |
@rdohms I understand. But as far as I can tell, deprecating functionality is a normal thing to do with a minor release according to SemVer. I understand that you don't want to ignore deprecations until it's too late, but your configuration sounds a bit too strict to me. |
Thus label |
Siler is using it as well, just got the warnings upgrading to PHPUnit 8. P.S.: it should be good to update the docs then: https://phpunit.readthedocs.io/en/8.0/assertions.html#assertarraysubset Add a warning telling newcomers that this feature is deprecated. foreach ($expectedSubset as $key => $value) {
$this->assertArrayHasKey($key, $actualArray);
$this->assertSame($value, $actualArray[$key]);
} |
It is helpful for API feature tests: public function testAuth(): void
{
$response = $this->post('/oauth2/auth', [
'grant_type' => 'password',
...
]);
self::assertEquals(200, $response->getStatusCode());
self::assertJson($content = $response->getBody()->getContents());
$data = json_decode($content, true);
// Check subset of all or needed static values:
self::assertArraySubset([
'token_type' => 'Bearer',
...
], $data);
// Check other generated values:
self::assertArrayHasKey('access_token', $data);
self::assertNotEmpty($data['access_token']);
} |
+1 for API tests, very useful to be able to check part of a response is present without having to check the whole thing. Often I'll have a test for the whole response, and then separate tests to check that certain attributes change based on different setups. In these cases there's no need to check the whole response array again because it's already covered. |
This one is used quite a bit. Debate the deprecation. |
Please do not deprecate this without a proper alternative. It's used in many projects and even big frameworks (e.g. laravel) |
Using this method myself in a few tests to ensure that payloads sent to and received from APIs contain the data required and also that the payloads do not contain any excess data we don't want to send. Due to the fact that we also send data that is not persisted anywhere, we cannot perform simple string comparison of serialized JSON. Some data only lives during creation of the requests. So we need structural comparison as provided by What does work as alternative for me is the following: $expected = [
'foo' => [
'bar' => 123
],
'baz' => 'hello world!'
];
$result = $someClass->myTestedMethod();
// phpunit v7
$this->assertArraySubset($expected, $result); // compare structure only
$this->assertArraySubset($expected, $result, true); // compare structure and values strictly
// phpunit v8
$this->assertTrue(
empty(array_diff_key($expected, $result)) && empty(array_diff_key($result, $expected)
); // compare structure (keys) only
$this->assertTrue(
empty(array_diff_assoc($expected, $result)) && empty(array_diff_assoc($result, $expected)
); // compare structure (keys) and values strictly Actually, using |
@sebastianbergmann This depreciation is surprising and somewhat frustrating as |
All I have to say on this subject I have written down here. If you rely on |
@sebastianbergmann honestly packaging such a widely spread and basic assertion into a separate extension and thereby forcing people to rely on a less stable and maintained extension for again basic minor functionality, does not seem like a logical choice at all. Why not decide on the behavior of the method and add it as a new properly documented method? It seems like most of the frustrations are being caused when asserting a subset of a non associative array. For most developers when they want to assert that a certain array is a subset of a non associative array. They consider the keys as something to identify the "order" of the elements in the array and not as something to identify the element by. So having one method to deal with both associative and non associative arrays didn't make sense in the first place anyway. What would make sense is having methods like this:
The behavior for the assertAssocArraySubset method would be exactly the same as the current assertArraySubset method. The behavior for the assertIndexArraySubset method would differ from assertAssocArraySubset in the way that it would not consider the keys of the elements. It will also introduce a boolean order that would be false by default and checks if the elements in the subset have the same order as in the array. To illustrate this with an example i'll reference the issues encountered in #2069 .
Respectively this would return:
Last but not least. I really hope we can give this another chance :) Best regards, |
The excellent @rdohms got you covered: https://packagist.org/packages/dms/phpunit-arraysubset-asserts |
The
assertArraySubset()
method is a constant source of confusion and frustration. For example, see #2069, #2108, #2568, #3101, #3234, #3240, or #3319.I have come to the conclusion that this mess cannot be fixed without breaking backward compatibility. In addition to that, I myself have yet to see a use case for this or how this would be used then. I have also not seen this used in the wild.
This is why I decided to deprecate
assertArraySubset()
in PHPUnit 8 and to remove it in PHPUnit 9. Anybody who thinks this functionality is useful is more than welcome to take the code, put it into a separate project, and package it as an extension for PHPUnit.The text was updated successfully, but these errors were encountered: