Closed (fixed)
Project:
Drupal core
Version:
10.1.x-dev
Component:
phpunit
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
17 Aug 2019 at 21:17 UTC
Updated:
21 Mar 2023 at 14:14 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
mile23Maybe a duplicate of #3075648: Refactor TestDatabase::lastTestGet to use dynamic queries
Comment #3
mondrakeOne things that pops up looking at TestDatabase right now is that it is doing many things in the same class. In particular, it
- sets up the database for the SUT, and
- manages (a part) of the test run where it logs test results, tracks db prefixes, keeps the {simpletest*} schema definitions, etc within the SITE database
The second part, though, it is still all over the place, see the table below to see which classes/scripts are doing what with the {simpletest*} tables:
One initial idea here could be to try and have a class (say
TestTracker?) abstracting away the DB implementation details from the consuming code, and providing them a set of necessary methods. This way in the future the structure of the {simpletest*} tables could become totally internal (actually, maybe we won't even need db at the end of the day).Comment #4
mondrakeHere's an initial idea - quite rough, but I thought I share this at this point to get some feedback if this all makes any sense.
In general, with the table
{simpletest_test_id}we trace the status of the last db prefix used by a test_id, and with{simpletest}we log the messages of the test execution.We have already a
TestStatusclass, even if it has only a static method to map test status codes to some human readble status strings.If we change that class to become an object that bears the status of a test and of the logged messages, and manage within that class all the interaction with the database, then we can abstract away the DB API calls from consuming code. Here I am only trying with 'insert' and 'update' operations - for 'delete' it's better wait for #2800267: Turn simpletest_clean*() functions into a helper class, and for 'select' wait for #3075648: Refactor TestDatabase::lastTestGet to use dynamic queries, and further feedback here.
Actually, potentially even the schema for creating the tables could be advocated by the class itself, so creating the tables on-demand rather than at simpletest install or by run-test.sh.
Comment #5
mondrakeComment #6
mondrakeComment #7
mondrakeUpdate after commit of #3075648: Refactor TestDatabase::lastTestGet to use dynamic queries.
I thought here to add a new
TestRunclass, instead of expandingTestStatus. The idea is that a TestRun object bears a status and a message log, both being stored in db tables as the test run goes. The object abstracts away all the interaction with the tables. Here doing that for 'select', 'insert' and 'update' DB calls. Leaving out 'delete' ATM while waiting for #2800267: Turn simpletest_clean*() functions into a helper class.This approach moves along the lines of what @larowlan was suggesting in #3075648-8: Refactor TestDatabase::lastTestGet to use dynamic queries and #3074043-19: Move simpletest.module DB-related functions to TestDatabase, deprecate:
since here
$db_prefix = TestDatabase::lastTestGet($child['test_id'])['last_prefix']becomes$test_run->getDatabasePrefix().Interdiff would not make much sense.
Comment #9
mondrakeAddressing test failures.
Comment #10
mile23Looks pretty good.
Let's do a little analysis here.
The way this currently works is:
Given this, it makes sense to have a value class that abstracts away the tabular nature of the data, and eventually also understands the things we want from PHPUnit and/or JUnit (such as risky and incomplete and so forth). We have an issue for adding risky and incomplete so let's not do that here, but looking at that issue might be instructive... #2905007: Allow run-tests.sh to report skipped/incomplete PHPUnit tests
We also want the various pieces to be testable in isolation and in various combinations.
So the flow we might wish to see is:
Assuming the result maker can log in a flexible way, we can then unit test its behavior, and we can also do a more integrative test of the round-trip the JUnit XML takes through this subsystem.
Also, as we move responsibilities away from
TestDatabase, it goes back to only giving us a connection to a database. We'll then want callers to get the connection and inject it into the value object, so that we can then mock the connection for testing. That is: The report maker should never useTestDatabase, but the injectedConnectionobject instead, to facilitate mocking.And hey, we look at the patch and what do we see:
..so we're off to a good start in terms of design thinking. :-)
But I think we should separate concerns and have a value-only results class that consumes JUnit results, and then an abstract report maker, and then a concrete report maker that knows how to write to a
Connectionwith a {simpletest} schema.This enables us to test, and then also gives us relatively easy options when it comes time to report on risky and incomplete tests.
I'd work on a patch right now but life is in the way.
Comment #11
mondrakeDoing some better usage of the TestRun object around. Haven't seen #10 yet. @Mile23 feel free to take over anytime, just pls assign to yourself so I know I will have to keep hands away :)
Comment #12
mondrake#10 sounds great!
... and another implementation of the concrete report maker that, for example, just writes to memory for testing purposes without any DB interaction, if I understand correctly.
For now, in this patch I am just moving
TestDatabase::logReadto a method onTestRun, since AFAICS it belongs there - that method, given a test run, scans the PHP error log file and adds appropriate log entries to the test run. At the end of the game,TestDatabasewill only provide methods to setup and provide references for the database for the SUT, so to decouple that from managing the test results.Comment #13
mile23Comment #14
mile23Comment #15
mondrakeAssigning, trying to separate TestRun from results storage
Comment #16
mondrakeSo, here's my next idea.
Test runners (simpletest.module and run-test.sh) run tests opening
TestRunobjects that have state and an execution log.TestDatabaseobjects only cares about setting up the SUT database, not the results logging. EachTestRunobject is associated with aTestRunResultsStorageInterfaceobject, which responsibility is to store permanently the state and execution log of each test run. This interface is storage agnostic, implementations could use a database or anything else.SimpletestTestRunResultsStorageis at the moment the only implementation ofTestRunResultsStorageInterface, which is using the database and the legacy {simpletest} and {simpletest_test_id} tables for the purpose.Comment #18
mondrakeAddressing test failures
Comment #20
mondrakeLet's see this.
Comment #21
mondrakeI suggesto to wait for #2800267: Turn simpletest_clean*() functions into a helper class before continuing.
Comment #22
mondrakeComment #23
mondrakeRerolled and moved
TestDatabase::processPhpUnitResultstoTestRun::processPhpUnitResultsComment #24
mondrakeAddressing test failure.
Comment #25
mondrakeRefactoring
run-tests.shto use the new objects.Comment #26
mondrakePatch in #25 is pushing too far.
Comment #27
mondrake#2800267: Turn simpletest_clean*() functions into a helper class is in and this now needs reroll + incorporating into
SimpletestTestRunResultsStorageall the db 'delete' operations. Will work on that.Comment #28
mondrakeJust a reroll now.
Comment #29
mondrakeAddressing failures of #28.
Comment #30
mondrakeHere with
SimpletestTestRunResultsStoragemanaging *all* interactions with the DB layer, AFAICS. This completes abstraction of the test results storage from the media actually used for it. Did some local testing, let's see what bot thinks.Comment #31
mondrakeBetter.
Comment #32
mondrakeFar from being ready, but I think we can unpostpone now, for review.
Comment #33
mondrakeWorking at adding tests for
SimpletestTestRunResultsStorageandTestRun.Comment #34
mondrakeAdding a bunch of tests for
SimpletestTestRunResultsStorageandTestRun.Comment #35
mondrakeAdjusted
TestRun::processPhpErrorLogFileto make it testable and added tests + fixture test error.log file.I do not like the results of the processing of the error.log file - a results record is added for each line of the file, and that means an entry for each item in the backtrace of the failure. In practice, given the test error.log file I'd expect 2 entries, but actually 9 entries are added. But that is pre-existing behavior, I just reflect it in the test. I'd suggest a follow-up to improve that logic.
Comment #37
mondrakeComment #38
mondrakeReroll after #3080482: Decouple FunctionalTestSetupTrait from the simpletest module
Comment #39
mondrakeAdding a
TestDatabase::getPhpErrorLogPathmethod to make finding the error.log file reusable and testable, adjusting tests.Comment #41
mondrakeDo we really need the path to be absolute?
Comment #42
mondrakeReroll after #3074433: Decouple run-tests.sh from the simpletest module
Comment #44
mile23Patch still applies, re-running test.
Comment #45
mile23Repeat of #44.
Comment #46
mondrakeAdding a test for TestRun::processPhpUnitResults. Would be good to get some feedback about the direction of this patch.
Comment #47
mondrakeComment #48
mondrakeUpdated IS with (more or less) what the latest patches are trying to implement.
Comment #49
mondrakeSome more cleanup+docs
Comment #51
mondrakeComment #53
mondrakeLess typehints, they fail on Simpletest.
Comment #54
mondrakeMoving TestRun::processPhpUnitResults into the PhpUnitTestRunner class.
Comment #56
mondrakeAddressing failures of #54.
Comment #57
mondrakeComment #58
mondrakeEnvironmentCleanerto useTestRunobjectsTestSetupTrait::getDatabaseConnectionso to channel all interaction to test results storageTestBase::deleteAssertto use test results storage instead of direct db callsComment #59
mondrakeComment #60
mondrakeLet's see how this works now after removal of simpletest from core in #3110862: Remove simpletest module from core. Reroll.
I think this becomes 9.1.x material, now.
Comment #62
mondrakeReintroducing TestDatabase::testingSchema to stay away from changing Simpletest stub
Comment #63
mondrakeReroll.
Comment #64
mondrakeRerolled and adding typehints to functions.
Comment #65
mondrakeComment #66
mondrakeRerolled.
Comment #67
longwaveIt feels like Simpletest is abandoned, there is no real activity in the contrib module, so if this gets us on the way to removing Simpletest-isms from core then I think it's a good idea.
This is considered internal so we could just remove it?
Might as well set these versions and add a change record.
Otherwise I don't see any big issues and I think this is a nice cleanup.
Comment #68
mondrakeThank you @longwave, I am on it.
Comment #69
mondrakeDrafted CR https://www.drupal.org/node/3176816
Comment #70
mondrakeAddressed #67, thank you.
Comment #72
mondrakeFixes for failures in #70.
Comment #73
longwaveA few more real tiny nits now I have gone back for a second look:
As we typehint to array the empty check seems useless, foreach over empty array will do nothing anyway.
Is this actually needed?
I don't think we normally break long lines like this.
All other functions in run-tests.sh begin with
simpletest_script_except this one, probably should be consistent.This can be single-quoted now.
Comment #74
mondrake#73 all done, thank you.
#73.4 I'd rather do the other way round i.e. replace "simpletest" with "runtests" everywhere but yea, let's do that elsewhere.
Comment #75
longwaveLooks great now, thanks! Looking forward to some followups where we remove more references to Simpletest :)
Comment #77
mondrakeRerolled
Comment #80
mondrakeComment #82
spokje@mondrake
I think we need to rebase the MR on
9.3.x.(And by we, I of course mean: you, because only the original creator of an MR can do so 😇)
Comment #83
mondrakeAfter sitting for 9 months in RTBC with no action, I'm not sure where this issue is going, really. But OK, rebasing.
Comment #84
mondrakeComment #85
spokjeI hear what you're saying there and I was kinda hoping a rebase would get this one in quicker.
Thanks :)
Back to RTBC per #75, trusting TestBot to kick it down when it's not returning green.
Comment #86
mondrakeThis issue has been sitting in RTBC for over one year with no sign of interest from committers. I assume won't fix, if nothing else to avoid rerolling it to no avail.
Comment #87
mondrakeDiscussed with @longwave in Slack it's worth giving this another try. I will rebase this onto 10.1.x.
Comment #88
mondrakeRebased onto 10.1.x
Comment #89
mondrakeComment #90
longwaveA couple of questions/comments - I am OK if you want to defer further changes to followups, getting this testable means we can refactor and untangle the Simpletest-isms more easily.
Comment #91
mondrakePlease see comments inline the MR.
Comment #92
longwaveThanks - this looks OK to me and will mean that we can start removing more dead code related to Simpletest in followups.
Comment #93
alexpottI've stared at this issue lots of times and little bits of it make me feel "are we sure that we need to do this or that" - for example I'm not sure about the utility of having an interface for TestRunResultsStorageInterface - I get that internally we're going to swap it for a non-simpletest labelled implementation at some point in the future but it feel unnecessary. That said, I'm not sure that these objections are that important or should stand in the way of progress here. I don't think we should consider any of this public API and the MR helpfully adds @internal in quite a few places. Therefore I think we should proceed here with a commit.
Committed f711435 and pushed to 10.1.x. Thanks!
Comment #96
mondrakeThanks. BTW, there's a bit of Space Oddity in Drupal's code, now :)