Tuesday, March 11, 2014

First Project With Scala

So I started my first project with Scala about six months ago.  I had hired a new guy to build some automated testing out for our main application, and I figured that was a fairly low risk type of project to kick the tires out on.  I knew I was going to be using Web Driver to do most of the work, so it seemed largely irrelevant to me what language was actually pushing the commands out, they are probably all roughly the same.  Also, the resource I hired was still in school, so this would be a chance to see how quickly someone with limited coding experience, could pick up Scala and use it for something.  This project wasn't going to have to have any fancy design or be overly complicated, so we could ease into it without getting too sophisticated in the functional world yet.

The project is here: https://github.com/johntbush/sakai-test-suite.  I wanted to use cucumber because our application is pretty large and complex and I had another tester guy who already knew the functional aspects of the application, so I figured he could write cucumber tests and feed them to my automation Scala newbie to implement.  We stuck with maven for building, junit, and other tools we were familiar with.  This was a classic ease into Scala type of project.

Within a few days I had the basic skeleton working. I actually struggled more with getting cucumber to work with scala and junit, more than anything else.  Really the stupid phantomjs driver (nice idea, not a fan) and getting everything pulled into jenkins was much harder than anything to do with the Scala language.  Just basic Selenium funkiness, especially with the iframes in our app too some time to figure out, the dsl in Scala was really nice to work with.  This lead me to my first conclusion, the frameworks matter. You can have all the nails in the world, but without a hammer to drive them in, you are screwed.  The nails being power of Scala, hammer the frameworks... ok you get the idea.  You weren't expecting a fucking poet here were you ?

Singletons Are Built In

So the first cool thing I discovered was that Scala has built in singletons.  If you come from Java world, that was like a big deal to me.  Because its either dependency injection (I really didn't need to be that fancy in this app), or having to create a whole class with single instance of itself with static method and all that.  Yeah, its not hard, and yeah I've done it a million times, but it sure was nice to just go:


1:  object Config extends Config  
2:  class Config {  
3:   val systemProperties = System.getProperties()  
4:   val targetServer: String = loadProperty ("target.server","https://nightly.cle.rsmart.com/portal")  
5:   val sakaiVersion : String = loadProperty("sakai.version", "2.9.1")  
6:   val sakaiDistro : String = loadProperty("sakai.distro", "ani")  
7:   val defaultAdminEid : String = loadProperty("sakai.admin.eid", "admin")  
8:   val defaultAdminPassword : String = loadProperty("sakai.admin.pwd", "admin")  
9:   def defaultCourseSiteId = "course-test-1"  
10:   def defaultCourseSiteTitle = "Course Site Test 1"  
11:   def defaultInstructorEid = "instructor1"  
12:   def defaultStudentEid = "student01"  
13:   def defaultInstructorPassword = "password"  
14:   def defaultStudentPassword = "password"  
15:   def loadProperty (name : String, defaultValue : String) = {  
16:    if (!StringUtils.isEmpty(systemProperties.getProperty(name))) {  
17:     systemProperties.getProperty(name)  
18:    } else {  
19:     defaultValue  
20:    }  
21:   }  
22:  }  

Now I had a nice Config object, defaulted by a properties file, overridable by system properties.  I could call from anywhere else and not worry about injection or any of that business.  Nothing fancy, quick and dirty, does the job:

    Portal.navigateToPage(Config.targetServer)

You can pass functions around?!

So this is something every language but Java seems to have, but when you've been living without it for a long time... its like a conjugal visit.  I had one piece of code that was basically the same as this other piece of code except for a block in the middle.  So I move the two blocks into functions, and then invoked the surrounding method by passing that in and applying it at the right spot.  Its too much code to share here, if you can see:  https://github.com/johntbush/sakai-test-suite/blob/master/src/test/scala/com/anisakai/test/pageobjects/SiteManageTool.scala, look at the createProjectSite() and createCourseSite().  I think there is a better way to do that now that I know more, but whatever this is part of my journey.


More bad language, unfiltered opinions, and voodoo coming


Ok, all for now, next post I'll talk about my new project with Play! and emberjs, where we learn about implicit parameters, and implicit methods and all kinds of awesome voodoo that makes for some really concise and powerful code.  Stay tuned more coming....

No comments:

Post a Comment