RFC: TestCase events for Tester
- Milo
- Nette Core | 1283
By @mystik (original post)
Sometimes we use in our tests some additional tools (Mockista, mockery, database connection, PHP server, memcached, dummy presenter, different container configurations, …). Current solution is to create some base TestCases with different combinations of these tools. But it get complicated as more and more tools used. Not mentioning you need to call all of them in tearDown and setUp correctly.
We think about solution inspired by Codeception modules. What we need to create something like that is ability of modules to hook on some TestCAse lifecycle events.
Co we suggest to add to TestCase these events which can be hooked from modules to extends TestCAse behaviour:
- beforeSetUp
- afterSetUp
- beforeTearDown
- afterTearDown
- beforeRunTest
- afterRunTest
Usage for Mockery in some module then can look like:
Or for database extension:
Concept of modules need to be think throught and is not ready yet. It probably should be addon. But adding this events is first step to be able to do this, it is not BC break and can improve extendability of TestCase.
Proposed solution in PR #246.
- mystik
- Member | 313
Listener is ok I think. But if we use Listener how about addListener(ITestCaseListener $listener) more like standard Listener pattern.
Then we should decide if use single ITestCaseListener with all events or separate interface for each event like IOnBeforeSetupListener
Last edited by mystik (2015-08-14 22:33)
- Milo
- Nette Core | 1283
mystik wrote:
Listener is ok I think. But if we use Listener how about addListener(ITestCaseListener $listener) more like standard Listener pattern.
That's a next possibility.
Then we should decide if use single ITestCaseListener with all events or separate interface for each event like IOnBeforeSetupListener
Separated interfaces (in this case) are error prone:
- mystik
- Member | 313
Traits would entirely kill original purpose of this RFC of simplifing extensions of tests. Such extensisons would be limited to traits and cannost use inheritance of its own, fluent interface, multiple use of single extension (two database connections), …
Possible BC break of interface can be solved in two ways:
- Separate interfaces
(maybe not split it by each event separate but for example to SetUpTearDownListener, RunListener, TestResultListenter). New Listeners for new events then can be added in future.
- Extended interface (with additional events added in future)
I personally preffer first solution.
Last edited by mystik (2015-08-17 15:53)
- mystik
- Member | 313
I imlepmented in in our own fork so we can start using it. See https://github.com/…ter/pull/249
- Milo
- Nette Core | 1283
@mystik Sorry it takes too long.
Personally, I'm against any interface (for now). The reason is simple. Once we define an interface, any method name/signature change is a big BC break. I'm not sure we can design an interfaces well on a first shot.
I tried to find some use case in my libraries where I could test such event system. And I didn't. Unfortunatelly I have no time to write some just for fun/testing purpose. It is a next reason why I don't want to code from top of my head.
So, that's why I proposed the solution with a callback. It's harder to use, but simplier to maintain.
Maybe @DavidGrudl @FilipProcházka or @enumag have more skills with event systems. Any practical experiencies share is welcomed.
- enumag
- Member | 2118
@Milo I don't have much experience with Nette/Tester but you might want to check how it is solved in Codeception: https://github.com/…n/Subscriber. It's a bit of a compromise. Maybe you and @mystik will like it.
Also it's similar to Kdyby/Events which has even better API in my opinion:
You could use something very similar.
Last edited by enumag (2015-09-17 22:26)