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

Reply via email to