Skip to content

Commit 9b949ab

Browse files
SamMousasamdark
authored andcommitted
This adds support for components that keep state that must be cleared… (#4924)
* This adds support for components that keep state that must be cleared between requests * Fixed issue in test skip logic + nitpick CS * Fix application reset after exception * Add configuration option to recreate the whole application before each request * Add default configuration
1 parent 54ef972 commit 9b949ab

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

src/Codeception/Lib/Connector/Yii2.php

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ class Yii2 extends Client
6464
*/
6565
public $requestCleanMethod;
6666

67+
/**
68+
* @var string[] List of component names that must be recreated before each request
69+
*/
70+
public $recreateComponents = [];
71+
72+
/**
73+
* This option is there primarily for backwards compatibility.
74+
* It means you cannot make any modification to application state inside your app, since they will get discarded.
75+
* @var bool whether to recreate the whole application before each request
76+
*/
77+
public $recreateApplication = false;
78+
6779
/**
6880
* @return \yii\web\Application
6981
*/
@@ -133,31 +145,19 @@ public function doRequest($request)
133145
$_GET[$k] = $v;
134146
}
135147

136-
$app = $this->getApplication();
137-
138-
/**
139-
* Just before the request we set the response object so it is always fresh.
140-
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
141-
* those changes to be reflected in the reponse.
142-
*/
143-
$this->resetResponse($app);
148+
ob_start();
144149

150+
$this->beforeRequest();
145151

152+
$app = $this->getApplication();
146153

147154
// disabling logging. Logs are slowing test execution down
148155
foreach ($app->log->targets as $target) {
149156
$target->enabled = false;
150157
}
151158

152-
ob_start();
153159

154-
// recreating request object to reset headers and cookies collections
155-
/**
156-
* Just before the request we set the request object so it is always fresh.
157-
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
158-
* those changes to be reflected in the reponse.
159-
*/
160-
$this->resetRequest($app);
160+
161161

162162
$yiiRequest = $app->getRequest();
163163
if ($request->getContent() !== null) {
@@ -186,7 +186,6 @@ public function doRequest($request)
186186
$app->errorHandler->handleException($e);
187187
} elseif (!$e instanceof ExitException) {
188188
// for exceptions not related to Http, we pass them to Codeception
189-
$this->resetApplication();
190189
throw $e;
191190
}
192191
$response = $app->response;
@@ -378,4 +377,28 @@ protected function resetRequest(Application $app)
378377
break;
379378
}
380379
}
380+
381+
/**
382+
* Called before each request, preparation happens here.
383+
*/
384+
protected function beforeRequest()
385+
{
386+
if ($this->recreateApplication) {
387+
$this->resetApplication();
388+
return;
389+
}
390+
391+
$application = $this->getApplication();
392+
393+
$this->resetResponse($application);
394+
$this->resetRequest($application);
395+
396+
$definitions = $application->getComponents(true);
397+
foreach ($this->recreateComponents as $component) {
398+
// Only recreate if it has actually been instantiated.
399+
if ($application->has($component, true)) {
400+
$application->set($component, $definitions[$component]);
401+
}
402+
}
403+
}
381404
}

src/Codeception/Module/Yii2.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* ## Application state during testing
2424
* This section details what you can expect when using this module.
2525
* * You will get a fresh application in `\Yii::$app` at the start of each test (available in the test and in `_before()`).
26+
* * Inside your test you may change application state; however these changes will be lost when doing a request if you have enabled `recreateApplication`.
2627
* * When executing a request via one of the request functions the `request` and `response` component are both recreated.
2728
* * After a request the whole application is available for inspection / interaction.
2829
* * You may use multiple database connections, each will use a separate transaction; to prevent accidental mistakes we
@@ -41,8 +42,12 @@
4142
* Between test casesthe whole application is always recreated
4243
* * `requestCleanMethod` - (default: recreate) Method for cleaning the request object. Note that this is only for multiple requests inside a single test case.
4344
* Between test cases the whole application is always recreated
45+
* * `recreateComponents` - (default: []) Some components change their state making them unsuitable for processing multiple requests. In production this is usually
46+
* not a problem since web apps tend to die and start over after each request. This allows you to list application components that need to be recreated before each request.
47+
* As a consequence, any components specified here should not be changed inside a test since those changes will get regarded.
48+
* You can use this module by setting params in your functional.suite.yml:
49+
* * `recreateApplication` - (default: false) whether to recreate the whole application before each request
4450
* You can use this module by setting params in your functional.suite.yml:
45-
*
4651
* ```yaml
4752
* actor: FunctionalTester
4853
* modules:
@@ -154,7 +159,9 @@ class Yii2 extends Framework implements ActiveRecord, PartedModule
154159
'entryScript' => '',
155160
'entryUrl' => 'http://localhost/index-test.php',
156161
'responseCleanMethod' => Yii2Connector::CLEAN_CLEAR,
157-
'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE
162+
'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE,
163+
'recreateComponents' => [],
164+
'recreateApplication' => false
158165
];
159166

160167
protected $requiredFields = ['configFile'];

0 commit comments

Comments
 (0)