Chapter 9. Collaborative and barrier-free development with Groovy and Scala – Agile ALM: Lightweight tools and Agile strategies

Chapter 9. Collaborative and barrier-free development with Groovy and Scala

 

This chapter covers

  • Approaches for integrating different languages and tools for barrier-free testing
  • Agile and polyglot, with Groovy
  • Scala and BDD, with specs2

 

In this chapter, we’ll continue to discuss collaborative development and testing. We’ll talk about approaches to integrating different languages for barrier-free programming and testing. In our discussion, I’ll use the term “polyglot,” which means multilingual, to refer to using different languages for software engineering, in conjunction, to solve a given problem.

 

Polyglot Programming

“Polyglot programming refers to leveraging existing platforms by solving problems via solutions that compose special purpose languages.”—Neal Ford[1]

1 Neal Ford, “Polyglot Programming: Building Solutions by Composing Languages”, www.devx.com/codemag/Article/39419/1763.

 

We’ll discuss Groovy and Scala, both of which are major languages that run on the JVM. Groovy and Scala, used together with Java, bridge different languages, technologies, and tools, providing many valuable features throughout the development lifecycle. As a consequence, Groovy and Scala enable the development of software without any barriers, which makes software development a “barrier-free” experience. Both languages offer interesting features for setting up a polyglot ecosystem, leveraging existing platforms by providing solutions that involve special purpose languages. With Groovy and Scala, you can also write tests and use behavior-driven development, which helps to overcome various barriers:

  • Barriers between project phases and project activities (because coding and testing move together more closely)
  • Barriers between artifact types (because code and executable specifications are written on the same unified infrastructure)
  • Barriers between project roles (because tests are written collaboratively, with mechanisms to use terms close to the problem domain)
  • Barriers between tools (because the same tools are used for programming and testing)

In summary, barrier-free development accelerates feedback loops and removes the sources of many potential problems that are barriers to quality.

We’ve already looked at strategies for avoiding many common problems, and we’ve discussed integrated approaches. Now let’s start to discuss Agile and polyglot programming with Groovy.

9.1. Agile and polyglot with Groovy

This section contributed by Vaclav Pech

When talking about Agile practices and barrier-free development and testing, we should discuss the Groovy programming language. Due to its features, Groovy is destined to enrich ALM and overcome barriers between testing, development, and operations.

Groovy is an object-oriented programming language, and it’s the major language on the JVM besides Java and Scala. It’s a dynamic language that can also be used for scripting. Groovy is compiled to the JVM bytecode and works seamlessly with other bytecode that originates from Java sources.

Groovy is well positioned to be used for testing Java code. These are the most noteworthy features that prove this:

  • Groovy has the built-in Power Assert command (assert), which provides detailed error reports on what went wrong during the running of assertions.
  • Groovy has built-in support for JUnit, so you can script JUnit tests in Groovy for your Groovy and Java classes.
  • Groovy has relaxed rules for typing that increase test versatility and reduce the verbosity of tests.
  • Groovy has relaxed accessibility rules that give tests the freedom to access pretty much any field, method, or class without having to raise the access permission level in the target code.
  • Groovy allows easy stubbing and mocking of Java classes thanks to the dynamic nature of Groovy meta-programming.
  • Groovy allows scripts to run Groovy tests against an already running application. For example, a web application administrator can log in and type in Groovy code to verify the internal state of the application with a few asserts, getting back immediate feedback about the health of the system.

Thanks to its tight relationship with Java, Groovy can leverage the Java infrastructure completely. All Java libraries can be used as-is in Groovy code. And vice versa, all Groovy-written code is fully accessible from Java or any other JVM-based programming language, such as Scala or Clojure. The power of Java and Groovy code’s seamless integration can lead to fancy constructs. For example, consider a Groovy class that implements a Java interface and that will be extended by a Java class. In this construct, a modern editor would not distinguish between the origins of methods, be it a Java artifact or a Groovy artifact (see the following listing).

