While trying out clj-webdriver (for testing web pages), I got the impulse to reduce some of my boilerplate. I'd like your advice on best practices. Here's the original code.
(deftest test-login (let [b (start :firefox "https://github.com")] (try (implicit-wait b 60000) (-> b (find-it {:text "Login"}) click) (-> b (find-it {:class "text", :name "login"}) (input-text "username")) (-> b (find-it {:class "text", :name "password"}) (input-text "password")) (-> b (find-it :input {:value "Log in"}) click) (is (-> b (find-it {:href "/logout"}) present?)) (finally (-> b quit))))) In most of my tests, there's going to be (highlighted in red text above) the declaration of the browser, a tweak to how long to wait before declaring something not found, and a try-finally for closing the browser regardless of the test's outcome. I'd like a test definition to just list the browser type (e.g. :firefox) and the URL and the test steps... leaving out the let, the implicit-wait, and the try-finally. Can there be a macro that defines browser b for the test steps that I feed into it? For the test steps themselves, the way an html element is found (find-it {:text "Login"}) could be factored out and made re-usable... (defmacro login-link [browser & actions] `(-> ~browser (find-it {:text "Login"}) ~@actions)) (defmacro username [browser & actions] `(-> ~browser (find-it {:class "text", :name "login"}) ~@actions)) (defmacro password [browser & actions] `(-> ~browser (find-it {:class "text", :name "password"}) ~@actions)) (defmacro login-btn [browser & actions] `(-> ~browser (find-it :input {:value "Log in"}) ~@actions)) This allows my tests to look like this instead: (deftest test-login (let [b (start :firefox "https://github.com")] (try (implicit-wait b 60000) (login-link b click) (username b (input-text "username")) (password b (input-text "password")) (login-btn b click) (is (-> b (find-it {:href "/logout"}) present?)) (finally (-> b quit))))) Is this a good way to do it? Can my macros be changed to eliminate the mention of the browser b as the first argument? (I'm guessing this is bad practice) And is there something I can do to reduce the boilerplate in my macro definitions so that I can say this instead... (defelem login-link {:text "Login"}) (defelem username {:class "text", :name "login"}) (defelem password {:class "text", :name "password"}) (defelem login-btn *:input* {:value "Log in"}) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en