Problem/Motivation

As title

Proposed resolution

Example:

-    $this->assertTrue(isset($ids['entity_test.entity_test.field_test_import']));
+    $this->assertNotNull($ids['entity_test.entity_test.field_test_import']);

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#99 3131807-99.patch229.03 KBmondrake
#95 3131807-95.patch249.84 KBmondrake
#86 3131807-86.patch271.05 KBjungle
#86 raw-interdiff-85-86.txt8.72 KBjungle
#85 interdiff_84-85.txt33.2 KBmondrake
#85 3131807-85.patch271.03 KBmondrake
#84 interdiff_82-84.txt7.86 KBmondrake
#84 3131807-84.patch272.89 KBmondrake
#82 interdiff_80-82.txt42.04 KBmondrake
#82 3131807-82.patch275.28 KBmondrake
#81 interdiff_78-80.txt2.04 KBmondrake
#80 3131807-80.patch239.72 KBmondrake
#78 interdiff-77-78.txt2.78 KBjungle
#78 3131807-78.patch239.9 KBjungle
#77 3131807-77.patch239.97 KBmondrake
#77 interdiff_76-77.txt1.03 KBmondrake
#76 interdiff_74-76.txt22 KBmondrake
#76 3131807-76.patch239.97 KBmondrake
#74 3131807-74.patch226.61 KBmondrake
#74 interdiff_73-74.txt1023 bytesmondrake
#73 interdiff_72-73.txt1000 bytesmondrake
#73 3131807-73.patch226.61 KBmondrake
#72 interdiff_65-72.txt59.85 KBmondrake
#72 3131807-72.patch226.61 KBmondrake
#71 interdiff-131807-69-71.txt2.74 KBmsuthars
#71 3131807-71.patch275.61 KBmsuthars
#69 3131807-69.patch277.54 KBmsuthars
#65 interdiff-3131807-61-65.txt2.6 KBmsuthars
#65 3131807-65.patch171.76 KBmsuthars
#61 interdiff_57-61.txt14.37 KBravi.shankar
#61 3131807-61.patch171.77 KBravi.shankar
#57 interdiff_55-57.txt3.76 KBmohrerao
#57 3131807-57.patch173.47 KBmohrerao
#55 interdiff_47-55.txt66.5 KBmohrerao
#55 3131807-55.patch173.22 KBmohrerao
#54 interdiff_47-54.txt66.5 KBmohrerao
#54 3131807-54.patch173.22 KBmohrerao
#47 interdiff-45-47.txt22.79 KBnaresh_bavaskar
#47 3131807-47.patch160.87 KBnaresh_bavaskar
#45 interdiff-42-45.txt738 byteshardik_patel_12
#45 3131807-45.patch142.74 KBhardik_patel_12
#42 3131807-42.patch142.69 KBmrinalini9
#39 3131807-39.patch142.66 KBjungle
#39 interdiff-36-39.txt10.08 KBjungle
#36 interdiff-3131807-29-36.txt27.11 KBsja112
#36 3131807-36.patch142.66 KBsja112
#34 interdiff-3131807-29-34.txt22.09 KBsja112
#34 3131807-34.patch142.65 KBsja112
#33 phpstrom-80chars.png1.01 MBjungle
#32 interdiff-3131807-29-32.txt22.16 KBsja112
#32 3131807-32.patch142.65 KBsja112
#29 interdiff-3131807-28-29.txt58.34 KBsja112
#29 3131807-29.patch142.15 KBsja112
#28 interdiff-3131807-27-28.txt90.95 KBsja112
#28 3131807-28.patch141.02 KBsja112
#27 3131807-27.patch124.88 KBsja112
#26 interdiff_20-26.txt610 bytesspokje
#26 3131807-26.patch124.91 KBspokje
#21 interdiff_18-20.txt3.34 KBspokje
#21 3131807-20.patch124.91 KBspokje
#18 interdiff-17-18.txt72.99 KBquietone
#18 3131807-18.patch124.72 KBquietone
#17 3131807-17.patch45.17 KBquietone
#17 interdiff-12-17.txt2.66 KBquietone
#13 interdiff-4-12.txt37.38 KBquietone
#13 3131807-12.patch45.68 KBquietone
#7 3131807-7.patch6.44 KBspokje
#10 drupal-core-3131807-10.patch6.45 KBandrewsizz
#4 3131807-4.patch6.26 KBquietone
#7 interdiff_4-7.txt998 bytesspokje

Issue fork drupal-3131807

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jungle created an issue. See original summary.

mondrake’s picture

Nice one. Imho

A) need to make sure this is for arrays only (isset on scalar will not apply here)
B) besides checking the existence ofthe array key, we need to ensure also that the key value is not null, since it could be. Maybe we can just assertNotNull instead, if the array key is missing we will get an exception anyway

jungle’s picture

Issue summary: View changes

Thanks @mondrake. Updating IS and mentioning to remove redundant assertion messages

quietone’s picture

Status: Active » Needs review
StatusFileSize
new6.26 KB

Just a wee start. This makes the changes to Unit tests. Used this to find the files to edit, egrep -r "this->assert.+isset" core | grep Unit | awk -F: '{print $1}' | sort -u.

Status: Needs review » Needs work

The last submitted patch, 4: 3131807-4.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jungle’s picture

@quietone, thanks! BTW, 1 coding standards message

core/tests/Drupal/KernelTests/Core/Database/ConnectionUnitTest.php line 5 Unused use statement

spokje’s picture

StatusFileSize
new6.44 KB
new998 bytes

Quick "Reroll-n-Run" patch attached (hopefully) fixing Test Failures and addressing #6

andrewsizz’s picture

Status: Needs work » Reviewed & tested by the community

reviewed patch - Looks good for me.

andrewsizz’s picture

Status: Reviewed & tested by the community » Needs work

no, in last patch missing return

 -    return $this->assertArrayHasKey($id, $list);
+    $this->assertArrayNotHasKey($id, $list);
andrewsizz’s picture

StatusFileSize
new6.45 KB
spokje’s picture

@AndrewsizZ All assert functions return void. A return isn't needed IMHO, if it fails it will throw an Exception. So I removed it on purpose.

jungle’s picture

Thank you all!

Just a wee start. This makes the changes to Unit tests.

@quietone already said it was just a start, and only made changes to Unit tests.

There are many more to do, checked with regex assert.+isset got over 100+ matches.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new45.68 KB
new37.38 KB

Another installment, still much work to do. I was working off the patch in #4 so the interdiff is against that.

For now I have restored the assertions in ConnectionUnitTest.php

andrewsizz’s picture

@Junge, than you man
Do we have list of issues where we still need work?

jungle’s picture

Re @AndrewsizZ

What I meant is this issue still having a lot of assertions to replace, as you can see from the new patch @quietone just uploaded.

About similar/relevant/sibling issues, you can check out the parent issue #3128573: [meta] Replace assertions with more appropriate ones for more if you are interested in.

Status: Needs review » Needs work

The last submitted patch, 13: 3131807-12.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new2.66 KB
new45.17 KB

I want to fix the tests before going further. So, fixing typos and stray characters.

quietone’s picture

StatusFileSize
new124.72 KB
new72.99 KB

Another installments and this is enough for today on this.

mondrake’s picture

Per #2.B,

+++ b/core/modules/aggregator/tests/src/Functional/AggregatorRenderingTest.php
@@ -119,7 +119,7 @@ public function testFeedPage() {
-    $this->assertTrue(isset($links[0]), new FormattableMarkup('Link to href %href found.', ['%href' => $href]));
+    $this->assertArrayHasKey(0, $links);

in case you have

  $links = [
    0 => NULL,
  ];

will result in isset($links[0]) return FALSE. So assertTrue will fail. But, $links DOES have a 0 key, so assertArrayHasKey(0, $links) will pass, which is wrong vs the original intention.

I think in this case $this->assertNotNull($links[0]) would fit better here, because if the array has not the key 0 we will have an exception, if the key is there but associated to NULL, we would fail as well.

Status: Needs review » Needs work

The last submitted patch, 18: 3131807-18.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

spokje’s picture

StatusFileSize
new124.91 KB
new3.34 KB

Wow, much work done there @quietone!

I've (tried to) fix(ed) 4 out of the 5 fails and the codesniffer issue.

The remaining failure is addressed by @mondrake in #19. I happily leave that to people with Bigger Brains than mine :)

Here's a patch based on #18

quietone’s picture

Status: Needs work » Needs review

@mondrake, thanks for getting me to think more about this. I don't like the idea of getting an exception in a test, I'd rather have assertions catch the errors.

But the point is that replacing assertions on isset() with just arrayHasKey/arrayNotHasKey won't work. isset does two checks, that the variable exists and that it is not NULL whereas arrayHasKey/arrayNotHasKey just checks that they key exists, using array_key_exists. To remove the isset() there needs to be two assertions, arrayHasKey/arrayNotHasKey followed by an assertNull/assertNotNull. However, that too is problematic. One needs to know if the test always fails on the existence or absence of the key or the value of the variable.

Just to see I changed two tests in ConnectionUnitTest.php:

    */
   protected function assertConnection($id) {
     $list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0);
-    return $this->assertTrue(isset($list[$id]), new FormattableMarkup('Connection ID @id found.', ['@id' => $id]));
+    $this->assertArrayHasKey($id, $list);
+    $this->assertNotNull($list[$id]);
   }
 
   /**
@@ -89,7 +89,7 @@ protected function assertConnection($id) {
    */
   protected function assertNoConnection($id) {
     $list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0);
-    return $this->assertFalse(isset($list[$id]), new FormattableMarkup('Connection ID @id not found.', ['@id' => $id]));
+    $this->assertArrayNotHasKey($id, $list);
   }

But that works for this file. There could be other tests, in a loop, where the isset() fails in one case on the existence of the key and in other where it fails because the fail it NULL.

daffie’s picture

Status: Needs review » Needs work

Patch looks good. I have 2 remarks:

  1. +++ b/core/modules/content_moderation/tests/src/Functional/ViewsModerationStateFilterTest.php
    @@ -347,7 +347,7 @@ protected function assertWorkflowDependencies(array $workflow_ids, ViewEntityInt
    -      $this->assertTrue(!isset($dependencies['config']));
    +      $this->assertArrayHasKey('config', $dependencies);
    

    Change is wrong. We should use assertArrayNotHasKey().

  2. In most code changes the assert message text has been removed, but not in all of them. Why?

The removal of the return value for the methods Drupal\KernelTests\Core\Database\ConnectionUnitTest::assertConnection(), Drupal\KernelTests\Core\Database\ConnectionUnitTest::assertNoConnection() and
Drupal\Tests\system\Functional\Form\ConfirmFormTest::assertCancelLinkUrl() is not a problem, because those returns values are never used.

jungle’s picture

Re #23, see #3131946: [policy] Remove PHPUnit assertion messages when possible, and standardize remaining messages for more about the reason of removing redundant assertion messages.

daffie’s picture

@jungle: Thank you for the answer.

I have looked at the issue and I also looked again at the patch from comment #21. The changes for the assert message text are for me correct.
Still open are comments #22 and #23.1.

spokje’s picture

StatusFileSize
new124.91 KB
new610 bytes

Reroll of patch in #21
Also addresses #23.1
Still needs addressing #22

sja112’s picture

StatusFileSize
new124.88 KB

Reroll of patch in #26
Still needs addressing #22

sja112’s picture

Status: Needs work » Needs review
StatusFileSize
new141.02 KB
new90.95 KB

Addressed #22.

Also includes change recommended by @xjm, https://www.drupal.org/project/drupal/issues/3128815#comment-13593362 [#25.1],

Here we're losing information provided by the assertion messages. Can we move them to inline comments above the respective assertions?

sja112’s picture

StatusFileSize
new142.15 KB
new58.34 KB

Updated the patch to fix a nitpick. Updated inline comments, included // Verify that... (etc.).

jungle’s picture

Status: Needs review » Needs work

Thanks, @sja112 for working on this.


...
+    // Verify that the appended #pre_render callback has not yet run before rendering.
...
+    // Verify that body field created when using the UI to create block content types.
...
+    // Verify that field has been deleted and needs purging before configuration synchronization.
...
+    // Verify that the field currently being deleted is not shown in the entity deletions.
...
+    // Verify that interface language negotiation method removed from the stored settings.
...
+    // Verify that the path-frontpage class found on the body tag with french as the active language.
...
+    // Verify that a link generated by the link generator to the current page is marked active.
...
+    // Verify that label follows field and label option class correct for regular checkboxes.
...
+    // Verify that label follows field and label option class correct for regular radios.
...
+    // Verify that label follows field and label option class correct for a checkbox by default.
...
+    // Verify that label tag with required marker precedes required textfield with no title.
...
+    // Verify that label after field and label option class correct for text field.
...
+    // Verify that properly placed the #field_prefix element after the label and before the field.
...
+    // Verify that properly places the #field_suffix element immediately after the form field.
...
+    // Verify that properly places the #description element before the form item.
...
+    // Verify that vertical tab wrappers are not displayed to unprivileged users.
...
+    // Verify that an invalid token with spaces in the token type has not been matched.
...
+    // Verify that simple configuration system.site has a UUID key even though it is
...
+    // Verify that the config_test.dynamic.entity1 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity1 has a dependency on the config_test module.
...
+    // Verify that the config_test.dynamic.entity1 does not have a dependency on the Views module.
...
+    // Verify that the config_test.dynamic.entity1 does not have a dependency on itself.
...
+    // Verify that the config_test.dynamic.entity2 has a dependency on config_test.dynamic.entity1.
...
+    // Verify that the config_test.dynamic.entity3 has a dependency on config_test.dynamic.entity1.
...
+    // Verify that the config_test.dynamic.entity4 has a dependency on config_test.dynamic.entity1.
...
+    // Verify that the config_test.dynamic.entity1 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity2 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity3 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity4 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity1 does not have a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity2 does not have a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity3 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity4 has a dependency on the Node module.
...
+    // Verify that the config_test.dynamic.entity1 does not have a dependency on the content entity.
...
+    // Verify that the config_test.dynamic.entity2 has a dependency on the content entity.
...
+    // Verify that the config_test.dynamic.entity3 has a dependency on the content entity (via entity2).
...
+    // Verify that the config_test.dynamic.entity4 has a dependency on the content entity (via entity3).
...
+    // Verify that the generic entity translation creation hook is run when adding

over 80 chars

sja112’s picture

Assigned: Unassigned » sja112
sja112’s picture

Assigned: sja112 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new142.65 KB
new22.16 KB

@jungle addressed your review points.

Thanks!

jungle’s picture

Status: Needs review » Needs work
StatusFileSize
new1.01 MB
+++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
@@ -205,7 +205,8 @@ public function testBlockViewBuilderViewAlter() {
-    // Verify that the appended #pre_render callback has not yet run before rendering.
+    // Verify that the appended #pre_render callback has not
+    // yet run before rendering.
...
+++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
@@ -74,7 +74,8 @@ public function testBlockContentTypeCreation() {
+    // Verify that body field created when using the UI to
+    // create block content types.

Thanks, @sja112. All changes are wrong. see https://www.drupal.org/docs/develop/standards/api-documentation-and-comm...

Lines containing comments (including docblocks) must wrap as close to 80 characters as possible without going over, with a few exceptions (noted in the Tag Reference below).

If you are using PHPStorm, you can enable the 80 columns guideline.

sja112’s picture

Status: Needs work » Needs review
StatusFileSize
new142.65 KB
new22.09 KB

@jungle,

Thanks for the review and suggestion.

I have addressed

Lines containing comments (including docblocks) must wrap as close to 80 characters as possible without going over, with a few exceptions (noted in the Tag Reference below).

#33 and updated the patch accordingly.

Please review.

jungle’s picture

Status: Needs review » Needs work

Thanks again, but NW still.


must wrap AS CLOSE TO 80 CHARACTERS AS POSSIBLE WITHOUT GOING OVER

Examples:

  1. +++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
    @@ -74,7 +74,8 @@ public function testBlockContentTypeCreation() {
    +    // Verify that body field created when using the UI to create block
    +    // content types.
    

    // Verify that body field created when using the UI to create block content
    // types.

  2. +++ b/core/modules/field/tests/src/Kernel/FieldImportDeleteUninstallTest.php
    @@ -151,7 +151,8 @@ public function testImportAlreadyDeletedUninstall() {
    +    // Verify that field has been deleted and needs purging before
    +    // configuration synchronization.
    

    // Verify that field has been deleted and needs purging before configuration
    // synchronization.

  3. +++ b/core/modules/field_ui/tests/src/Functional/FieldUIDeleteTest.php
    @@ -117,7 +117,8 @@ public function testDeleteField() {
    +    // Verify that the field currently being deleted is not shown in the
    +    // entity deletions.
    

    // Verify that the field currently being deleted is not shown in the entity
    // deletions.

sja112’s picture

StatusFileSize
new142.66 KB
new27.11 KB

@jungle,

I have gone through all the added strings.

I have fixed the #35.1, #35.3, and other related strings.

Haven't fixed #35.2 as the change was leading to 81 characters.

Hopefully, this change fixes all the issues.

Thanks!

sja112’s picture

Status: Needs work » Needs review
jungle’s picture

Assigned: Unassigned » jungle
Status: Needs review » Needs work

Thanks, @sja112. assigning to myself to fix them.

jungle’s picture

Assigned: jungle » Unassigned
Status: Needs work » Needs review
StatusFileSize
new10.08 KB
new142.66 KB

Continue addressing #35

mondrake’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
mrinalini9’s picture

Assigned: Unassigned » mrinalini9
mrinalini9’s picture

Assigned: mrinalini9 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new142.69 KB

Rerolled patch #39, please review.

daffie’s picture

Status: Needs review » Needs work
Issue tags: -Needs reroll

Patch was rerolled.
I have only 1 remark:

+++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
@@ -82,11 +85,15 @@ public function testBlockContentTypeCreation() {
-    $this->assertTrue(isset($field_definitions['body']), "Body field for 'basic' block type created when using the testing API to create block content types.");
+    // Verify that body field for 'basic' block type created when using the
+    // testing API to create block content types.
+    $this->assertArrayHasKey('body', $field_definitions);

Missing the "assertNotNull()" for this change.

daffie’s picture

Some more remarks:

  1. When I do a code base search for "$this->assert(", I still find testing for array elements.
  2. The same for when I search for "$this->assertTrue(isset(".
  3. And for "$this->assertTrue(!isset(".
  4. Also for "$this->assertFalse(isset("
hardik_patel_12’s picture

StatusFileSize
new142.74 KB
new738 bytes

Adding assertNotNull()

+++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
@@ -82,11 +85,15 @@ public function testBlockContentTypeCreation() {
-    $this->assertTrue(isset($field_definitions['body']), "Body field for 'basic' block type created when using the testing API to create block content types.");
+    // Verify that body field for 'basic' block type created when using the
+    // testing API to create block content types.
+    $this->assertArrayHasKey('body', $field_definitions);

as suggested at #43.

naresh_bavaskar’s picture

Assigned: Unassigned » naresh_bavaskar
naresh_bavaskar’s picture

Assigned: naresh_bavaskar » Unassigned
StatusFileSize
new160.87 KB
new22.79 KB

Addressed many of
assertTrue(isset*, assert(isset*
as per #44 comment still there are occurrences which needs to be fixed

naresh_bavaskar’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 47: 3131807-47.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

naresh_bavaskar’s picture

Please ignore #47 patch....it messed existing changes of #45...
Kindly consider #45 whoever picking and going ahead.

mohrerao’s picture

Assigned: Unassigned » mohrerao

Working on remaining replacements

msuthars’s picture

Assigned: mohrerao » msuthars

I'm working on it.

pratik_kamble’s picture

Issue tags: +DIACWJuly2020

Tagging for DIA contribution sprint.

mohrerao’s picture

StatusFileSize
new173.22 KB
new66.5 KB

Apologies. Couldnt complete it earlier.
I did few more replacements and fixed failing tests.
@msuthars, Please review if possible.

mohrerao’s picture

Status: Needs work » Needs review
StatusFileSize
new173.22 KB
new66.5 KB

Fixed lint errors.

Status: Needs review » Needs work

The last submitted patch, 55: 3131807-55.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mohrerao’s picture

Status: Needs work » Needs review
StatusFileSize
new173.47 KB
new3.76 KB

Fixed failing tests and CS errors.

msuthars’s picture

Assigned: msuthars » Unassigned
mondrake’s picture

Status: Needs review » Needs work

I understand that in this patch assertTrue(isset()) is generally converted to two separate assertions - a assertArrayHasKey and a assertNotNull. Although a bit redundant (assertNotNull would fail if the array has not the key), fine with me. That needs to be done conistsently though.

  1. +++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
    @@ -205,9 +205,13 @@ public function testBlockViewBuilderViewAlter() {
    +    $this->assertTrue($build['#prefix'] === 'Hiya!<br>', 'A cached block without content is altered.');
    

    assertSame (invert the order of arguments)

  2. +++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
    @@ -73,7 +73,10 @@ public function testBlockContentTypeCreation() {
    +    // Verify that body field created when using the UI to create block content
    +    // types.
    

    'was' or 'is' created

  3. +++ b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
    @@ -220,7 +221,8 @@ public function testImport() {
    +    // Verify that bartik theme uninstalled during import.
    

    same

  4. +++ b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
    @@ -508,11 +510,11 @@ public function testExtensionValidation() {
    +    $this->assertNotNull($module_data['node']->requires['text'], 'The Node module depends on the Text module.');
    ...
    +    $this->assertNotNull($theme_data['test_subtheme']->requires['test_basetheme'], 'The Test Subtheme theme depends on the Test Basetheme theme.');
    

    needs a assertArrayHasKey also, for consistency

  5. +++ b/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php
    @@ -97,8 +97,10 @@ public function testRelationship() {
    +    $this->assertNotNull($base_tables['users_field_data']);
    ...
    +    $this->assertNotNull($base_tables['watchdog']);
    

    out of scope here

  6. +++ b/core/modules/field/tests/src/Functional/Views/FieldUITest.php
    @@ -98,7 +98,7 @@ public function testHandlerUI() {
    -    $this->assertTrue(isset($dependencies['views.view.test_view_fieldapi']), 'The view is dependent on the field storage.');
    +    $this->assertArrayHasKey('views.view.test_view_fieldapi', $dependencies, 'The view is dependent on the field storage.');
    

    needs a assertNotNull also, for consistency

  7. +++ b/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
    @@ -364,7 +364,7 @@ public function testPurgeField() {
    -    $this->assertTrue(isset($storages[$field_storage->uuid()]), 'The field storage exists and is not deleted');
    +    $this->assertArrayHasKey($field_storage->uuid(), $storages, 'The field storage exists and is not deleted');
    

    same

  8. +++ b/core/modules/field/tests/src/Kernel/FieldImportDeleteUninstallTest.php
    @@ -102,8 +102,8 @@ public function testImportDeleteUninstall() {
    +    $this->assertArrayHasKey($unrelated_field_storage->uuid(), $deleted_storages);
    

    same

  9. +++ b/core/modules/file/tests/src/Functional/FileFieldWidgetTest.php
    @@ -107,7 +107,7 @@ public function testSingleValuedWidget() {
    +    $this->assertArrayHasKey(0, $label, 'Label for upload found.');
    

    same

  10. +++ b/core/modules/filter/tests/src/Functional/FilterFormatAccessTest.php
    @@ -157,9 +157,9 @@ public function testFormatPermissions() {
    +    $this->assertArrayHasKey($this->allowedFormat->id(), $options);
    

    same

  11. +++ b/core/modules/forum/tests/src/Functional/ForumTest.php
    @@ -375,7 +375,7 @@ private function doAdminTests($user) {
    +    $this->assertArrayHasKey(0, $relations_widget, 'Relations widget element found.');
    

    same

  12. +++ b/core/modules/locale/tests/src/Functional/LocaleJavascriptTranslationTest.php
    @@ -100,7 +100,7 @@ public function testFileParsing() {
    +        $this->assertArrayHasKey($str, $source_strings, new FormattableMarkup('Found source string: %source', $args));
    

    same

  13. +++ b/core/modules/menu_link_content/tests/src/Kernel/PathAliasMenuLinkContentTest.php
    @@ -84,7 +84,7 @@ public function testPathAliasChange() {
    +    $this->assertArrayHasKey($menu_link_content->getPluginId(), $tree);
    

    same

  14. +++ b/core/modules/node/tests/src/Functional/NodeLoadMultipleTest.php
    @@ -57,9 +57,11 @@ public function testNodeMultipleLoad() {
    +    $this->arrayHasKey($node1->id(), $nodes);
    

    assertArrayHasKey - wrong method name, and misses assertNull

  15. +++ b/core/modules/node/tests/src/Functional/NodeTranslationUITest.php
    @@ -421,7 +421,7 @@ protected function doTestAlternateHreflangLinks(Node $node) {
    +            $this->assertNotNull($links[0], new FormattableMarkup('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', ['%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()]));
    

    needs a assertArrayHasKey also, for consistency

  16. +++ b/core/modules/node/tests/src/Kernel/NodeAccessLanguageTest.php
    @@ -219,7 +219,9 @@ public function testNodeAccessQueryTag() {
    +    $this->assertNotNull($nids[$node_public->id()]);
    ...
    +    $this->assertNotNull($nids[$node_no_language->id()]);
     
    

    out of scope

  17. +++ b/core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php
    @@ -102,11 +102,17 @@ public function testFormRefill() {
    +        $this->assertTrue($elements[0]->getValue() == $value, "Field $key is set to $value");
    

    assertEquals

  18. +++ b/core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php
    @@ -102,11 +102,17 @@ public function testFormRefill() {
    +        $this->assertTrue(!empty($elements[0]->getAttribute('checked')), "Field $key is checked");
    

    assertNotEmpty

  19. +++ b/core/modules/system/tests/src/Functional/Form/ConfirmFormTest.php
    @@ -78,14 +78,12 @@ public function testConfirmFormWithExternalDestination() {
    -   *
    -   * @return bool
    -   *   Result of the assertion.
        */
       public function assertCancelLinkUrl(Url $url, $message = '', $group = 'Other') {
         $links = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]);
         $message = ($message ? $message : new FormattableMarkup('Cancel link with URL %url found.', ['%url' => $url->toString()]));
    -    return $this->assertTrue(isset($links[0]), $message, $group);
    +    $this->assertArrayHasKey(0, $links, $message);
    +    $this->assertNotNull($links[0]);
       }
    

    add a return TRUE; at the end, keep the return @bool in the doc. Removing the return is a good idea, but there's another issue for that.

  20. +++ b/core/modules/update/tests/src/Kernel/UpdateReportTest.php
    @@ -32,6 +32,7 @@ public function testTemplatePreprocessUpdateReport($variables) {
    +    $this->assertNotNull($variables['no_updates_message']);
    

    out of scope

ravi.shankar’s picture

Assigned: Unassigned » ravi.shankar

Working on this.

ravi.shankar’s picture

Assigned: ravi.shankar » Unassigned
Status: Needs work » Needs review
StatusFileSize
new171.77 KB
new14.37 KB

Here I have tried to made changes as suggested in comment #59, please review.

Status: Needs review » Needs work

The last submitted patch, 61: 3131807-61.patch, failed testing. View results

mondrake’s picture

  1. +++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
    @@ -211,7 +211,7 @@ public function testBlockViewBuilderViewAlter() {
    -    $this->assertTrue($build['#prefix'] === 'Hiya!<br>', 'A cached block without content is altered.');
    +    $this->assertSame('A cached block without content is altered.', $build['#prefix'] === 'Hiya!<br>');
    

    should be $this->assertSame('Hiya!<br>', $build['#prefix'], 'A cached block without content is altered.');

  2. +++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
    @@ -73,7 +73,7 @@ public function testBlockContentTypeCreation() {
    +    // Verify that body field is created when using the UI to create block content
    

    exceeds the 80 chars per row comment limit

  3. +++ b/core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php
    @@ -105,14 +105,14 @@ public function testFormRefill() {
    -        $this->assertTrue($elements[0]->getValue() == $value, "Field $key is set to $value");
    +        $this->assertEquals($elements[0]->getValue() == $value, "Field $key is set to $value");
    

    $this->assertEquals($value, $elements[0]->getValue(), "Field $key is set to $value");

  4. +++ b/core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php
    @@ -105,14 +105,14 @@ public function testFormRefill() {
    -        $this->assertTrue(!empty($elements[0]->getAttribute('checked')), "Field $key is checked");
    +        $this->assertNotEmpty(!empty($elements[0]->getAttribute('checked')), "Field $key is checked");
    

    $this->assertNotEmpty($elements[0]->getAttribute('checked'), "Field $key is checked");

msuthars’s picture

Assigned: Unassigned » msuthars

I'm working on the suggested changes and failed test cases.

msuthars’s picture

StatusFileSize
new171.76 KB
new2.6 KB

Updated the patch with suggested changes. Please review.

msuthars’s picture

Assigned: msuthars » Unassigned
Status: Needs work » Needs review
mondrake’s picture

Status: Needs review » Needs work

I tried grepping the code base with the following regexp, >assert.*\(.*isset\(, and found 232 more results in 87 files. Maybe some are false positives, but at a first glance there are many that still can be converted.

Nit:

+++ b/core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php
@@ -105,14 +105,14 @@
+        $this->assertNotEmpty($elements[0]->getAttribute('checked'), "Field $key is checked"); ¶

This adds a whitespace at the end of the line.

msuthars’s picture

Assigned: Unassigned » msuthars
msuthars’s picture

StatusFileSize
new277.54 KB

Covers almost isset(), but there some use case in which we can't replace them.

msuthars’s picture

Assigned: msuthars » Unassigned
Status: Needs work » Needs review
msuthars’s picture

StatusFileSize
new275.61 KB
new2.74 KB

Revert some isset() changes. Fixed test cases issue.

mondrake’s picture

StatusFileSize
new226.61 KB
new59.85 KB

@msuthars I started reviewing #71 and there were too many unexpected changes. Here restarting from #65 that was almost ready IMHO. 137 more instances to check based on #67.

mondrake’s picture

StatusFileSize
new226.61 KB
new1000 bytes
mondrake’s picture

StatusFileSize
new1023 bytes
new226.61 KB

Status: Needs review » Needs work

The last submitted patch, 74: 3131807-74.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mondrake’s picture

StatusFileSize
new239.97 KB
new22 KB
mondrake’s picture

StatusFileSize
new1.03 KB
new239.97 KB
jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new239.9 KB
new2.78 KB

Thanks @mondrake for pushing this forward!

Fixing failed tests in #77

+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -692,7 +692,7 @@ public function testDataTableFields() {
-    $this->assertArrayNotHasKey('relationship', $data['entity_test_mul']['type']);
+    $this->assertFalse(isset($data['entity_test_mul']['type']['relationship']));

Above this assertFalse(), there is $this->assertArrayNotHasKey('type', $data['entity_test_mul']);. The assertion assertFalse() is unnecessary to me, but instead of removing it, got it reverted.

mondrake’s picture

Status: Needs review » Needs work

Thanks. Approx ~90 more cases to check.

mondrake’s picture

StatusFileSize
new239.72 KB

Alternative fixes for #78

mondrake’s picture

StatusFileSize
new2.04 KB
mondrake’s picture

Status: Needs work » Needs review
StatusFileSize
new275.28 KB
new42.04 KB

This should be it, the remaining ones IMHO should stay as is.

Status: Needs review » Needs work

The last submitted patch, 82: 3131807-82.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mondrake’s picture

Status: Needs work » Needs review
StatusFileSize
new272.89 KB
new7.86 KB

Some fixes.

mondrake’s picture

StatusFileSize
new271.03 KB
new33.2 KB

When $this->xpath is used, it's enough to check if an element with the specific index exists in the array - no need to also check if it's not null.

jungle’s picture

Status: Needs review » Needs work
StatusFileSize
new8.72 KB
new271.05 KB

Thanks, @mondrake!

$ egrep -r "assert.+\(isset|assert.+\(\!isset" .
./core/tests/Drupal/KernelTests/Core/Database/AlterTest.php:    $this->assertFalse(isset($record->$age_field), 'Age field not found, as intended.'); ✅
./core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php:    $this->assertFalse(isset($tables['test']['all_fields']), 'Count query correctly unsets \'all_fields\' statement.'); ❌
./core/tests/Drupal/KernelTests/Core/Database/FetchTest.php:      $this->assertFalse(isset($record->classname), 'Classname field not found, as intended.'); ✅
./core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php:    $this->assertFalse(isset($cached->data->this_should_not_be_in_the_cache)); ✅
./core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php:    $this->assertFalse(isset($fresh_cached->data->this_should_not_be_in_the_cache)); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php:    $this->assertFalse(isset($base_field_definitions['id']->translatable), 'Translatability for the <em>id</em> field is not defined.'); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name->value), new FormattableMarkup('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name[0]->value), new FormattableMarkup('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertTrue(isset($entity->name->value), new FormattableMarkup('%entity_type: Name is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertTrue(isset($entity->name[0]->value), new FormattableMarkup('%entity_type: Name is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertTrue(isset($entity->name[0]), new FormattableMarkup('%entity_type: Name string item is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name[1]), new FormattableMarkup('%entity_type: Second name string item is not set as it does not exist', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertTrue(isset($entity->name), new FormattableMarkup('%entity_type: Name field is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->nameInvalid), new FormattableMarkup('%entity_type: Not existing field is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name[0]), new FormattableMarkup('%entity_type: Name field item is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name[0]->value), new FormattableMarkup('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:    $this->assertFalse(isset($entity->name->value), new FormattableMarkup('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:      $this->assertTrue(isset($entity->name->value), new FormattableMarkup('%entity_type: Name is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:      $this->assertTrue(isset($entity->name), new FormattableMarkup('%entity_type: Name field is set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:      $this->assertFalse(isset($entity->name[0]), new FormattableMarkup('%entity_type: Name field item is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:      $this->assertFalse(isset($entity->name[0]->value), new FormattableMarkup('%entity_type: First name item value is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:      $this->assertFalse(isset($entity->name->value), new FormattableMarkup('%entity_type: Name value is not set.', ['%entity_type' => $entity_type])); ✅
./core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php:          $this->assertTrue(!isset($value) || is_scalar($value) || $value instanceof EntityInterface, $entity_type . ": Value $value_name of item $delta of field $name is a primitive or an entity."); ✅
./core/modules/comment/tests/src/Functional/CommentEntityTest.php:    $this->assertFalse(isset($settings['ajaxPageState']['libraries']) && in_array('comment/drupal.comment-new-indicator', explode(',', $settings['ajaxPageState']['libraries'])), 'drupal.comment-new-indicator library is present.'); ❌
./core/modules/comment/tests/src/Functional/CommentEntityTest.php:    $this->assertFalse(isset($settings['history']['lastReadTimestamps']) && in_array($term->id(), array_keys($settings['history']['lastReadTimestamps'])), 'history.lastReadTimestamps is present.'); ❌
./core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php:      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); ❌
./core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php:      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); ❌
./core/modules/field/tests/src/Functional/EntityReference/EntityReferenceIntegrationTest.php:      $this->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]->getConfigDependencyName(), $dependencies[$key]), new FormattableMarkup('@type dependency @name does not exist.', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()])); ❌
./core/modules/search/tests/src/Functional/SearchAdvancedSearchFormTest.php:        $this->assertFalse(isset($elements[0]) && $elements[0]->getValue() == $value, "Field $key is not set to $value"); ❌
./core/modules/system/tests/src/Functional/System/TokenScanTest.php:    $this->assertFalse(isset($token_wannabes['']['empty token type']), 'An empty token type has not been matched.'); ❌
./core/modules/system/tests/src/Functional/System/TokenScanTest.php:    $this->assertFalse(isset($token_wannabes['']['']), 'An empty token and type has not been matched.'); ❌
./core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php:    $this->assertFalse(isset($formatter->randomValue)); ✅
./core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php:    $this->assertFalse(isset($widget->randomValue)); ✅
./core/modules/node/tests/src/Functional/NodeAccessBaseTableTest.php:          $this->assertIdentical(isset($this->nidsVisible[$nid]), $should_be_visible, strtr('A %private node by user %uid is %visible for user %current_uid on the %tid_is_private page.', [ ❌
./core/modules/views/tests/src/Unit/EntityViewsDataTest.php:    $this->assertFalse(isset($data['entity_test_mul']['type']['relationship'])); ❌
./core/modules/views/tests/src/Kernel/ViewExecutableTest.php:    $this->assertFalse(isset($executable->displayHandlers->get('default')->default_display)); ✅
./core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php:    $this->assertFalse(isset($display['display_options']['fields']['id_broken'])); ❌

According to the output of egrep -r "assert.+\(isset|assert.+\(\!isset" above after rerolled the patch, it looks like there are a few left to replace/double-check, marked ❌ at the end for those ones, FYI. Attaching the rerolled patch.

mondrake’s picture

Assigned: Unassigned » mondrake

on this

mondrake’s picture

Status: Needs work » Needs review

./core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php: $this->assertFalse(isset($tables['test']['all_fields']), 'Count query correctly unsets \'all_fields\' statement.');

./core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php: $this->assertFalse(isset($display['display_options']['fields']['id_broken']));

./core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php:      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); 
./core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php:      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); 
./core/modules/system/tests/src/Functional/System/TokenScanTest.php:    $this->assertFalse(isset($token_wannabes['']['empty token type']), 'An empty token type has not been matched.'); 
./core/modules/system/tests/src/Functional/System/TokenScanTest.php:    $this->assertFalse(isset($token_wannabes['']['']), 'An empty token and type has not been matched.'); 

./core/modules/views/tests/src/Unit/EntityViewsDataTest.php: $this->assertFalse(isset($data['entity_test_mul']['type']['relationship']));

./core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php: $this->assertFalse(isset($display['display_options']['fields']['id_broken']));

in these cases, the array would miss even keys earlier than the last sub-key, the test would fail on missing index, so I preferred to keep as is for readibility

./core/modules/comment/tests/src/Functional/CommentEntityTest.php: $this->assertFalse(isset($settings['history']['lastReadTimestamps']) && in_array($term->id(), array_keys($settings['history']['lastReadTimestamps'])), 'history.lastReadTimestamps is present.');

this and the other ones that have an ANDed assertion I'd rather leave to a follow-up

mondrake’s picture

Assigned: mondrake » Unassigned
longwave’s picture

Status: Needs review » Needs work

Reviewed about half this before I ran out of steam. Detailed comments are below.

I have a feeling that this is getting too big and complicated to try and solve in one issue as there is a lot of subtle changes here and reviewing it is already hard. I suggest that we can break some of this out into separate issues:

  1. Changes to helper methods only
  2. Calls to assertTrue(... && ...) which can be broken into multiple assertions
  3. Functional test patterns similar to
    $something = $this->xpath(...);
    $this->assertArrayHasKey(0, $something);
    

    which would be much better off as $this->assertSession()->elementExists() or similar

The latter case I feel most strongly about, as all we are doing in this issue is rearranging assertTrue to assertArrayHasKey when in fact the assertion really feels like it should be rewritten entirely - elementExists is far more readable.

If we don't do any of those, or if it is still too big after that, how about breaking it down by test type, e.g. splitting out Kernel and Functional tests?

  1. +++ b/core/modules/aggregator/tests/src/Functional/AggregatorRenderingTest.php
    @@ -62,12 +62,12 @@ public function testBlockLinks() {
         $links = $this->xpath('//a[@href = :href]', [':href' => reset($items)->getLink()]);
    -    $this->assert(isset($links[0]), 'Item link found.');
    +    $this->assertArrayHasKey(0, $links, 'Item link found.');
    

    Do we need a followup to change this sort of thing to $this->assertSession()->linkByHrefExists()?

  2. +++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
    @@ -205,9 +205,13 @@ public function testBlockViewBuilderViewAlter() {
    +    $this->assertArrayHasKey('#prefix', $build);
    +    $this->assertNotNull($build['#prefix']);
    +    $this->assertSame('Hiya!<br>', $build['#prefix'], 'A cached block without content is altered.');
    

    assertNotNull seems redundant here

  3. +++ b/core/modules/block/tests/src/Kernel/BlockViewBuilderTest.php
    @@ -266,7 +270,8 @@ public function testBlockViewBuilderBuildAlter() {
    +      $this->assertArrayHasKey('#create_placeholder', $build);
    +      $this->assertNotNull($build['#create_placeholder']);
           $this->assertIdentical($value, $build['#create_placeholder']);
    

    assertNotNull seems redundant here

  4. +++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
    @@ -73,7 +73,10 @@ public function testBlockContentTypeCreation() {
    -    $this->assertTrue(isset($field_definitions['body']), 'Body field created when using the UI to create block content types.');
    +    // Verify that body field is created when using the UI to create block
    +    // content types.
    +    $this->assertArrayHasKey('body', $field_definitions);
    +    $this->assertNotNull($field_definitions['body']);
    

    Is the not null check strictly necessary here? Feels better to either just assertArrayHasKey or also assert a specific type rather than just "not null".

  5. +++ b/core/modules/ckeditor/tests/src/Functional/CKEditorLoadingTest.php
    @@ -207,10 +207,14 @@ public function testLoadingWithoutInternalButtons() {
    +    $this->assertArrayHasKey('customConfig', $editor_settings);
    +    $this->assertNotNull($editor_settings['customConfig']);
    +    $this->assertArrayHasKey('entities', $editor_settings);
    +    $this->assertNotNull($editor_settings['entities']);
    +    $this->assertArrayHasKey('allowedContent', $editor_settings);
    +    $this->assertNotNull($editor_settings['allowedContent']);
    +    $this->assertArrayHasKey('disallowedContent', $editor_settings);
    +    $this->assertNotNull($editor_settings['disallowedContent']);
    

    Same

  6. +++ b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
    @@ -103,9 +103,15 @@ public function testInstallUninstall() {
    +    // Verify that the comment module will be disabled.
    +    $this->assertArrayHasKey('comment', $modules_to_uninstall);
    +    $this->assertNotNull($modules_to_uninstall['comment']);
    +    // Verify that the File module will be disabled.
    +    $this->assertArrayHasKey('file', $modules_to_uninstall);
    +    $this->assertNotNull($modules_to_uninstall['file']);
    +    // Verify that editor module will be disabled.
    +    $this->assertArrayHasKey('editor', $modules_to_uninstall);
    +    $this->assertNotNull($modules_to_uninstall['editor']);
    

    Same

  7. +++ b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
    @@ -149,7 +149,8 @@ public function testImport() {
    -    $this->assertTrue(isset($GLOBALS['hook_cache_flush']));
    +    $this->assertArrayHasKey('hook_cache_flush', $GLOBALS);
    +    $this->assertNotNull($GLOBALS['hook_cache_flush']);
    

    Same

  8. +++ b/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
    @@ -266,8 +266,10 @@ public function testPurgeWithDeletedAndActiveField() {
    +    $this->assertNotNull($fields[$deleted_field_uuid]);
    

    This feels like it should be assertInstanceOf

  9. +++ b/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
    @@ -397,7 +399,9 @@ public function testPurgeFieldStorage() {
    +    $this->assertNotNull($fields[$field->uuid()]);
    

    Same

  10. +++ b/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
    @@ -407,7 +411,9 @@ public function testPurgeFieldStorage() {
         $storages = \Drupal::entityTypeManager()->getStorage('field_storage_config')->loadByProperties(['uuid' => $field_storage->uuid(), 'include_deleted' => TRUE]);
    -    $this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is not deleted');
    +    $this->assertArrayHasKey($field_storage->uuid(), $storages);
    +    $this->assertNotNull($storages[$field_storage->uuid()]);
    +    $this->assertFalse($storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is not deleted');
    

    Extracting $uuid to a variable might feel cleaner

  11. +++ b/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
    @@ -359,8 +359,9 @@ public function testEntityReferenceConfigEntity() {
    +    $this->assertArrayHasKey('relationship', $views_data['entity_test__field_test_data']['field_test_data']);
    +    $this->assertNotNull($views_data['entity_test__field_test_data']['field_test_data']['relationship']);
    

    Again I don't understand the not null check here. I realise that assertTrue(isset()) will do a non NULL check and assertArrayHasKey doesn't care if the value is NULL, but while that is the semantics of the existing test, is that really what was intended?

  12. +++ b/core/modules/file/tests/src/Functional/FileFieldWidgetTest.php
    @@ -107,7 +107,7 @@ public function testSingleValuedWidget() {
         $label = $this->xpath('//label[@for="' . $input[0]->getAttribute('id') . '"]');
    -    $this->assertTrue(isset($label[0]), 'Label for upload found.');
    +    $this->assertArrayHasKey(0, $label, 'Label for upload found.');
    

    More like this that I think should just be e.g. $this->assertSession()->elementExists()?

  13. +++ b/core/modules/language/tests/src/Functional/LanguageNegotiationInfoTest.php
    @@ -156,7 +158,9 @@ public function testInfoAlterations() {
         // Check that unavailable language negotiation methods are not present in
         // the negotiation settings.
         $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled');
    -    $this->assertFalse(isset($negotiation[$test_method_id]), 'The disabled test language negotiation method is not part of the content language negotiation settings.');
    +    // Verify that the disabled test language negotiation method is not part of
    +    // the content language negotiation settings.
    +    $this->assertArrayNotHasKey($test_method_id, $negotiation);
    

    Second comment just duplicates the first IMO

  14. +++ b/core/modules/locale/tests/src/Kernel/LocaleStringTest.php
    @@ -147,11 +147,17 @@ public function testStringSearchApi() {
    -    $this->assertTrue($found && isset($found->language) && isset($found->translation) && !$found->isNew(), 'Translation not found searching by source and context.');
    +    $this->assertNotNull($found);
    +    $this->assertNotNull($found->language);
    +    $this->assertNotNull($found->translation);
    +    $this->assertFalse($found->isNew(), 'Translation not found searching by source and context.');
    

    I wonder if a way of breaking this down is to do assertTrue(... && ...) in a separate issue? These are all quite similar and would simpler to get in.

  15. +++ b/core/modules/node/tests/src/Functional/NodeLoadMultipleTest.php
    @@ -57,9 +57,12 @@ public function testNodeMultipleLoad() {
    +    $this->assertArrayHasKey($node1->id(), $nodes);
    +    $this->assertNotNull($nodes[$node1->id()]);
    +    $this->assertArrayHasKey($node2->id(), $nodes);
    +    $this->assertNotNull($nodes[$node2->id()]);
    +    $this->assertArrayHasKey($node4->id(), $nodes);
    +    $this->assertNotNull($nodes[$node4->id()]);
         foreach ($nodes as $node) {
           $this->assertIsObject($node);
         }
    

    I don't think we need to care about assertNotNull here if we are checking the type in the following loop.

  16. +++ b/core/modules/rest/tests/src/Functional/Views/StyleSerializerTest.php
    @@ -611,7 +612,8 @@ public function testLivePreview() {
    -    $this->assertTrue(!isset($build['#markup']) && $rendered_json == $expected, 'Ensure the previewed json is escaped.');
    +    $this->assertArrayNotHasKey('#markup', $build, 'Ensure the previewed json is escaped.');
    +    $this->assertEquals($expected, $rendered_json, 'Ensure the previewed json is escaped.');
    

    Should we drop the $message arguments here?

  17. +++ b/core/modules/system/tests/src/Functional/Routing/RouterTest.php
    @@ -97,17 +97,20 @@ public function testFinishResponseSubscriber() {
    +    $this->assertArrayHasKey('X-Drupal-Cache-Contexts', $headers);
    +    $this->assertNotNull($headers['X-Drupal-Cache-Contexts']);
    +    $this->assertArrayHasKey('X-Drupal-Cache-Tags', $headers);
    +    $this->assertNotNull($headers['X-Drupal-Cache-Tags']);
    +    $this->assertArrayHasKey('X-Drupal-Cache-Max-Age', $headers);
    +    $this->assertNotNull($headers['X-Drupal-Cache-Max-Age']);
    

    Can headers even be NULL? I think they are always strings?

  18. +++ b/core/modules/system/tests/src/Functional/System/SiteMaintenanceTest.php
    @@ -64,7 +64,8 @@ public function testSiteMaintenance() {
         $links = $this->xpath('//script[contains(@src, :href)]', [':href' => '/core/misc/drupal.js']);
    -    $this->assertFalse(isset($links[0]), 'script /core/misc/drupal.js not in page');
    +    // Verify that the script /core/misc/drupal.js not in page.
    +    $this->assertArrayNotHasKey(0, $links);
    

    This would be so much more readable as some kind of elementExists check.

  19. +++ b/core/modules/system/tests/src/Functional/System/TokenScanTest.php
    @@ -30,13 +30,20 @@ public function testTokenScan() {
         $this->assertFalse(isset($token_wannabes['']['empty token type']), 'An empty token type has not been matched.');
         $this->assertFalse(isset($token_wannabes['']['']), 'An empty token and type has not been matched.');
    -    $this->assertTrue(isset($token_wannabes['node']), 'An existing valid token has been matched.');
    +    // Verify that an existing valid token has been matched.
    +    $this->assertArrayHasKey('node', $token_wannabes);
    +    $this->assertNotNull($token_wannabes['node']);
    

    Did we miss the assertFalse() here?

mondrake’s picture

Thanks a lot @longwave.

I agree, this has become too large for a single issue.

I’ll think a way to spin off some separate issues, the one for xpath to start with.

AFK at the moment, if anyone feels like taking that feel free.

mondrake’s picture

Unpostponed #3129002: Replace usages of deprecated AssertLegacyTrait::assert() since I think that's the better currently open issue where to start tackling

Functional test patterns similar to

$something = $this->xpath(...);
$this->assertArrayHasKey(0, $something);

which would be much better off as $this->assertSession()->elementExists() or similar

when that's agreed a lot of similar instance could be addressed similarly.

mondrake’s picture

Status: Needs work » Postponed
Related issues: +#3166450: Split assertTrue using && into multiple assertions
mondrake’s picture

mondrake’s picture

StatusFileSize
new249.84 KB

Just a reroll.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

mondrake’s picture

Status: Postponed » Needs work

#3166450: Split assertTrue using && into multiple assertions is in, maybe this can be worked on again

mondrake’s picture

Status: Needs work » Postponed

Actually no, this one is still too much overlapping with #3167880: [meta] Convert assertions involving use of xpath to WebAssert, where possible.

mondrake’s picture

StatusFileSize
new229.03 KB

A reroll anyway.

mondrake’s picture

Rerolled and chenged to MR workflow

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mondrake’s picture

Rerolled

mondrake’s picture

Title: Replace assertions involving calls to isset() with assertArrayHasKey()/assertArrayNotHasKey » Replace assertions involving calls to isset() with more appropriate assertions
Status: Postponed » Needs work
longwave’s picture

Status: Needs work » Needs review

Fixed all cases that I can find by looking for >assert.*isset, except EntityFieldTest which I think makes more sense left alone and a few with complex boolean assertions.

CommentEntityTest has been simplified to such an extent I'm not sure it was ever testing anything useful.

mondrake’s picture

Status: Needs review » Needs work

I started reviewing the MR, then I realized we probably better discuss here first:

IMHO we should:
a) avoid using assertArrayHasKey() with an immediately following assertNotNull(). The latter also includes check for the former.
b) revert the removals of the $message argument where it is supported by the method - we do not have any consensus to remove them massively and when we could get there we could have a separate issue.

longwave’s picture

Agree with both points. There is no need for two assertions; assertNotNull will also fail if the key doesn't exist. And yes, let's deal with the messages elsewhere. I think it's fair to replace t() or FormattableMarkup with plain strings if you find it here though.

longwave’s picture

Status: Needs work » Needs review

I think all issues are addressed.

Pleased that we also found a bug in UserAccountFormFieldsTest here where we were testing a nonexistent form element all along.

daffie’s picture

Status: Needs review » Needs work

The testbot is failing.

longwave’s picture

Status: Needs work » Needs review

Fixed test failures, I hope.

mondrake’s picture

Status: Needs review » Needs work

Just a few more checks please, then this is pretty much ready.

mondrake’s picture

Issue summary: View changes

Found a few more instances, in

core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php and
core/modules/views/tests/src/Unit/EntityViewsDataTest.php

longwave’s picture

Status: Needs work » Needs review

Thanks for reviewing. I think I've fixed up everything except EntityFieldTest. I noted this in #105; to me this makes sense to leave as it is, as the comment above the section in question states "Test using isset(), empty() and unset()" and this is explicitly checking the magic methods __isset() and friends on the entity field objects. Apart from the use of FormattableMarkup the test reads well to me and I think would lose readability by changing it to use other assertions.

EntityViewsDataTest was a strange one, I have just deleted this assertion. It wasn't testing anything and should have been removed in https://git.drupalcode.org/project/drupal/-/commit/376fb615d7f862aade6e7... as far as I can see - the type property was removed from entity_test_mul here as were two other assertions checking this, but the negative assertion was left in place.

The errors we have found while fixing this makes me think a good use of static analysis would be to detect asserting for non-existence in arrays when we don't assert for existence of the parent item first. This would have caught at least two bugs that were discovered here.

mondrake’s picture

Thanks for the explanations @longwave. This looks great to me now. I'd be +1 on RTBC but I do not think I can set it myself.

longwave’s picture

I went through the whole patch as of #104 and fixed or upgraded parts that I thought needed to be changed, so to me that counts as a review of an earlier version. I think if you have reviewed the whole patch again since I made the recent changes, it's OK for you to mark RTBC - as it's quite a large set of changes I'm not sure if we will recruit anyone else to look at it before it ends up with merge conflicts.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community

Agreed. Let’s see if core committers do as well.

mondrake’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

Needs a reroll.

mondrake’s picture

Issue tags: -Needs reroll

Rerolled, waiting for test run as recent runs were red

mondrake’s picture

Assigned: Unassigned » mondrake

on this

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review

Fixed the test failure.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Changes by @mondrake look good to me. We only care about the header keys and not their values in the debug_cacheability_headers test (the header values themselves are tested in a number of elsewhere) so I think this change is OK.

mondrake’s picture

Rerolled

mondrake’s picture

Rerolled

mondrake’s picture

Rerolled

mondrake’s picture

Status: Reviewed & tested by the community » Needs work

There's one fail now

mondrake’s picture

Status: Needs work » Reviewed & tested by the community

Fixed, one line was changed to comment in EntityViewsDataTest before being moved from Unit to Kernel, reflected here.

mondrake’s picture

Title: Replace assertions involving calls to isset() with more appropriate assertions » [D9.3 beta - w/c Nov 8, 2021] Replace assertions involving calls to isset() with more appropriate assertions

There's no explict input from core committers here, but I assume given the size of this patch it has to wait for a beta disruptive patch window.

longwave’s picture

Bumping for visibility, patch still applies cleanly for me.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

This one needs a re-roll after the other three disruptive issues went in.

Tried a 3-way merge but to no avail.

	both modified:   core/modules/system/tests/src/Functional/Form/ElementsTableSelectTest.php
	both modified:   core/modules/system/tests/src/Functional/Form/FormTest.php
	both modified:   core/modules/system/tests/src/Functional/System/SiteMaintenanceTest.php
mondrake’s picture

Issue summary: View changes

Corrected IS example, thanks @berdir on Slack

mondrake’s picture

Status: Needs work » Needs review

Rerolled. I agree with @Berdir a lot of these assertions should be improved with more strict checks, but I am afraid it will too big a change to be done here.

My suggestion would be to wait for #3131348: Replace assertions involving calls to empty() with assertEmpty()/assertNotEmpty()/assertArrayNotHasKey(), too, then have appropriate issues to convert instances of assertNotNull, assertArrayHasKey, assertNotEmpty with more strict ones.

Rome was not built in a day. :)

longwave’s picture

Had another scan through the MR and added some comments to ones. I think I agree with @Berdir here that the assertNotNull() is not really meaningful in a lot of cases; it feels like either assertArrayHasKey() is what we really want in the simple case (especially if nearby we assertArrayNotHasKey() as well) or an actual value assertion if we want a more thorough test.

There is a lot of good cleanup here - the response header and any xpath ones for example - but I wonder if we could maybe split the scope of this and that would make it easier to get in outside of a disruptive patch window and also give us more time to think about the non-trivial cases and fix them properly?

mondrake’s picture

Title: [D9.3 beta - w/c Nov 8, 2021] Replace assertions involving calls to isset() with more appropriate assertions » [meta] Replace assertions involving calls to isset() with more appropriate assertions
Category: Task » Plan
Status: Needs review » Active

Alright, let's make a meta of this issue then, and split issues with smaller scope.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mondrake’s picture

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mondrake’s picture

Status: Active » Closed (won't fix)

A few things were fixed in spin-offs, and what's left out is probably not worth pursuing based on the comments. Wontfix then, if anyone disagrees please open a new issue with new scope. Thx

mondrake’s picture

Status: Closed (won't fix) » Closed (outdated)

Probably outdated is a better status.

longwave’s picture

Status: Closed (outdated) » Fixed

Closing as fixed and assigning credit to all contributors.

longwave’s picture

Issue tags: -Needs reroll

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.