Problem/Motivation
There is no need to use t() in tests, unless we're testing translations, however in core we do not follow this consistently, which does not set a good example for new contributions.
A rough estimation, adapted from that one of @longwave, shows that here are 4247 instances of this as of 22b08be669260979ec6a45676b16be79c89719eb:
$ find core -type f -iname '*Test.php' | xargs grep '[^a-zA-Z]t(' | wc -l
4247
We will need to ensure to leave t() where the test actually tests the translation system.
Proposed resolution
Use find core -type f -iname '*Test.php' | xargs grep '[^a-zA-Z]t(' | grep -v 'modules/locale' | grep -v 'package_manager' | grep -v 'modules/language' | grep -vi translation | grep -v "php:\s*\*" | grep -v "php:\s*\/\/" | nl
The 6 files not changed are
1 core/modules/mysql/tests/src/Unit/InstallTasksTest.php
2 core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
3 core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php
4 core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php
5 core/tests/Drupal/KernelTests/Core/Common/XssUnitTest.php
6 core/tests/Drupal/KernelTests/Core/TypedData/TypedDataTest.php
All but EntityTest are related to translations. EntityTest is not changed because the 'entity_test' module is well used in contrib.
Remaining tasks
Review changes
Commit
Open a Coding standards issue to consider adding a sniff to warn when t() is used in tests.
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #56 | find_t.sh_.txt | 2.54 KB | quietone |
| #2 | remove_t_list.txt | 631.96 KB | manuel garcia |
Issue fork drupal-3133726
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:
- 3133726-meta-remove-usage
changes, plain diff MR !10995
Comments
Comment #2
manuel garcia commentedComment #3
Kumar Kundan commentedComment #4
Kumar Kundan commentedComment #5
dwwThanks for opening this! Note that the estimate in the summary was from @longwave in Slack. I was just pasting it into the other issue. Updating summary to give credit where due.
Given the huge # of required changes here, we might need to convert this into a meta and split up the task by core module or subsystem or something. TBD.
Comment #6
jungleNow the scope matters, IMHO, before proceeding, to get a confirmation about the scope from committer(s) is important. Filing issue per module/per component is not encouraged according to the current scope policy, or issues filed will be rejected/marked as won't fix, that would be a waste of time to contributors.
Thanks!
Comment #7
manuel garcia commentedRe #5/#6: Added that to the remaining tasks :)
Comment #8
longwaveCould we scope this by method call? e.g. removing
t()fromdrupalPostForm()would seem to be fairly straightforward to do and review, and that would cover a large number of the calls discovered in #2.Comment #9
longwave2234 changes that mostly look correct just with
Comment #10
cburschkaI guess the translations with arguments should be replaced with
new FormattableMarkup()Comment #11
dww+1 to #9. Should we move that to the first child issue and make this a sub-meta? ;)
Comment #12
longwaveOpened #3145005: [November 9, 2020] Remove uses of t() in drupalPostForm() calls to kick this off.
Comment #13
longwaveAlso opened #3145418: [November 9, 2020] Remove uses of t() in assertText() calls but I think I should wait for feedback on this scoping until we go further down this path, there is a long tail after this:
Comment #14
tr commentedThere's already in issue open for this ... #2552067: Remove t() from assertion messages in tests ... has been open for five years.
It's also something that has been addressed time and again for more than 10 years, e.g.:
#500866: [META] remove t() from assert message
#2555145: Remove t() from pass/fail assertions in tests
... and probably a dozen others.
Rather than continuing to expend effort repeatedly trying to correct this, shouldn't we develop a sniff and then be done with it?
Comment #15
jungleCombined with the comment #10 and the comment #14. I would suggest
t()in tests and make it auto-fixible byphpcbft()tonew FormattableMarkup()if possiblet()usages wheret()has to be called by usingphpcs:ignoreComment #16
joseph.olstadIf I/we install Drupal in another language using these changes and run these tests, the tests will fail.
Comment #17
cburschkaEach test installs a new site based on a test-specific profile; they do not use the existing configuration and therefore always run in the default language.
Comment #18
joseph.olstadah ok, makes sense then. Thanks for the explanation
Comment #19
joseph.olstadhowever ya, it might be useful to test profile installations in another language at some point?
not sure if the performance gains are worth it to make these changes, it is not that expensive.
Comment #20
tr commented@joseph.olstad: All those things have been discussed again and again for >10 years. PLEASE let's not re-open that - it was decided long ago that this is the right thing to do. And it has been documented as the core policy for all this time. For example in:
https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-browser-te...
The problem we have here is that t() keeps getting used in new tests, to a point where there are thousands of usages again. We need a way to make sure this STAYS fixed if we are going to put in all the work trying to fix it again.
This current issue is about "Remov(ing) usage of t() in tests not testing translation" - no one is saying that you can't use t() when testing translation-related things, but also be aware that testing the translation system is something that should be done in translation system tests, not in every single test of every single feature in core and contrib.
Comment #21
alexpottI'm all for removing t() from tests but #3153168: Remove uses of t() in setLabel() and setDescription() calls is different. It's removing it from modules that support tests. I'm not sure the case is as clear cut there. People learn from this code and use copy&paste. I think we should exclude such fixtures from this meta. See #3157938: Use t() for #title and #description in tests and test modules for an issue that wants to add t() to such code.
Comment #23
longwaveWe've done nearly 75% of these cases now, there were 4247 when we started:
Comment #25
tr commentedWoo hoo, down to 1035.
Comment #26
longwaveOne way of tackling the remainder might be to try and handle all t() that use only plain strings (no replacement values) in a single issue:
Comment #27
longwaveIf we ignore
assertEquals()which is being dealt with in #3153468: Strip HTML tags when using assertEquals() to compare markup we are left with 279, and many of these are false positives:Comment #30
longwaveWe are down to 201 remaining instances:
Comment #31
longwaveA lot of the remaining ones are %-placeholdered strings, e.g.
where we can convert to either
or
Not sure which is preferable.
Comment #33
quietone commentedTagging for coding standards and moving to the 'other' component where such issues live.
Comment #35
longwave#3337295: Remove remaining uses of t() in assertEquals() calls landed.
I think we are down to the final few stragglers, opened #3410128: Remove remaining unnecessary uses of t() in tests to cover those.
I also am leaning towards closing #3153168: Remove uses of t() in setLabel() and setDescription() calls as won't fix as we are effectively testing that APIs can receive TranslatableMarkup, as they would outside of tests.
Comment #40
smustgrave commentedComment #48
quietone commentedComment #51
quietone commentedClosed that related issue and moved credit here
Comment #52
quietone commentedAnd the number of instances has risen since #30.
Comment #53
quietone commentedTrying to confirm that this is done, since #3410128: Remove remaining unnecessary uses of t() in tests has been committed. I searched Test files using the grep in that issue and ignored all the files listed in that IS that are valid uses of t(). Then ignored the tests in package_manager because which isn't testing translations but tests validation messages where the methods have a type hint for TranslatableMarkup. That left 16 files with 26 instances of t() that need to be checked.
Comment #55
quietone commentedOf those, 13, is testing translations. The rest includes some that were missed in #3410128: Remove remaining unnecessary uses of t() in tests and others from commits made this month. There is nothing to prevent added other unnecessary uses of t() in tests so lets' fix this last group and stop chasing new introduced cases. Right now, we can only rely on review to prevent the addition of more unnecessary uses of t() in tests.
Comment #56
quietone commentedHere is the script I used for finding usages of t() in tests.
Comment #57
quietone commentedPostponing until the issues to fix "DrupalPractice.Objects.GlobalFunction" in tests is complete. #3113904: [META] Replace t() calls inside of classes
Comment #58
quietone commentedComment #59
smustgrave commentedUsed the script provided and believe all instances have been found.
Comment #60
catchThis appears to be removing one assertion entirely instead of updating it to not use t().
Comment #61
quietone commentedWork is not needed, the line is a duplicate.
Comment #64
nod_Committed e4df448 and pushed to 11.x. Thanks!
Comment #66
xjmAmending attribution.