Listing 9.1. Mixing Java and Groovy

In recent years, the Groovy community has generated numerous frameworks, the impact of which often extends beyond the boundaries of the Groovy world. Let’s look at some of them.

  • Gradle (http://gradle.org) is a universal, enterprise-grade build system aiming to compete with and replace Maven. Although implemented in Java, Gradle chose a Groovy-based DSL as the language in which to write build scripts and configuration.
  • Grails (http://grails.org) is a rapid web application development framework that adopts many of the Ruby on Rails ideas, such as easy prototyping, scaffolding, configuration-by-exception, DRY[2] or DSL-based MVC architecture, as well as proven, enterprise-scale, Java-based technologies. Groovy serves as the glue language, connecting all the technologies, and a family of Groovy-based DSLs enables developers to create their applications quickly and easily.

    2 Don’t Repeat Yourself.

  • Griffon (http://griffon.codehaus.org), like Grails, adopts many of the Agile principles discussed in this book to rapid desktop application development and uses Groovy as the glue and DSL language.
  • Gaelyk (http://groovy.codehaus.org/Gaelyk) is a lightweight Groovy toolkit for developing and deploying Groovy applications on Google’s App Engine. It provides a set of DSLs to define the MVC structure of an application and access GAE APIs, like data management, email service, and others.

Groovy’s ALM features include built-in testing and mocking capabilities, low-ceremony language constructs, the flexibility to create intuitive yet powerful domain-specific languages (DSLs), a rich ecosystem of innovative frameworks, and the ability to alter code at runtime through scripting or meta-programming. Add in Groovy’s Java-like syntax, seamless Java-to-Groovy and Groovy-to-Java interoperability, mature IDE support, and build tool integration, and you’ll see Groovy as the powerful vehicle that it is, with the potential to attract and serve well many of the approximately 9 million Java developers worldwide. Several aspects in particular are worth discussing in more depth.

 

Typing on the Java Virtual Machine

Groovy is a dynamically typed programming language, whereas Java and Scala are statically typed. Generally, a language is said to use static typing when type checking is performed at compile time as opposed to runtime (which is dynamic typing). With JSR 223, version 6 of the Java Standard Edition can also execute scripting languages.

Java 6 comes with its own exemplary language—the Rhino JavaScript engine. Besides that, languages like JRuby, Jython, Groovy, and Scala produce Java bytecode that runs on the JVM. Nowadays, the JVM is more a deployment system and runtime environment that can run many languages other than Java. With JSR 292 (and its new invoked dynamic bytecode), the VM offers support for other languages out of the box. Running something other than Java source compiled code on the JVM is a generational advancement in the technology.

 

First, Agile development refers to light processes as being “low ceremony,” which many developers find more effective and productive than verbose processes that require a great deal of “ceremony.” Groovy can help to reduce the ceremony involved with scripting.

9.1.1. Low ceremony and scripting

Compared to Java, Groovy reduces the implied ceremony in code, often by a factor of two or more. A dedicated syntax for lists, maps, or functions; an enhanced closure-based API for the JDK classes, called GDK (Groovy Development Toolkit); powerful operators; properties; named parameters; dynamic typing; and many other features all help express programmers’ ideas concisely.

Look at the following snippet, for example. You can see that the dedicated syntax for collections plus all the collection-processing methods added to collections, lists, and maps by Groovy reduce verbosity and clearly express the programmer’s intent:

['Java', 'Groovy']*.toUpperCase()
def cities = [
'Germany' : 'Berlin'
'United Kingdom' : 'London'
'France' : 'Paris'
]
[
'http://groovy.codehaus.com',
'http://www.dzone.com',
'http://www.infoq.com'
].collect {it.toURL().text}.findAll{it.contains 'groovy'}

As a dynamic language, Groovy can accept new code at runtime. A running application could receive new source code as text from the user or as a file, a URL, a database, or any other location, and then compile and use it. Putting aside the security concerns, which should certainly be considered and handled (perhaps by leveraging the standard Java mechanisms of security managers), being able to add code to a live application opens new possibilities. Think of an administration console allowing the administrator to fire ad hoc queries or tests against a server-side application. Imagine a business rule engine offering the ability to alter the rules on the server without any downtime.

Groovy scripting, particularly when combined with the DSL aspect of the language, can also implement macro support, allowing users to customize or automate functionality of off-the-shelf software.

9.1.2. Domain-specific languages

Domain-specific languages (DSLs) are valued for allowing developers to express their ideas in terms close to the problem domain. The smaller the gap is between the language and the domain, the less code is needed (because the code is written in a special purpose language focused on the given problem area) and the fewer bugs that are likely to occur in the program. As a convenient side effect, a nonprogrammer domain expert can often understand and verify the code written by a programmer.

Groovy offers a whole set of tools for creating DSLs. The first feature is the relaxed syntax regarding parentheses, semicolons, and the return keyword, which helps reduce boilerplate code. The ability to override standard operators is also handy in this context. The principles of categories and mix-ins enable classes to take on methods and properties of other classes. And we must not forget about the ability to alter the definition of any class or object at runtime.

To give you a taste of what’s possible, in the micro-DSL shown in the following snippet the left shift (>>) operator is overridden to indicate a request to transfer money between two accounts. I defined dynamic properties to convert numbers to money or dates, respectively, and I altered the behavior of the toUpperCase method on the string 'Joe' to add an exclamation mark at the end of the string, hiding the original functionality.

'Account1' >> 350.eur >> 'Account2'
(3.days + 5.hours).ago
'Joe'.metaClass.toUpperCase = {-> delegate + '!'}

In addition to runtime modifications, the recent addition of AST Transformations to Groovy enables greater flexibility at compile time, with all the benefits of higher performance and potential assistance from IDEs or other tools when compared to the runtime code modifications. In the following code, you can see the Registrations class defines a field named items. Thanks to the @Delegate annotation, all public methods of java.util.List are added at compile-time to the Registrations class, so users can invoke List-specific methods on Registrations instances (people in this case) directly.

class Registrations {
   @Delegate List items = []
}

def people = new Registrations()
people.addAll(["Joe", "Dave"])
assert ["Dave", "Joe"] == people.reverse()

This, combined with no restrictions (whether the enhanced class has been defined in Java or Groovy), puts explosive power at the developer’s fingertips. No wonder frameworks such as Grails or Griffon, the success of which depends on the flexibility and power of their DSLs, have been created around Groovy and enjoy a rapidly increasing adoption rate.

Check out the following examples of DSLs used to build Grails applications. The first example shows the ease of creating simple database queries:

def recentBooks = Book.findByReleaseDateBetween now - 5, now

Defining constraints for a domain class is also intuitive, isn’t it?

country nullable:false, unique:true, inList:['de', 'uk', 'cz', 'at']

Another DSL is ready to make your life easy whenever you need to explicitly define the mapping of your domain classes to database tables:

static mapping = {
table 'CONFERENSES'
if (current == PRODUCTION) {
country column:'COUNTRY_CODE'
age type:'integer'
}
participants fetch:'join', sort:'name'
}

DSLs help create tools that solve problems in a specific domain. Spock and easyb are two BDD testing tools implemented as DSLs in Groovy.

9.1.3. Testing with easyb and Spock

Writing good tests is an important aspect of Agile development. Groovy comes with built-in support for testing and mocking and can be used to test both Java and Groovy code. IDE support for Groovy is quickly improving and now allows for efficient TDD practices, such as the ability to define or alter class or method definitions for a specific usage or to refactor and generate code. Two BDD frameworks have emerged from the Groovy community—easyb and Spock. Thanks to the close Groovy and Java relationship, they can both be used to implement BDD on pure Java projects.

easyb (www.easyb.org) is a BDD framework for the Java platform. By using a specification-based DSL, easyb aims to enable executable, yet readable, documentation. Its specifications are written in Groovy and run via a Java runner that can be invoked with the command line, with Maven, or with Ant. What’s more, easyb supports a few different styles of specifications that range from RSpec’s to a story-based DSL with givens, whens, and thens. The following example shows a test case where we invoke the zipvalidate function using an invalid zip code, and we confirm that it appropriately returns the value of false:

given "an invalid zip code", {
   invalidzipcode = "221o1"
}
and "given the zipcodevalidator is initialized", {
   zipvalidate = new ZipCodeValidator()
}
when "validate is invoked with the invalid zip code", {
   value = zipvalidate.validate(invalidzipcode)
}

then "the validator instance should return false", {
   value.shouldBe false
}

easyb stories provide an easy way to capture user requirements in natural language, making requirements closely match normal conversations between people. The plain text story DSL is separated from the behavior DSL and implementation. At the early stages of gathering requirements, empty or “pending” stories will typically be created. Pending stories are not yet implemented and leave the closure body unimplemented. The implementation is expected to be provided later in the process by adding bodies to the textual descriptions of the different steps of the story.

Spock (http://code.google.com/p/spock/) is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. As you can see from the following snippet, Spock code tweaks Java syntax quite a bit. It allows you to create several sections describing different aspects of your test, each labeled accordingly, such as expect:, where:, when:, and then:.

class HelloSpock extends spock.lang.Specification {
    def "can you figure out what I'm up to?"() {
        expect:
        name.size() == size

        where:
        name << ["Kirk", "Spock", "Scotty"]
        size << [4, 5, 6]
    }
}

Whereas easyb takes a more traditional approach to defining DSLs in Groovy, Spock relies on compile-time AST Transformations and therefore can stretch the allowed syntax a bit further. While Spock provides syntax that looks different from typical Java or Groovy code, Spock feels comfortable to developers, who are used to unit testing frameworks like JUnit. By leveraging the power of Groovy meta-programming and DSL definition abilities, together with being able to help pure Java shops, both frameworks serve as good examples of typical citizens of the Groovy ecosystem.

9.1.4. Groovy Maven ecosystem

Besides IDE support, build tools also support working with Groovy. Groovy is designed to run alongside Java, so any build tool that works for Java works for Groovy as well. The following listing shows an example Maven POM for compiling Groovy classes.

Listing 9.2. Compiling Groovy with Maven

Groovy is one of the languages you can use to write POM information that Maven supports. If you would prefer to write your POM as source code, as opposed to XML, Groovy supports that approach. A translator tool is also available to translate a given POM into a Groovy derivate by calling translator pom.xml pom.groovy.

The following listing shows an example POM written in Groovy.

Listing 9.3. A Maven POM, written in Groovy
project {
    modelVersion '4.0.0'
    parent {
        artifactId 'artifact-parent'
        groupId 'group'
        version '1.0.0-SNAPSHOT'

    }
    artifactId 'artifact'
    version '1.0.0-SNAPSHOT'
    name 'name'
    url 'http://maven.apache.org'
    dependencies {
       dependency { groupId 'junit'; artifactId 'junit'; 
         version '4.7'; scope 'test' }
       dependency { groupId 'org.hamcrest'; artifactId 'hamcrest-all';
         version '1.1'}
       dependency { groupId 'log4j'; artifactId 'log4j'; 
         version '1.2.12' }
    }
    profiles {
        profile {
            id 'development'
            properties {
                 'log4j.level' 'DEBUG'
            }
        }
        profile {
            id 'production'
            properties {
                 'log4j.level' 'WARN'
            }
        }
    }

    properties {
         'log4j.level' 'info'
    }
}

Because Groovy is supported in all modern IDEs, writing POMs this way can be even more fun.

Groovy has many interesting applications that can help you support an Agile ALM. Scala/specs2 provide another useful approach that supports BDD.

9.2. BDD with specs2 and Scala

This section contributed by Radosław Holewa

Scala, which is short for “scalable language,” is a statically typed hybrid for object-oriented and functional programming. It runs on the Java platform (JVM) and is interoperable with Java. The Java and Scala languages share the same runtime environment and deployment infrastructure. As a result, you can invoke your existing Java code from inside your Scala methods and also invoke Scala code from Java. Scala, Java, and Groovy can all be used together, so you can choose the language that best fits your particular requirements without leaving the JVM ecosystem.

Scala is popular, and API-breaking changes in new versions are rare. Scala was created at a university, and clarity and richness of features were the goals in mind. Scala is a fully object-oriented language. Every value or variable used in your code is an object. This also holds for Java primitive types, which come with their own Scala wrapper classes. In Scala, functions are first-class citizens. You can create anonymous functions, pass functions as parameters of other functions, and even return functions as method results. But Scala functions are also objects. You can even derive subclasses from function types.

Scala works well in multithreaded environments due to its Actors library, which was inspired by Erlang actors.[3] Hence, multithreading applications written in Scala are often more reliable and scalable than their Java counterparts. For example, using actors prevents data races caused by inconsistent states, because the data is encapsulated within actors and can’t be accessed from outside. The only way for actors to cooperate is by sending messages to each other.

3 For more information on the Erlang programming language and runtime environment, see www.erlang.org.

Scala is an interesting and important language; it’s a generational advance in terms of syntax and programming language approach. Fifty years of programming language design influenced the design of Scala, and the Scala language’s origins are a major distinguishing feature as compared to Java. Java has grown over the years to serve as an easy, multipurpose language. Scala, in contrast, represents new ideas that many programmers haven’t seen (such as applying functional programming). This can help us all reflect on how we approach BDD and provides new models for abstraction. Scala’s core is small but extensible, and its SDK contains many useful libraries that were developed by extending the Scala core, including the Actors and XML libraries. The language’s flexibility also helps in creating internal and external DSLs. Scala allows you to develop your own syntax on top of Scala language features, and it also provides combinator passing for processing your own external DSL grammars.

9.2.1. Scala/specs2

specs2 (http://specs2.org) is one of the most popular external Scala libraries. It provides a BDD framework that was created by Eric Torreborre. Specs2 leverages Scala’s flexibility and offers many constructions useful in helping to write BDD tests.

Now it’s time for some fun. Let’s code a Coca-Cola machine example in Scala, using the specs2 framework! (If you’re wondering, I don’t get any rebates from Coca-Cola for doing this.)

We’ll define our specifications within the CocaColaMachineSpec object:

import org.specs2.mutable._
object CocaColaMachineSpec extends Specification { 
  "coca-cola machine" should { 
   "sell one can and return change" in { 
   } 
   "not sell can because of wrong price and return all money" in { 
} 
   "not sell can because of missing cans and return all money" in { 
   }
  }  
}

This snippet is written in what specs2 calls unit specification style, where the text is interleaved with the specification code. As you can see, we created the specification using almost pure natural language. Thanks to this fact, it’s readable not only by developers, but also by other project stakeholders.

The first example could be read as “coca-cola machine should sell one can and return change.” This is the specification of the first use case: The Coca-Cola machine will sell the child a can of Coke. This kind of definition obviously helps in understanding what effect the processing should have. It also shows how elegant BDD tests can be.

The body of this example is implemented in the next step. Here is the implementation of the first part of our specification:

"coca-cola machine" should { 
    def machine = CocaColaMachine.create(5, 2) // some factory
  
    "sell one can and return change" in { 
      val (can, change) = machine.sell(4) 
      can must not beEmpty
      change must be_==(2) 
    } 
}

 

Declaring matchers

There are different ways to declare and use matchers that can look more or less like using the English language. For example, the canonical way of expecting an option to be “not empty” is can must not beEmpty.

This can also be written as can must not be empty (works with any object that has an isEmpty method), but this needs a bit more machinery than creating only a new matcher. Therefore, if you want to create a matcher like this:

moneyInEur1 must not be matchingMoney(moneyInEur2)

instead of

moneyInEur1 must not beMatchingMoney(moneyInEur2)

you would have to create a new implicit definition:

implicit def toMoneyResult(r: MatchResult[Money]) = 
  new { def matchingMoney(m: Money) = 
  r.apply(beMatchingWith(m))}

Consult the specs user guide (http://code.google.com/p/specs/wiki/UserGuide) for all options.

 

Let’s take a closer look at this example. We invoke the sell method on the machine object and receive the Coke can and change as a result. Scala/specs2 provides a special internal DSL for writing specifications. As you can see,

  • can must not beEmpty checks if the machine delivers the can
  • change must be_==(2) checks if the returned change is 2

Thanks to the internal DSL, the code for final state checking is clear immediately. The whole CocaColaMachineSpec object is presented in the following listing.

Listing 9.4. The CocaColaMachineSpec object

First we use the factory method invocation to create an instance of the CocaCola-Machine class. For each instance, we invoke the sell() method with the amount of money as the argument, check the first value of the returned tuple to make sure it isn’t empty, and then confirm the value of the returned change .

 

Specification: Class or Object?

A specification can be either a class or an object. Using the class approach, you could execute the class with scala -cp <...> specs2.run CocaColaSpec.[4] JUnit can also execute this by appending WithUnit to the extended class name: class CocaColaSpec extends SpecificationWithJUnit.

4 The classpath is represented by the <...> placeholder.

 

specs2 is a powerful BDD framework with many useful features. It’s also flexible, which means you can easily extend specs2. Let’s consider a subset of the previously discussed code snippet:

val (can, change) = machine.sell(2) 
can must beEmpty 
change must be_==(2)

You can see what a nice piece of code we’ve specified using specs2. This code fragment looks friendly and ensures good readability: can must beEmpty. The preceding code checks the value against an empty matcher represented by beEmpty, which is the special matcher that was created for checking options.

 

Matchers

Matchers as defined in specs and pattern matching are two different things. A specs matcher generally doesn’t use pattern matching. You can find more details on general pattern matching with Scala here: www.scala-lang.org/node/120.

 

Matchers are constructs that simplify the code. Specs offers many predefined matchers out of the box, but you can create a new one, as the following example illustrates. Let’s start by creating Currency object:

object Currency extends Enumeration { 
  type CurrencyType = Value 
  val EUR, USD, CHF = Value 
}

This code is an example of an enumeration definition in Scala. It defines an enumeration of currency values: EUR, USD, and CHF. We’ll use our currency enumeration as the type of currency value in the Money class:

class Money(val value: Integer, val currency: Currency.CurrencyType) { 
  override def equals(obj: Any) = { 
    val money = obj.asInstanceOf[Money] 
    value.equals(money.value) && currency.equals(money.currency) 
  } 
  
  override def toString = value + " " + currency 
}

The class overrides two methods. The equals method is used by the matcher. The Money class contains two overridden methods: equals() and toString(). The equals method will be used to compare Money objects that belong to the matcher class. (You could also create the Money class as a case class here to avoid ClassCastException with obj.asInstanceOf[Money]).

Now let’s create a new matcher for the Money class. There are different ways of creating matchers in specs2, but here is the simplest way:

def matchMoney(money: Money): Matcher[Money] = { 
  (m: Money) => (m.equals(money),
                 m + " is equal to " + money, 
                 m + " is not equal to " + money) 
}

The following listing shows how this matcher can be used in a simple specs example.

Listing 9.5. Specs2 in our example

As you can see, matchers make your code compact by hiding checks inside their implementation and providing intuitive DSL-like constructions that can be reused in specifications.

Another nice and useful feature of specs2 is data tables. Consider a simple test where you want to check whether the sum of two given values was calculated correctly. The simplest way to write such a test is to add two values directly and compare the result with the sum. But what happens if your test is invoked for many different predefined value pairs? This is where the specs2 data table feature enters the game. This example illustrates how to use it:

"calculation example" should { 
  "add values correctly" in { 
    "first value" | "second value" | "sum" |> 
      1           !      2         !  3    | 
      4           !      5         !  9    | { (value1, value2, sum) => 
         (value1 + value2) must be_==(sum) 
      } 
    } 
 }

Here, we define a data table with two rows of data and one row with table column names. The first and second columns contain values that will be added, and the third column contains the sum of the two values. The code (value1 + value2) must be_==(sum) will be invoked for every row in the data table (excluding the column headers row). Obviously, this is a simple and powerful solution for providing a test data set.

 

Eric Torreborre on the present and future of specification tools

As he reviewed this chapter, Eric Torreborre, the founder of specs/specs2, offered the following comments:

“I built the Forms support in specs2 as an alternative to Fit in the Java world. I wanted to (a) get the specification closer to statically typed code (whereas in Fit the tables can’t be type checked); (b) propose more complex forms that can be composed instead of simple tables—this suits better complex domain models; and (c) still allow for simple text to be used with appropriate code inserted to check the literal assertions. There is still a big gap to fill in terms of collaboration with the business analyst (or product owner or whatever role you give her). The big question is, can you let the BA write the specifications and then have the developer instrument them for execution? This point is important, because the person writing the specification ultimately owns it. That’s her work, her baby.

But there are fundamental difficulties in putting BDD and acceptance testing tools in the hands of a BA:

  • Tools need to live close and evolve with the code. Otherwise it’s prone to the same kind of evolution issues that we faced when trying to synchronize UML diagrams with code.
  • Specification text needs to be version controlled, which brings in concepts that aren’t so easy to understand for the BA (even for developers sometimes).
  • Successful specifications need to be constantly refactored like any code. This requires some thinking skills that are close to a developer mindset.

On the other hand, leaving all the BDD artifacts in the hands of the developers is also doomed to fail because it’s less easy to use the artifacts as communication and discussion tools.

In conclusion, I think that there is still room for improvement in that space. I can envision tools where the developer would build templates and components for accessing and setting up the business objects, domain, and services, and for checking up on them. Then the BA would use those tools to write up the specification. When those templates or components don’t exist, the BA should still be able to create some generic or not executable ones to start off the work.”

 

The last feature I’d like to mention in this context is the support for literate specifications.[5] Suppose you need to handle tests where the test description could also be a part of the code that will be invoked. This way, tests can be described using a natural language. And as another benefit, each change in the description will have an impact on the test execution.

5 For more information about literate specifications, see http://code.google.com/p/specs/wiki/LiterateSpecifications.

9.2.2. Specs2 forms

The next example was created using specs2 Forms and creates tables with your custom content in a convenient way.[6]

6 For more information on Forms, please consult the specs2 Forms documentation: http://etorreborre.github.com/specs2/guide/org.specs2.guide.Forms.html.

Listing 9.6. Specs2 Forms in action

With Forms, you can represent domain objects and declare expected values in tables. Forms can be composed of other Forms to accommodate composite information. specs2 allows you to write tests in what specs2 calls acceptance style. In a test written according the acceptance style, the implementation is isolated from the specification text and located elsewhere.

When using the acceptance style, a list of “fragments” is concatenated by the special caret character (^). Specification examples are written using the format: "description" ! body. Other special characters are used by specs2 as well. For instance, surrounding an item with triple double-quotes ("""), at its start and its end, allows things written on multiple lines to be treated as continuous strings. Another example are blocks that are separated from each other by introducing “p” as in “paragraph”. In the class, these special operations are often aligned on the right to leave the text on the left free from visual markers. For more information on the layout, see http://etorreborre.github.com/specs2/guide/org.specs2.guide.SpecStructure.html#Layout.

Running this example outputs the report that’s shown in figure 9.1.

Figure 9.1. A Forms sample, BDD with Scala

9.2.3. Scala build ecosystem

Scala artifacts can be built with Maven. This next listing shows an extract of a Maven POM for processing Scala artifacts.

Listing 9.7. A Maven POM that includes Scala

Besides Maven, the simple-build-tool (http://code.google.com/p/simple-build-tool), sbt for short, is another powerful option for building your Scala projects. sbt is written in Scala and can be configured and extended by using the Scala language, so you don’t need to leave your Scala platform to configure your build scripts. Additionally, sbt supports specs2 as well as advanced dependency management. You can use different dependency declaration types, including Ivy and Maven configuration files. It’s also possible to trigger sbt build scripts with Jenkins, using Jenkins’ dedicated plug-in (https://wiki.jenkins-ci.org/display/JENKINS/sbt+plugin).

9.3. Summary

This final chapter detailed collaborative and barrier-free development and testing. We introduced Groovy and Scala as languages that also run on the Java Virtual Machine. They’re part of the polyglot development movement, bridging different languages, technologies, and tools to gain the best benefit for specific project requirements. Both languages, Groovy and Scala, provide features that can bridge the distance between the coding and testing activities.

Roundup

In this book, we discussed what Agile ALM is, and we covered strategies and tools for implementing an Agile ALM. You’ve seen that ALM evolved from SCM, which in turn evolved from version control. An Agile ALM enriches an ALM with Agile strategies. Concepts are agnostic regarding tools, but I’ve offered suggestions on how to use and integrate lightweight tools while applying Agile strategies. Concepts, as well as tools, can be aligned with your individual requirements, and the resulting mash-up can form an Agile ALM. I’ve shown example toolchains along with different aspects of Agile ALM in dedicated chapters in this book.

Consider the following items, which we’ve discussed in this book:

  • Introduce quality gates—milestones in the project where quality requirements must be fulfilled
  • Work in isolation and as a team; maintain productive development environments, in order to focus on individual tasks, while also working collaboratively as a team in an efficient way
  • Commit early, commit often, to provide your changes to the team and to gain from fast feedback
  • Structure work so it’s aligned with tasks, to allow humans and tools to link work items to technical artifacts in a traceable way
  • Include audits to detect integration issues early and often, and to improve quality
  • Follow conventions as a team by aligning your work with standards that were committed to by the team
  • Apply barrier-free approaches to avoid silos by integrating tools, project phases, artifact types, activities, and considering polyglot languages and specification by example
  • Streamline your work by implementing strategies for building, testing, staging, and configuring artifacts

Also, consider the common questions I pointed to in chapter 1, including:

  • How can I improve communication in the team?
  • How can I set up a flexible infrastructure to secure the assets of my company?
  • What is the state of my software?
  • Which changes (requirements, bugs) are implemented in which artifacts?

Step out of your career as a software professional for a moment, and imagine yourself doing something different, perhaps building cars or managing a restaurant. Almost all of these activities involve interacting with a lot of people. These are all universal terms and questions—the ideas in this book can be extended well beyond issues of software development to address corporate challenges and project management.

In this book, we applied these universal principles to the specific instance of software programming. Each instance I picked could be slightly modified for a different managerial environment: For example, “How do I significantly improve the quality of the food I sell at my restaurant?” Obviously, the answers across different fields will differ, but the questions are remarkably similar. Gathering requirements and then testing to ensure that there is acceptable functionality is a good example of aspects that can be applied in many different situations.

In this book, I’ve developed a set of questions every business owner should be asking, and I’ve delivered answers for the specific instance of software programming. We’ve examined many different problem domains, and I’ve suggested a variety of ways to improve the development process in terms of both productivity and quality. I hope that you have enjoyed the book and will apply these approaches in your Agile ALM.