greenlight
greenlight copied to clipboard
Sequence of steps should be reusable as well
Right now there are two basic constructs: step
and test
. While step
is reusable, IMO a collection of steps should also be easily reusable.
To illustrate what I'm saying, one concrete example: I'm using greenlight
to write end to end tests and I have a sequence of steps to create an user, validate its email and save its data in greenlight context. While I'm able to use (concat user-creation-steps [...])
to test most flows, there are places where I can't, like when I want to create two different users and have them saved in different keys in the context.
Having an easy way of composing steps would be really helpful.
Does it work in your case to have user-creation-steps
be a function that returns a collection of steps, parameterizing the :output
key?
(defn user-creation-steps
([] (user-creation-steps :user))
([output-key]
[#::step{:name 'step1
:title "step1"
:test (fn [_] 1)
:output :step1}
#::step{:name 'step2
:title "step2"
:inputs {,,,}
:test (fn [_] output-key)
:output output-key}]))
(deftest test-multiple-users
"Testing creation of multiple users"
(user-creation-steps :user1)
(user-creation-steps :user2)
#::step{:name 'check-users
:title "check-users"
:inputs {:user1 (step/lookup :user1)
:user2 (step/lookup :user2)}
:test (fn [{:keys [user1 user2]}]
(is (= :user1 user1))
(is (= :user2 user2)))})
@jstokes yeah, that's basically what I'm doing, but I think there's a little too much boilerplate involved. Some steps would already exist and may need a different key as input, also intermediate steps may output stuff that may be desired as well. There's also the issue with intermediate results overriding previous results, like in your case with :step1
key. In my case, I wasn't able to generalize the user-creation-steps
.
Ideally IMO the steps composition would run in a separate context, with its own sets of defined inputs/output as the interface with the outer context.
I came across this whilst trying to create a more generic step. Perhaps the below snippet will help someone. I use it to dynamically lookup a previous step's output (where step-edit-event is a defstep)
(defn step-customise-edit-event [event-type inputs & kvs]
(let [s (apply step-edit-event inputs kvs)]
(update-in s [:greenlight.step/inputs] merge {:event (step/lookup (fn [ctx]
(get ctx event-type)))})))