-
Notifications
You must be signed in to change notification settings - Fork 327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid Request::factory() calls in test providers #627
Avoid Request::factory() calls in test providers #627
Conversation
`Request::factory()` calls in test "provider" methods initializes the `Request::$initial` static variable, affecting other test methods, even if those "provider" methods are not direct providers of those other test methods. In our case the `HTTPTest::test_redirect` is affected because the `HTTP::redirect` method needs the `Request::$initial` static variable to be available. Even if PHPUnit is run with the `--filter=HTTPTest` flag, the "provider" methods of `RequestTest` are still available, `Request::factory()` calls are still made, and the `Request::$initial` static variable is still initialized. This becomes problematic because `HTTPTest::test_redirect` is now dependant of the `RequestTest` "providers", as those "providers" change the global state in favor of its needs. Once `RequestTest` "providers" are not available -- ex: by deleting RequestTest.php file from disk -- `HTTPTest::test_redirect` test cases fail. In order to not alter the global state, and to not affect other tests, static variables initialization, and calls to methods that affect static variables should not be made in test case providers. Rather calls should be done carefully in `setUp` and `tearDown` methods, as well as in the tests methods themselves. In this case I have removed `Request::factory()` calls from providers and restructed the tests.
Initialize `Request::$initial` for HTTPTest::test_redirect. After initializing `Request::$initial`, it is probably better to set it to `NULL` instead of using `$this->_initial_request` to temporary save the value. But I prefered to keep things in conformity with `RequestTest` for the time being.
reverting the hhvm diff, does not work:
|
@acoulton any hope you could review and merge this :) |
@enov sorry, I was away on holiday last week. This looks good to me, thanks for fixing. Perhaps we should also add something to the |
…lls-in-providers Avoid Request::factory() calls in test providers
Thanks @acoulton
That might be a good idea. But I am not sure how to do: For some reason, all test provider methods seem to be always running/available... So even if we |
@enov ISTR PHPUnit does a first pass to load the list of all tests - which includes running all providers, because it can't tell how many tests there are till it knows how many sets of arguments each provider returns. Then it filters the list, and then it starts actually running tests - always calling So you can always guarantee |
https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.backupStaticAttributes may be sufficient. If you want to find or assert when a tearDown() is leaving state, you could add a static function with As an aside, the update to the HHVM test suite was un-reverted; this turned out to be an unrelated infrastructure issue that would have been triggered by any update. Sorry for the noise. |
My preliminary attempts seemed to show that PHPUnit was NOT following that rule. The way providers of However, now that I am still preparing a reply to your comment, I noticed that in Thank you for your hard work. I'll dig deeper into those, or see if a base Cheers! |
The advantage of @beforeClass is that it should still be executed if a subclass overrides setUp and doesn't call parent. |
I think 70b88e8 causes a bug when internal sub requests are made. So if there's an initial request already and you do an internal sub request with:
and then in the action matching the URI of this sub request you try to get In Kohana 3.3.4 and before:
In Kohana 3.3.5:
I think this is a major bug introduced in Kohana 3.3.5. It could be worked around using:
However setting query params in the URL of |
Kohana 3.3.5 does not allow passing query params as part of the URL in Request::factory(). See kohana/core#627 (comment) for more details.
Kohana 3.3.5 does not allow passing query params as part of the URL in Request::factory(). See kohana/core#627 (comment) for more details.
Just to note I couldn't find any documentation describing the case of including query params in the URL string passed to |
Hello all,
It is funny, sad and frustrating at the same time to know why Kohana is not marking 100% in the official HHVM OSS frameworks tests suite.
Background
I requested a pull to update the tested Kohana framework version in HHVM framework tests to v3.3.4. It was surprising for me to see it passing only at 99.85%.
HTTPTest::test_redirect
was the failing test. However, when running PHPUnit tests from within the Kohana folder, the standard way, all was OK and tests were passing.I had hard time to figure out the real cause. Took me around 3 days, with a cumulative 12 hours. Even when I run
HTTPTest
alone with the--filter=HTTPTest
flag from within the standard Kohana installation folder, the test always passed. I tried in vain to find ways to debug this. At some point, I was furious enough to delete all other test files from the disk exceptHTTPTest.php
, in order to "force" PHPUnit to run with onlyHTTPTest.php
phisically available. It was only then, to my surprise, that the test failed. A clear indication that some tests are affecting others. I hunted down and found out the culprit. It was theRequestTest
that was affectingHTTPTest
.Cause
Request::factory()
calls in test "provider" methods initializes theRequest::$initial
static variable, affecting other test methods, even if those "provider" methods are not the direct providers of those other test methods.In our case the
HTTPTest::test_redirect
is affected because theHTTP::redirect
method needs theRequest::$initial
static variable to be available. Here's the pseudo call stack:HTTP::redirect()
HTTP_Exception_Redirect::location()
URL::site()
URL::base()
which usesRequest::$initial
This becomes problematic because
HTTPTest::test_redirect
is now dependant of theRequestTest
"providers", as thoseRequestTest
"providers" change the global state in favor ofHTTPTest
's needs. OnceRequestTest
"providers" are not available -- ex: by deleting RequestTest.php file from disk --HTTPTest::test_redirect
test cases fail.Solution (well... for the moment)
This is a reported issue and we lengthily discussed this elsewhere already... For the moment, however, this is what I am proposing for v3.3:
In order to not alter the global state, and to not affect other tests: static variables initialization, and calls to methods that affect static variables should not be made in test case providers. Rather, these calls should be done carefully in
setUp
andtearDown
methods, as well as within the test methods themselves.In this case, I have removed
Request::factory()
calls from providers and restructured the tests.Note that:
HTTP::redirect()
redirects with protocolcli
ex:cli://www.example.com/kohana/index.php/page_two
NULL
instead of using$this->_initial_request
. But preferred to keep things along the way it's done inRequestTest
.This is ready for merge, please review thoroughly, cc @acoulton.
Thanks!