greenlight icon indicating copy to clipboard operation
greenlight copied to clipboard

Sequence of steps should be reusable as well

Open caioaao opened this issue 6 years ago • 3 comments

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.

caioaao avatar Jan 29 '19 18:01 caioaao

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 avatar Jan 29 '19 18:01 jstokes

@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.

caioaao avatar Jan 29 '19 20:01 caioaao

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)))})))

patrick-galvin avatar Apr 18 '22 08:04 patrick-galvin