Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8542293
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T12:01:40+00:00 2026-06-11T12:01:40+00:00

Hope this is not a stupid question. For Regression testing, I wrote a small

  • 0

Hope this is not a stupid question.

For Regression testing, I wrote a small tool which uses Selenium to bring up the screen, verifies the loaded screen data against the database (multiple tables) and generates a report with screenshots (in case of errors).

Being a lazy guy that I am, instead of writing one class for single use case (~60 use cases for a screen), I wrote one single class which can accept multiple configuration files as a parameter. The configuration file dictates the flow of the testcase (in steps), the mapping of the xpath/id of the form field against the database query, the queries etc.

It all works well but the problem is that the configuration file is an XML. Neighboring projects are interested and would like to use the tool and I want them to easily understand the tool and customize to their needs. XML, in my opinion, is inappropriate here. Besides, the mapping between screen form fields and database columns are the same for many testcases which use the same screen for different use case combination. It would be great if there could be inheritance there instead of copying the content.

So, I am hoping to write a small DSL which goes something like

open application

load editClient window

switchTo generalTab

verify generalTab{

    if dataValidFor clientName then addInfoToReport else addErrorToReport
    if dataValidFor clientAddress then addInfoToReport else addErrorToReport
    if confidentialData visible then addInfoToReport else addErrorToReport

}
...

...

You get the idea. All I am planning to do is to translate the DSL to Java (or Groovy, if need be) method calls in the background. I understand that the requirement is not that huge to warrant a powerful library like Antlr. However, my experience with Groovy is very limited that I don’t even know whether it is possible in Groovy.

I referred to this presentation and it looks amazing. However, I am worried about the capability to include blocks in the DSL as in

verify generalTab{
...
}

PS : I am no expert in Lexers and Parsers (non-computer science under-grad) but I managed to self-learn ANTLR and played around with it for few weeks couple of years ago. Again, I have very little experience with Groovy.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T12:01:41+00:00Added an answer on June 11, 2026 at 12:01 pm

    I’m also no expert in groovy’s DSL, but have been playing with it a bit and i think your case is doable. But it is large.

    Writing

    verify generalTab { ... }
    

    Groovy seems to resolves to

    verify( generalTab({ ... }) )
    

    so a way near what you want would be to intercept method missing call (‘generalTab’ seems like a html component id to me, please correct me if i’m wrong).

    You will need: a verify() method and a methodMissing() method.

    Your if and elses… uh, can we swap it for when and otherwise? Just to avoid groovy’s own reserved words 😉

    Those double words after the if make the whole thing pretty ugly. It would be better if you could use a dot or just one word.

    when dataValidFor clientName then addInfoToReport otherwise addErrorToReport
    

    Resolves to

    when(dataValidFor).clientName(then).addInfoToReport(otherwise).addErrorToReport
    

    Which will be weird to parse. It is better if you could do something like:

    when dataValidFor('clientName') then addInfoToReport otherwise addErrorToReport
    

    I did the following:

    report = [:]
    
    // the closure passed as a parameter to the html component
    Closure runningVerification
    
    // the closure that handles adding info to report
    Closure addInfoToReport = { Data data -> 
      report[data] = "[INFO] Field '$data.field' from component '$data.component' valid: $data.valid"
    }
    
    // the closure that handles adding errors to report
    Closure addErrorToReport = { Data data -> 
      report[data] = "[ERROR] Field '$data.field' from component '$data.component' valid: $data.valid"
    }
    
    /*
     * The when() method will receive a data object and returns
     * a map to be handled by the 'then' and the 'otherwise' cases
     *
     * The 'then' and 'otherwise' must passes closures to this method
     */
    def when(Data data) {
      data.component = runningVerification.binding.htmlComponent
    
      [ then: 
        { Closure thenAction -> 
    
          if (data.valid) thenAction(data) 
    
          [ otherwise: 
            { Closure otherwiseAction -> 
              if (!data.valid) otherwiseAction(data) 
            }
          ]
        }
      ]
    }
    
    
    /*
     * Handles missing method calls. We need this to keep track of the 
     * 'generalTab', the HTML component whose tests are being ran against
     */
    def methodMissing(String method, args) 
    {
      runningVerification = args[0]
      runningVerification.delegate = this
      runningVerification.binding.htmlComponent = method // awful
      runningVerification()
    }
    
    
    /*
     * Verify the status of the validation for html component. The
     * argument is useless, it needs to access the report variable in 
     * the binding
     */
    def verify(dataValidation) {
      def errors = report.findAll { !it.key.valid }.size()
      report.each { println it.value }
      print "Result: "
      if (errors == report.size()) {
        println "Every test failed"
      } else if (errors == 0) {
        println "Success"
      } else {
        println "At least one test failed"
      }
    }
    
    class Data { String component; String field; Boolean valid }
    
    Data dataValidFor(String property) { 
      new Data(valid: new Random().nextInt() % 2, field: property)
    }
    
    Data confidentialData(String property) { 
      new Data(valid: new Random().nextInt() % 2, field: property)
    }
    
    
    verify generalTab {
      when dataValidFor('clientName') then addInfoToReport otherwise addErrorToReport
      when dataValidFor('clientCountry') then addInfoToReport otherwise addErrorToReport
      when confidentialData('clientId') then addInfoToReport otherwise addErrorToReport
    }
    

    And it works. It prints (randomly):

    [INFO] Field 'clientName' from component 'generalTab' valid: true
    [ERROR] Field 'clientCountry' from component 'generalTab' valid: false
    [INFO] Field 'clientId' from component 'generalTab' valid: true
    Result: At least one test failed
    

    It got pretty ugly. It’s more of a proof of concept. You need to separate the classes using BaseScripts, GroovyShell, delegate it to other classes, and the likes. You will also need to model it neatly, considering a class for reports and so. But so far, i think it’s doable. Rather large, though.

    My reading suggestions:

    Guillaume Laforge shows a script DSL for a robot in mars:
    http://www.slideshare.net/glaforge/going-to-mars-with-groovy-domainspecific-languages

    The art of Groovy’s command expressions:
    http://www.canoo.com/blog/2011/12/08/the-art-of-groovy-command-expressions-in-dsls/

    This is an email i sent to the groovy list today, once i managed to finish a DSL over JFugue for my personal use:
    http://groovy.329449.n5.nabble.com/Method-chaining-in-DSL-Instructions-td5711254.html

    It’s on github:
    https://github.com/wpiasecki/glissando

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Hope this question is not stupid since I am an amateur web designer. I
I hope that this is not a stupid question. Is it possible to redirect
i hope this is not a stupid question i need to rename microsoft access
I hope this is not a completely stupid question. I have searched quite a
I'm pretty new in .net, I hope this question will not sound stupid. How
I really hope this is not a question posed by millions of newbies, but
I hope this question is not 'controversial' - I'm just basically asking - has
I hope this question is not a duplicate but I didn't find anything equivalent
I hope this question will not be rejected as there is no code. But
dudes. I hope this question is not a repost. I'm newbie on Kohana. I'm

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.