testing in scala by adform research

35
Testing in Scala

Upload: vasil-remeniuk

Post on 15-Jul-2015

91 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Testing in Scala by Adform research

Testing in Scala

Page 2: Testing in Scala by Adform research

Concepts: Types of Tests

Technology

Business

GlobalLocal

Unit IntegrationFunctional

Acceptance

Page 3: Testing in Scala by Adform research

Unit Tests

• Check very specific functionality of your code

• Assumes everything else works (mocking)

• Test one specific/technical thing

• e.g. test your Hadoop job locally, given money in DKK, currency conversion to EUR is called once

Page 4: Testing in Scala by Adform research

Integration Tests

• Check that all components work together

• Includes real components, databases, files, etc.

• Test the connectivity of components

• e.g. run a job on a development Hadoop cluster, given sample data expected output is written

Page 5: Testing in Scala by Adform research

Functional Tests

• Test your product against the functionality you developed

• Use real components, real data

• E.g. run job on a live cluster, given a days worth of data the output is correct (as expected according to specification)

Page 6: Testing in Scala by Adform research

Acceptance Tests

• Final tests performed by your client before “accepting the product”

• Real components, real data, output is correct, performance is acceptable, client is happy

Page 7: Testing in Scala by Adform research

Concepts: Testing Styles

• TDD: Test Driven Development

• BDD: Behavior Driven Development

Page 8: Testing in Scala by Adform research

Test Driven Development

• Write an interface (trait) for the behavior

• Write an empty implementation

• Write your unit tests

• Make the code compile and tests fail

• Correct the implementation

• Make the tests pass !

Page 9: Testing in Scala by Adform research

Behavior Driven Development

• Same idea, just write more functional tests (define behavior)

Page 10: Testing in Scala by Adform research

Testing in Scala

• For every class in src/main/scala write a test class in src/test/scala

• Test classes ~ Test suites

• Methods ~ Tests

• Run the suit and see the output

Page 11: Testing in Scala by Adform research

Testing Libraries/Frameworks

• Java: JUnit, TestNG (can be used with scala)

• Scala: ScalaTest, Specs2

• Mocking: ScalaMock, EasyMock, JMock, Mockito

• Property Testing: ScalaCheck

• UI Testing: Selenium

Page 12: Testing in Scala by Adform research

• Very similar to Specs2, maybe more flexible, mainly choice of taste

• Integrates with sbt, IntelliJ

• Integrates with Mockito, ScalaCheck

libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.1" % "test"

Page 13: Testing in Scala by Adform research

Using ScalaTest

import org.scalatest.FunSuite

class SetSuite extends FunSuite {

test("An empty Set should have size 0") { assert(Set.empty.size == 0)

}

test("Invoking head on an empty Set should produce NoSuchElementException") { intercept[NoSuchElementException] {

Set.empty.head }

}

}

Page 14: Testing in Scala by Adform research
Page 15: Testing in Scala by Adform research
Page 16: Testing in Scala by Adform research
Page 17: Testing in Scala by Adform research

Style Traits

• ScalaTest allows you to mix in a testing style you like:• FunSuite• FlatSpec• FunSpec• WordSpec• PropSpec• etc.

• http://www.scalatest.org/user_guide/selecting_a_style

Page 18: Testing in Scala by Adform research

FunSuite

Page 19: Testing in Scala by Adform research

FlatSpec

Page 20: Testing in Scala by Adform research

WordSpec

Page 21: Testing in Scala by Adform research

FeatureSpec

Page 22: Testing in Scala by Adform research

Testing Styles

• ScalaTest recommends having an abstract class with the specs and other traits you like

package com.mycompany.myproject

import org.scalatest._

abstract class UnitSpec extends FlatSpec with Matchers with OptionValues with Inside with Inspectors

package com.mycompany.myproject

import org.scalatest._

class MySpec extends UnitSpec {

// Your tests here

}

Page 23: Testing in Scala by Adform research

Fixtures

• Your tests may need some setting up and tearing down

• ScalaTest has many ways of doing this

• http://www.scalatest.org/user_guide/sharing_fixtures

Page 24: Testing in Scala by Adform research
Page 25: Testing in Scala by Adform research

Matchers

• ScalaTest has lots of syntactic sugar to express your desires

result should equal (3)

result should have size 10

string should fullyMatch regex """(-)?(\d+)(\.\d*)?"""

result1 should not be an [Orangutan]

sevenDotOh should equal (6.9 +- 0.2)

"howdy" should contain oneOf ('a', 'b', 'c', 'd')

(Array("Doe", "Ray", "Me") should contain oneOf ("X", "RAY", "BEAM")) (after being lowerCased)

List(0, 1, 2, 2, 99, 3, 3, 3, 5) should contain inOrder (1, 2, 3)

map should (contain key ("two") and not contain value (7))

This is Scala Code !!

Page 26: Testing in Scala by Adform research

Mocking

• You should always code against interfaces (traits)

• If you do, testing is easier, since you can mock your dependencies!

val m = mock[Turtle]

m.expects.forward(10.0) twice

m1 returns 42

m2 expects ("this", "that") returning "the other"

Page 27: Testing in Scala by Adform research

Property Based Testing

• New and exciting way of testing your code!

• Instead of examples, you specify properties (higher order testing!)

• E.g. when you concatenate two lists, new lengths is sum of lengths

• ScalaCheck then generates random inputs and runs many tests

• This can catch MANY corner cases you never expect!

Page 28: Testing in Scala by Adform research

ScalaCheck

import org.scalacheck.Gen

val propConcatLists = forAll { (l1: List[Int], l2: List[Int]) =>

l1.size + l2.size == (l1 ::: l2).size

}

+ OK, passed 100 tests.

val propSqrt = forAll { (n: Int) => scala.math.sqrt(n*n) == n }

! Falsified after 1 passed tests:

> -1

Page 29: Testing in Scala by Adform research

ScalaCheck: Generators

val genLeaf = value(Leaf)

val genNode = for {

v <- arbitrary[Int]

left <- genTree

right <- genTree

} yield Node(left, right, v)

def genTree: Gen[Tree] = oneOf(genLeaf, genNode)

Option[Tree] = Some(Node(Leaf,Node(Node(Node(Node(Node(Node(Leaf,Leaf,-71),Node(Leaf,Leaf,-49),17),Leaf,-20),Leaf,-7),Node(Node(Leaf,Leaf,26),Leaf,-3),49),Leaf,84),-29))

Page 30: Testing in Scala by Adform research

is

AWESOME !!

Page 31: Testing in Scala by Adform research

Scoverage

• Produces test coverage reports

• Measures how many statements are tested

• Only works with Scala 2.11

Page 32: Testing in Scala by Adform research
Page 33: Testing in Scala by Adform research

Testing Scalding Jobs

HOMEWORK: use ScalaTest instead of Specs2

Page 34: Testing in Scala by Adform research

DEMO TIMESlava takes the stage

Page 35: Testing in Scala by Adform research