how scala promotes tdd
DESCRIPTION
This talk demonstrates why Scala is in my opinion the best language to do TDD onTRANSCRIPT
![Page 1: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/1.jpg)
How Scala promotes TDD
How Scala allows you to write better and
more testable code
audience.filter(_.usesJava).foreach { member =>
sayHi(member)
}
![Page 2: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/2.jpg)
À La Carte
ApéritifTDD and programing languages
EntréeA short overview of Scala’s features
Plat Principal• Better value objects using Case Classes • Determinism via immutability
![Page 3: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/3.jpg)
À La Carte
Plat Principal (cont’d)• Better type safety, no nulls and less exception
throwing • Better composition and cross-cutting concerns
using Traits• Declarative asynchrony
Le Dessert• Specs2• ScalaTest• Plain old JUnit• Mocking
![Page 4: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/4.jpg)
Apéritif
![Page 5: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/5.jpg)
TDD and programing languages
There’s a set of programming language features that are
necessary in order to grow software using TDD. These
include referential transparency, well-defined types that
are easy to declare, the ability to separate concerns into
individual codes of block and, of course, providing the
means to write short, concise and clear tests.
![Page 6: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/6.jpg)
Entrée
![Page 7: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/7.jpg)
A short overview of Scala’s features
• A functional/OO programming language that runs on
the JVM
• Everything is an object – no primitive types
• Functions are first-class members, every function is a
value, including what is usually an operator
• Scala is statically-typed and supports type inference
![Page 8: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/8.jpg)
A short overview of Scala’s features
• Lambda expressions, closures and currying naturally
• Pattern matching
• Multiple inheritance through Traits
• Scala is extensible, allowing you to write your own
“language structures”
![Page 9: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/9.jpg)
Plat Principal
![Page 10: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/10.jpg)
Case Classes
Good software engineering makes use of value objects.
These need to encapsulate the way they represent their
state, to provide information hiding and to be easy to
maintain.
case class Cat(name: String, age: Int, kittens: Seq[Cat] = Nil)
val philip = Cat(name = “Philip”, age = 9)
val aKitten = Cat(age = 1, name = “Shraga”)val withKittens = philip.copy(kittens = Seq(aKitten))
![Page 11: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/11.jpg)
Determinism via Immutability
Scala encourages everything to be immutable by default:
• Variables (vals)
• Collections
• Value objects (using Case Classes)
• Composition of collaborators
![Page 12: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/12.jpg)
Determinism via ImmutabilityAs a result, we get rid of annoying problems such as
aliasing, concurrent modifications of collections and
objects that have an unknown state
case class Cat(kittens: Seq[Cat] = Nil, dirty: Boolean = true) extends Pet
class Clinic(val shower: PetShower) { def wash(cat: Cat): Cat = { val kittens = cat.kittens.map shower.wash shower.wash(cat.copy(kittens = kittens) }}
![Page 13: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/13.jpg)
Determinism via ImmutabilityTesting Clinic.wash() should prove quite simple
val shower = mock[PetShower]val clinic = new Clinic(shower)
val kitten1 = Cat(dirty = true)val kitten2 = Cat(dirty = true)val mom = Cat(kittens = Seq(kitten1, kitten2)
clinic.wash(mom)
verify(shower).wash(kitten1)verify(shower).wash(kitten2)verify(shower).wash(mom)
![Page 14: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/14.jpg)
Better type safety
• Scala is statically and strongly typed; type inference
keeps the code lean and mean
• Stricter generics (in comparison to Java) provide better
compile-time checks
• Advanced features include structural types and type
aliases
![Page 15: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/15.jpg)
No nulls
Scala urges us to declare a possible return value using the
Option[T] monad; an option can be either Some(value) or
None, and allows us to assume to it can never be null. We
can use collection semantics to consume an Option[T].
def foo: Option[Foo]
foo match { case Some(Foo(bar)) => println(bar) case _ => println(“No foo found”)}
val barOrDefault = foo.map(_.bar).getOrElse(“no foo”)
![Page 16: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/16.jpg)
Less exception throwing using Try[T]
• Try[T] is an abstract monad type with two concrete
implementations, Success[T] and Failure[E]
• Represents the result of an operation which may fail
• Automatically translate an exception-throwing clause
to a Try[T] using the Try() apply method
![Page 17: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/17.jpg)
Less exception throwingclass SomeJavaObject { public Bar tryFoo() throws FooException {…}}
val someJavaObject = new SomeJavaObjectval maybeBar = Try(someJavaObject.tryFoo())
maybeBar match { case Success(bar) => println(bar) case _ => reportFailureAndRetry() }
![Page 18: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/18.jpg)
Better composition using Traits
Scala provides the means for multiple inheritance using
Traits; this can be useful for separating related but
independent pieces of logic into separate units of code,
each with its own test suite. class ComponentFactory extends ImageCreation with TextCreation with VideoCreation with … {
def create(cd: ComponentDefinition) = cd match { case Image(url, dimensions) => makeImage(…) case Text(text, kind) => makeText(…) … }}
![Page 19: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/19.jpg)
Better composition using Traitstrait ImageCreation { def makeImage(url: String, dimensions: Dimensions) = {…} }
class ImageCreationTest extends SpecificationWithJUnit {
val creator = new ImageCreation {… // init code}
“makeImage” should { “create an image” in {…} “fail gracefully” in {…} }}
![Page 20: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/20.jpg)
Cross-cutting concerns using TraitsIn the Java world, AOP can be used to add cross-cutting
concerns to existing code without altering it, but has the
downside of being non-transparent or too implicit. This
makes it hard to figure out which aspects are applied at
runtime, and impossible to test that aspects are indeed
being applied properly.
Let’s look at an example using the canonical use case for
AOP – auditing.
![Page 21: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/21.jpg)
Cross-cutting concerns using Traitstrait Auditing { def auditor: Auditor def audited(f: () => T): T = { auditor.before(…) val ret: T = f() auditor.after(…) ret }}
class Foo(baz: Baz, val auditor: Auditor) extends Auditing { def bar() { audited { baz.doSomething() } }}
![Page 22: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/22.jpg)
Cross-cutting concerns using Traitsclass FooTest extends SpecificationWithJUnit { val auditor = mock[Auditor] val baz = mock[Baz] val foo = new Foo(baz, auditor)
“Foo” should { “call baz” in { foo.bar() got { one(baz).doSomething() one(auditor).audit(…) } } }}
![Page 23: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/23.jpg)
Declarative asynchrony
Scala 2.10 adds a top notch Promise/Future library with
support for composing and pipelining, using callback or
monadic semantics.
A Future[T] will never throw an exception, it will return a
Try[T].
![Page 24: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/24.jpg)
Declarative asynchronytrait CatVaccinator{ def vaccinate(cat: Cat): Future[VaccinatedCat]}
trait PetStore { def deliver(cats: Seq[VaccinatedCat]): Unit}
class Vet(vaccinator: CatVaccinator, petStore: PetStore){ def deliver(cats: Seq[Cat]) { Future.sequence(cats.map vaccinator.vaccinate) .onSuccess { vaccinatedCats: Seq[VaccinatedCat] => petStore.deliver(vaccinatedCats) } .onFailure { exception => reportAndRetry(cats) // some retry logic } }}
![Page 25: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/25.jpg)
Declarative asynchrony// SameThreadExecutor or DeterministicExecutorval executorService: ExecutorService = …val vaccinator = mock[CatVaccinator]val petStore = mock[PetStore]val vet = new Vet(vaccinator, petStore)
“Vet” should { “call deliver” in { vaccinator.vaccinate(cat1) returns Future(vcat1) vaccinator.vaccinate(cat2) returns Future(vcat2)
vet.deliver(Seq(cat1, cat2))
got { one(petStore).deliver(Seq(vcat1, vcat2)) } }}
![Page 26: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/26.jpg)
Le Dessert
![Page 27: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/27.jpg)
Specs2
• Is somewhat of a de-facto standard in the Scala
community
• Github, active community, frequent releases
• Support for RSpec-style and BDD-style test code
• Rich matcher library
• Mediocre documentation
• Built-in Hamcrest integration
![Page 28: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/28.jpg)
ScalaTest
• Somewhat behind Specs2 in terms of adoption
• Supports a myriad of test formats (RSpec, BDD, XUnit,
etc)
• Rich and reliable documentation
• Poor matcher library
• No built-in Hamcrest integration
![Page 29: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/29.jpg)
Plain-old JUnit
• Lots of boilerplate
• Hamcrest doesn’t play well with Scala (for instance, for
matching collections)
• Less magic in comparison with Specs2 and ScalaTest
• No namespace collisions and easier to debug if
something weird happens
![Page 30: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/30.jpg)
Mocking
• ScalaTest supports ScalaMock, Mockito, JMock and
EasyMock
• Specs2 only supports Mockito out of the box but
writing your own sugar using Mixin traits is easy
• ScalaMock is a native Scala mock objects library. Worth
adopting if you don’t already rely heavily on another
library
![Page 31: How Scala promotes TDD](https://reader033.vdocuments.net/reader033/viewer/2022060110/5559e92fd8b42a39498b50ef/html5/thumbnails/31.jpg)
Questions?
http://shaiyallin.wix.com/about