0

In our system we have really big objects that are generated for scalacheck. All properties are of the same data structure, and therefore it seems unnecessary to generate cases for each property. They should be reused. I'm aware of something like this import org.scalacheck.Prop.{forAll, BooleanOperators}

val complexProp = forAll { (m: Int, n: Int) =>
  val res = myMagicFunction(n, m)
  (res >= m)    :| "result > #1" &&
  (res >= n)    :| "result > #2" &&
  (res < m + n) :| "result not sum"
}

but that's too messy, I'd like to write individual tests, but that each reuse the same data, is that even possible?

caente
  • 141
  • 7

1 Answers1

0

I ended up extending Prop, in other words making my own version of Properties, where the input was the same for all properties, something like

class MyProperties(implicit dataArb:Arbitrary[InputData]) extends Prop{

     private val tests = new scala.collection.mutable.ListBuffer[( String, Response => Boolean )]

    def apply( p: Gen.Parameters ) = customProperties( p )

    def property( name: String )( f: Response => Boolean ): Unit = tests += name -> f

    def customProperties: Prop = {
      Prop.forAll {
        ( data: InputData ) =>
          tests.foldLeft( Prop.passed ) {
            case ( r, ( name, p ) ) =>
              val response = methodThatUsesInputData( data ).exists( p )
              val label = if ( response ) name
              else
                s"""
                 |$name:
                 |${generateAnScalaTestFromInputData( data )}
               """.stripMargin
              r && ( label |: response )
          }
      }
    }
}

Basically you can write your properties in a similar fashion to ScalaTest, i.e.

object PropertiesOfMine extends MyProperties {
   property("some property"){
      response => some-boolean-from-response
   }
}

methodThatUsesInputData is the actual logic we want to test generateAnScalaTestFromInputData is an utility we have that generates code for an ScalaTest given an InputData object

caente
  • 141
  • 7