22. ... Testing: Spock
@Speck
@RunWith(Sputnik)
class PublisherSubscriberSpeck {
def "events are received by all subscribers"() {
def pub = new Publisher()
def sub1 = Mock(Subscriber)
def sub2 = Mock(Subscriber)
pub.subscribers << sub1 << sub2
when:
pub.send("event")
then:
1 * sub1.receive("event")
1 * sub2.receive("event")
}
}
23. Testing: EasyB ...
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
}
24. before "start selenium", {
given "selenium is up and running", {
// start selenium
}
}
scenario "a valid person has been entered", {
when "filling out the person form with a first and last name", {
selenium.open("http://acme.racing.net/greport/personracereport.html")
selenium.type("fname", "Britney")
selenium.type("lname", "Smith")
}
Testing: EasyB ...
and "the submit link has been clicked", {
selenium.click("submit")
}
then "the report should have a list of races for that person", {
selenium.waitForPageToLoad("5000")
values = ["Mclean 1/2 Marathon", "Reston 5K", "Herndon 10K", "Leesburg 10K"]
for(i in 0..<values.size()){
selenium.getText("//table//tr[${(i+3)}]/td").shouldBeEqualTo values[i]
}
}
}
after "stop selenium" , {
then "selenium should be shutdown", {
// stop selenium
}
}
25. Dependency Injection
• Hollywood Principle
– Don‘t call us, we‘ll call you
• “All problems in computer science
can be solved by another level of
indirection”
• "...except for the problem of too
many layers of indirection“
– For attributions, see
http://en.wikipedia.org/wiki/Inversion_of_control
26. Dependency Injection
• Pattern for loosely coupled & testable objects
class Client { class Client {
Calculator calc = Calculator calc
new CalculatorImpl() def executeCalc(a, b) {
def executeCalc(a, b) { calc.add(a, b)
calc.add(a, b) }
} }
}
Service locator/factory Need to select setter,
constructor, field style
Tightly coupled?
Can add complexity
Hard to test?
Manage configuration
Easy to understand?
Direct or framework
Refactoring/navigation?
Consistency/lifecycle
27. Dependency Injection: Spring ...
• Several flavors
– let‘s look at Annotation and BeanBuilder flavors
import org.springframework.stereotype.Component
@Component class AdderImpl {
def add(x, y) { x + y }
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component class CalcImpl3 {
@Autowired private AdderImpl adder
def doAdd(x, y) { adder.add(x, y) }
}
45. ... Duplication: Simian
Similarity Analyser 2.2.23 -
http://www.redhillconsulting.com.au/products/simian/index.html
Copyright (c) 2003-08 RedHill Consulting Pty. Ltd. All rights reserved.
Simian is not free unless used solely for non-commercial or evaluation
purposes.
{failOnDuplication=true, ignoreCharacterCase=true,
ignoreCurlyBraces=true, ignoreIdentifierCase=true,
ignoreModifiers=true, ignoreStringCase=true, threshold=6}
Found 6 duplicate lines in the following files:
Between lines 201 and 207 in
/Users/haruki_zaemon/Projects/redhill/simian/build/dist/src/java/
awt/image/WritableRaster.java
...
Found 66375 duplicate lines in 5949 blocks in 1260 files
Processed a total of 390309 significant (1196065 raw) lines in 4242 files
Processing time: 9.490sec
49. Builds: Groovy from Ant
• Need groovy jar on your Ant classpath
<taskdef name="groovy"
classname="org.codehaus.groovy.ant.Groovy"
classpathref="my.classpath"/>
<target name="printXmlFileNamesFromJar">
<zipfileset id="found" src="foobar.jar"
includes="**/*.xml"/>
<groovy>
project.references.found.each {
println it.name
}
</groovy>
</target>
50. Builds: Ant from Groovy
• Built-in (need ant.jar on your Groovy classpath)
new AntBuilder().with {
echo(file:'Temp.java', '''
class Temp {
public static void main(String[] args) {
System.out.println("Hello");
}
}
''')
javac(srcdir:'.', includes:'Temp.java', fork:'true')
java(classpath:'.', classname:'Temp', fork:'true')
echo('Done')
}
// =>
// [javac] Compiling 1 source file
// [java] Hello
// [echo] Done
51. Builds: Gant
• lightweight façade on Groovy's AntBuilder
• target def‘ns, pre-defined ‗ant‘, operations on
predefined objects
includeTargets << gant.targets.Clean
cleanPattern << [ '**/*~' , '**/*.bak' ]
cleanDirectory << 'build'
target ( stuff : 'A target to do some stuff.' ) {
println ( 'Stuff' )
depends ( clean )
echo ( message : 'A default message from Ant.' )
otherStuff ( )
}
target ( otherStuff : 'A target to do some other stuff' ) {
println ( 'OtherStuff' )
echo ( message : 'Another message from Ant.' )
clean ( )
}
52. Builds: GMaven
• Implementing Maven plugins has never been
Groovier!
• Groovy Mojos
– A Simple Groovy Mojo
• Building Plugins
– Project Definition
– Mojo Parameters
• Putting More Groove into your Mojo
– Using ant, Using fail()
• gmaven-archetype-mojo Archetype
• gmaven-plugin Packaging
55. Builds: Gradle ...
• A very flexible general purpose build tool like Ant
• Switchable, build-by-convention frameworks a la Maven.
But we never lock you in!
• Powerful support for multi-project builds
• Powerful dependency management (Apache Ivy based)
• Full support for your existing Maven or Ivy repository
infrastructure
• Support for transitive dependency management without
the need for remote repositories or pom.xml/ivy.xml files
• Ant tasks as first class citizens
• Groovy build scripts
• A rich domain model for describing your build
57. Builds: Hudson
• Gant Plugin — This plugin allows Hudson to invoke
Gant build script as the main build step
• Gradle Plugin — This plugin allows Hudson to
invoke Gradle build script as the main build step
• Grails Plugin — This plugin allows Hudson to invoke
Grails tasks as build steps
• Hudson CLI and GroovyShell Usage pattern?
Source: http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.html
68. Modularisation: OSGi
This is Apache Sling in five bullets:
• REST based web framework
• Content-driven, using a JCR content repository
• Powered by OSGi
• Scripting inside, multiple languages See also: Grails JCR plugin
• Apache Open Source project
See also: http://hamletdarcy.blogspot.com