tl;dr: I forked the lettuce package to use multiprocessing, tests run more then 4x faster on my MBP
I am a fan of Gabriel Falcão’s lettuce Behavior-Driven Development (BDD) tool. We have been using it on my team for 6+ months now. Recently our test suite completion time has crossed the 10 minute line, which had a bunch of negative effects, as you can imagine:
- people writing less tests
- people running the test suite less frequently
- people spending more time watching a test suite run, then coding, …
We all are using relatively modern MBP with 4 cores, and we might as well make the most of them. Here is my fork of lettuce that allows you to take advantage of all of your cores:
https://github.com/jtushman/lettuce
I have made two main modifications (You will find the lion share of my modifications in this file):
- I created a ParallelRunner (I have left the main runner alone), which kicks off processes to pull the scenarios off a queue
- After each run I store the run times of each test in a
.scenarios
file, so in subsequent runs I can sort them longest to shortest
My test suite used to take 12 minutes, now its takes 2 minutes — REJOICE!
Usage
lettuce tests -p 4 -v 2
-p: stands for parallel. You can set it to how many processes you like, I find that the number of cores should be your default
-v is the same verbosity parameter, but I recommend setting it to 2 when using parallelization, otherwise the steps will interlace and not make much sense
in your terrain.py
file, there are two new callbacks:
@before.batch
and @after.batch
which you should use to set up and tear down each process. I use main to fire up flask, selenium and mongo. Also note that I set a port_number attribute on world which you can use set up processes specific servers. For example:
1 2 3 4 5 6 |
|
Caveats
For this to work all of your tests need to be isolated, they can not depend on each other (which I think is best practice anyways). This means in your tests you should not use world at all Use scenario instead:
To do this, in your terrain
file add the following:
1 2 3 4 5 6 7 8 |
|
And I use this all the time in my steps to refer to state from previous steps
1 2 3 4 5 6 7 8 |
|
Hope you guys find this useful!