Repository navigation
Bugfix Issue 979 TcView Foreach On Null KeywordSet
Rendering a test case that has no keywords — neither own nor inherited
from an ancestor testsuite — fired PHP warnings that landed in the Event
Viewer / events table:
E_WARNING foreach() argument must be of type array|object, null given
- in lib/functions/testcase.class.php - Line 9347
Plus, for every keywordless test case, a set of str_replace() parameter
deprecations at testcase.class.php:9358 (Passing null to parameter #1/#2).
The symptoms only appear on PHP 8.x (E_WARNING / E_DEPRECATED). Keywordless TCs are the common case on a fresh database.
renderSpecialTSuiteKeywords() (lib/functions/testcase.class.php:9313)
builds a static cache:
$skwSet[$tcase_id] = $this->getPathLayered($tcase_id,$optSKW);getPathLayered() (testcase.class.php:5578) initialises $xtree = null
and only fills it for nodes whose node_table == 'testsuites' (line 5602).
Two failure modes:
-
Test case attached directly under the project root —
get_path()returns[testproject, testcase]with no testsuite node, so$xtreestaysnullandgetPathLayered()returnsnull.$skwSetbecomes the array[tcase_id => null], which is notnull, so the guardif( is_null($skwSet) ) return;(old line 9330) never triggers. The doubleforeachat line 9346-9347 then iterates the null element →E_WARNING foreach() ... null givenat 9347. This is the primary reported symptom. -
No
@#special keyword anywhere in the chain — the cache holds testsuite entries whosedata_managementisnull, so nothing ever gets appended to$searchSet/$replaceSet, which staynull→str_replace(null,null,...)raises deprecations at 9358 for all keywordless TCs (including suite children).
File: lib/functions/testcase.class.php — 3 changes in
renderSpecialTSuiteKeywords():
-
Default a
nullgetPathLayered()result to an empty array when filling the cache (fixes theforeach()E_WARNING):$skwSet[$tcase_id] = $this->getPathLayered($tcase_id,$optSKW); if( is_null($skwSet[$tcase_id]) ) { $skwSet[$tcase_id] = array(); }
-
Harden the early-return guard from
is_null($skwSet)toempty($skwSet)(the array is nevernullonce an element is stored). -
Initialise the search/replace sets to
array()instead ofnull(fixes thestr_replace()deprecations for keywordless TCs):$searchSet = array(); $replaceSet = array();
Behaviour is unchanged when special keywords DO exist — str_replace() on an
empty array of replacements simply leaves summary/preconditions untouched.
No i18n impact, no user-facing strings changed.
| File | Change |
|---|---|
lib/functions/testcase.class.php |
renderSpecialTSuiteKeywords() — null→array() cache default, empty() guard, array() search/replace init (7+ / 4-) |
docs/screenshots/issue-979-tcview-no-warning-postfix.png |
post-fix TC view render (new) |
docs/screenshots/issue-979-event-viewer-postfix.png |
Event Viewer after post-fix renders (new) |
Commit bed7f8561 on branch fix/issue-979.
-
Primary symptom (before): harness calling
renderSpecialTSuiteKeywords()for a root-attached keywordless TC capturedtestcase.class.php:9347 foreach() argument must be of type array|object, null givenplus 4str_replace()deprecations; the browser produced the same line-9347 event (event id 24,10:02:00). -
Primary symptom (after): same harness → 0 warnings from
testcase.class.php; browser re-render ofarchiveData.php?edit=testcase&id=50→ clean TC view, no new9347/9358event in the Event Viewer. -
Keywordless suite child (TC30): 4
str_replace()deprecations → 0. -
Positive control: keyword
@#DYNon the ancestor suite → summarymy @#DYN summaryrenders asmy DYN:Suite summary, still 0 warnings → replacement logic intact. -
Syntax gate:
php -l→No syntax errors detected. -
Blast radius:
renderSpecialTSuiteKeywordsis referenced only insidetestcase.class.php(3 occurrences: 1 def + 2 calls at lines 2944 / 4324); neither signature nor output contract changed. - Code review subagent: PASS (see review notes).
-
Event Viewer: no new Error/Warning from this fix. Unrelated pre-existing
template warnings (label keys,
testcase.class.php:7490) remain tracked separately.


Suite Regression — Issue #979 (7/7 PASS) appended to tmp/TLU_Test_Cases.md:
root-attached keywordless TC harness, suite-child keywordless harness, positive
@# keyword control, browser render of the affected view, Event Viewer
accounting, php -l gate, and diff-scope check.