-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Support concurrent executions of scenarios #630
Comments
Any update on this one? This missing feature currently stops me from using cucumber-jvm. Am I right that it's not even possible to achieve parallel execution of features unless using some clumsy hacks. |
Nobody has submitted any pull requests for this, so I'm afraid the answer is no. |
👍 I am carrying around this issue with me for quite a while now. Especially for UI tests it is absolutly nessessary to run tests in parallel. I've seen several attempts to make this possible from slicing feature files into single scenario files (within a build job) with massive jvm-forking to runners with ugly Reflection-Hacks that replace thread-unsafe code in Runners and Runtimes - none of them very satisfying. I tried to build a JUnit Runner around it but there are some internal design flaws that absolutely prevent one from efficiently executing cucumber scenarios in parallel. The core problem is IMO that the I'd really like to spent some time on this but it would, in one way or another introduce changes in the core apis. Thats why I'd kindly ask if such changes would be welcome at all :) |
I broke the hell out of core back in the day making the Jruby stuff work. I don't believe anyone would be opposed to seeing code. You'd just have to be willing to accept feedback and possibly change the code even more. |
Hear, hear! It would be a big, but welcome change. In the next months I intend to refactor the internals to use Gherkin3 and in order to avoid merge hell I'd like to see parallelism added after this. |
Two thumbs up @danielwegener. I really appreciate the proposed changes. If there's anything I can support you with, just let me know. I'll close #664 so we track the parallel scenario executions in one issue - and this one looks more promising! |
Good to hear that I am not alone with this requirement :) I find some time to investigate the code a bit and tried to push pieces around. How things are
Goals
Non-Goals
IdeasThe current major problem is the strong coupling between mutable resources. Although we could try to make things safe by sprinkling synchronization barriers and api-conventions with javadocs like 'please do not touch touch this after intialization', this will still hard to get things right then. I'd suggest a refactoring that clearly separates the following phases:
Possible changes
I'd be glad to hear your thoughts on this. Since code doesnt lie, prototyping happens here: https://github.com/danielwegener/cucumber-jvm/tree/wip/630-parallel |
Fantastic analysis @danielwegener - I couldn't have done it better myself. What are your thoughts on doing this in parallel with Gherkin3? I'm worried that both streams ofcwork will take a while and touch a lot of the same code. I plan to rip out the gherkin2 code entirely and modify everything that depends on it. The |
@aslakhellesoy It sounds like as if Gherkin3 will lead to a major release of cucumber-jvm anyway - and that would make breaking changes from this parallel-feature easier to justify. I would be fine to develop this parallel-feature on top of your gherkin3 branch (keeping the commit history small and rebasing regularly should not be such a pain). IMO It would be great if we could put both features into one major release, so users would have to make a maybe painful migration only once (from the point of view seen cucumber-jvm as a product). This may lead to some organizational coordination effort for the roadmap but after working with forked test executions for over a year now, I am not really in a rush :) So my suggestion would be: You develop gherkin3 on your branch (keeping it on top of master), I'll try to keep the parallel-feature on top of your branch (although I dont know how/if rebasing is practiced in this project). Eventually you merge to master and we can see if the parallel-feature is mature enough to put it into the same major release. If not, well then later :) |
Anything new on this issue? I have never contributed to a project such as this but am willing to help in any way that I can - this would be a great capability! |
Hi @ereber! Glad you picked up this issue. I've almost forgot about it. In my initial work towards a solution I stumbled across so many entangled state and side effects that I came to the conclusion that it's not really doable without major API changes. These changes would probably not only affect cucumber-jvm but also tools like intellij's cucumber-java integration (and friends), which then would need to support multiple versions of the cucumber-jvm api. I have another ongoing attempt: I am trying to change the synchronous execution (Runtime.runStep/runHook, CucmberScenario.run/CucumberScenarioOutline.run/CucumberFeature.run) into a trampoline that returns a partial execution and deferrable side effects on |
I guess the basic idea can become clearer if you look at danielwegener@22ec6f5#diff-6ec644ece6e92b60fe39b4cceef33c08L263 and danielwegener@22ec6f5#diff-744b09b40e36de28c426af7d91737bd1R20 :) (ongoing effort here: master...danielwegener:wip/630-retry) |
@danielwegener
This approach was discussed in Cukenhagen, when I described my solution to Jarl Friis and he pointed some problems with point 2 above out. My architecture for the parallel-runner also looks slightly different (as far as I can tell). It uses a three-layered architecture (in a map/reduce style):
Frontend:
Backend:
Worker:
This approach allows you to start with a multi-processing executor (or Backend) and add other parallel-execution backends in the future (like a Cloud-Executor, a Cluster-Executor, etc.). In addition, it should simplify some of your multi-threading problems related to formatters, etc. (because this requirement does no longer exist). |
Hi @jenisys , cheers for your feedback - good to get the discussion rolling :) . My code attempt mentioned above is already kind of outdated and I learned some more things. I think to control whether tests should be executed in parallel should not be defined in the gherkin model but rather in the runner (e.g. via Resource management is a good point (e.g. If I only have one selenium browser driver instance, it does not make sense to run tests in parallel). If we assume that these resources are provided as Glue instances by the backends, we could rather Pool glue instances (by type) while each glue instances is capable of executing one step at a time (and may maintain state while a scenario is executed). However, not all I don't really get your idea about the architectural split into frontend, backends and workers. Could you elaborate, or do you have any link (discussion, code) you could point me to? Do I understand it right that it is about distributing execution to multiple workers? If that and since you mentioned map&reduce - do you have any plans how to distribute the actual test bytecode to workers (thinking about Hadoop/Spark this is horrible to get right and pretty expensive). Instead of modeling a network of workers who actively pass around their work and results, I'd just create a "work-plan" (an executable graph of features/scenarios) once and let an executorService pull steps from this graph and allocate matching glue instances as long it has capacity (i.e. available glue code instances and unused threads.) Sure it depends what you test but most cucumber usages I've seen is talking to a selenium grid or rest-endpoints (and in fact spend most of their time waiting for IO). In such environments, the actual test execution code never was the bottleneck. As soon as we can run Scenarios on an ExecutorService I'd bet we won't have any problems to run lets say 100 scenarios in parallel (100 Threads waiting for IO is not really much for an application server). But one step after another! |
The point about reporters and progressIndicators is also very good. There are some reporters (like the junit reporter) which are only interested in progress events in a timely manner (like "scenario A step 3 failed") and others which really expect to receive a sequence of invocations which must, even if executed concurrently, be serialized before they are written to the wire (like console-output, where single scenarios steps from different scenarios should probably not overlap each other; or even json-reports which are expected to have even a stable order between features (sorted by filename?)). |
@aslakhellesoy Are there any objections against upgrading cucumber-jvm to java7 (maybe android)? I consider using the ForkJoin/RecursiveTask-Framework for scheduling/concurrent scenario execution. |
@danielwegener I'm convinced that concurrent testing should be provided by the actual framework, e.g. JUnit, i.e. cucumber shouldn't prevent it, but it should implement it either. See for example https://github.com/jhorstmann/zuchini, it's a rewrite that supports JUnit parallel executions (not saying that a rewrite is necessary, but it helps my case). |
@whiskeysierra Yes and no. |
Is the parallelism added? The issue is still opened. |
I think is still open. My latest attempt (https://github.com/danielwegener/cucumber-jvm/commits/wip/630-parallel) required too many refactorings (and changes in the client/non-java APIs) so I finally abandoned it. |
+1 - this would be awesome. My tests are currently up to 1.5 hrs. |
If your tests are that slow you should fix your architecture. https://skillsmatter.com/skillscasts/8567-testable-software-architecture |
@aslakhellesoy hey buddy, the tier of tests that cucumber meets in my situation is running tests that were done manually before. Your test speed note is really geared for unit testing and integration testing. This layer of testing I have proves the rigor of the system and, due to the application this system is designed for, cannot be run faster than roughly a minute for a scenario. These scenarios COULD RUN IN PARALLEL and my stuff would be done in a minute, thus the desire to have cucumber support this out of the box. This all makes less sense given that you have left this ticket open since 2014. And, for the record, I really like cucumber. It actually documents my tests quite well. |
@nwertzberger @aslakhellesoy is teasing you, well done for taking that so well and not feeding his trolling :) It's actually pretty rare to hear of a use-case where parallel tests are all that valuable. In my experience, most people with slow tests also have a lot of internal system state that relies on not running several tests at once. This is a big piece of work, and there are quite a few other things in the way of it right now. Thanks for adding your support for this, hopefully it will motivate someone to pick this up and help out with the steps to get us there. |
@mattwynne i am going to assume everyone else is doing what i just did today after @aslakhellesoy jokingly closed this ticket (and, as of this writing, it's still closed). |
I think the point why this ticket is was open for a long time is that it (imo) requires a big refactoring of the whole cucumber-jvm architecture and its language bindings, executor bindings and (possibly) tool integrations. The state is just too scattered (see elaboration above). @mattwynne I almost took the bait. Still wondering why this issue is closed. And I have to disagree - It's not always the case that tests are slow but just that there are alot (and that they are run against different enviroments (browsers)). And it's rather the case that you actually have cheap CI-Clusters with elastic worker nodes, ad-hoc docker composite deployments and selenium grids that could bring down your whole browser regression test suite down from 30 minutes to 3 minutes -- if the test-executor would be willing to run tests in parallel without hugging too much resources on its own (forking, no parallel executions, no support for async await). |
Yeah @danielwegener, I think you're probably talking more of a re-write than a refactoring TBH. That's what we went through with the Ruby codebase, and it took @tooky and I about 18 months altogether. Working with the test-case abstraction (rather than being coupled to the Gherkin document structure) is the key, but it breaks all the formatters, and so the herd of yaks grows and grows. I agree that this would be hugely valuable to people if we could do it. Right now many of us on the core team are hustling hard to get http://cucumber.io/pro out the door, which means we're neglecting our open-source responsibilities in the short term. Medium term we hope it will provide us with a steady revenue stream that enables us to give more of our time back to the community again, and we'll be able to invest in bigger pieces of work like this. |
@mattwynne Thanks for the clarification. I wish you the best going pro :). Fortunately Java is not Ruby and (I do not think it would take 18 month) - so once you finde some time to give some feedback or discuss on possible strategies - just drop a ping here and I'd be glad to join. |
@danielwegener We do not want to do any of this before lifting Cucumber-JVM to Gherkin v4.0 with the introduction of Gherkin compiler an Pickles (which is some sense mimics the re-write of the Ruby codebase). |
If at all interested, we've been battling with the same problem and ended up writing a maven plugin that executes multiple cucumber threads and combines the test reports. https://github.com/eu-evops/cucumber-runner-maven-plugin |
@sponte that's interesting - thanks for link. I use Jenkins scripted pipeline with parallel support to run multiple CLI runners for cucumber. It has advantage to scale on different nodes if required. Jenkins plugin for cucumber is grabbing all json files and generating single report for all. |
You might also be interested in: https://github.com/temyers/cucumber-jvm-parallel-plugin (have not used this myself, but was mentioned by others) |
There is some plugin like cucumber-jvm-parallel-plugin but to be used with gradle and doesn't interferes with Serenity living documentation? |
Not yet. There might be when cucumber can execute pickles in parallel: |
@mpkorstanje I've nearly finished my changes, just have to review the tests I've written to ensure appropriate coverage, also am going to double check some of yours that you wrote to ensure no cross over etc... Looks like I'm going to have a fun merge too based on your last few commits 😭 |
No problem! Let me do the merge. I made this bed. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Currently it's only possible to execute feature classes in parallel. In case you have independent scenarios (and you really should) it would be nice to run them concurrently. The current codebase does not support this. First of all the reporting is inherently sequential and there is some state in the Runtime class (
skipNextStep
andscenarioResult
). I would be happily contributing a patch, but this would require a major change of some of the internal structure.The text was updated successfully, but these errors were encountered: