WarpScript is an experimental measurement API based on the Free Monad, allowing users to represent a measurement plan
as a monadic pipeline of exec and measure operations. exec is a simple wrapper around a call-by-name parameter,
useful for side effects or setup test data. measure is for measuring a call-by-name parameter.
importcom.workday.warp.junit.WarpJUnitSpecimportcom.workday.warp.monadic.WarpAlgebra._importcom.workday.warp.logger.WarpLoggingimportorg.junit.jupiter.api.TestclassWarpScriptSpecextendsWarpJUnitSpecwithWarpLogging {
@Testdef measureSpec():Unit = {
val demo:WarpScript[Int] =for {
// exec() is useful for setup test data
a <- exec(1 + 1)
// measure() accepts a name and an expression, and measures that expression
b <- measure("com.workday.warp.MeasureSpec.a", { logger.info("computing a"); a + 1 })
c <- measure("com.workday.warp.MeasureSpec.b", a + b)
} yield c
// run the script
interpretImpure(demo) should be (5)
}
}
Macros
In our own testing, we found it cumbersome to repeat variables and TestIds within a WarpScript, so we provide a macro that
will rewrite a WarpScript and automatically derive a TestId for each measured section within the script. For example,
a script such as this:
1
2
3
4
5
6
for {
a <- exec(1 + 1)
b <- measure(a + 1)
c <- measure(b + 1)
d <- measure(c + 1)
} yield d
will be macro-expanded into this (assuming it is defined within a class called com.workday.warp.MacroExampleSpec):
1
2
3
4
5
6
for {
a <- exec(1 + 1)
b <- measure("com.workday.warp.MacroExampleSpec.b", a + 1)
c <- measure("com.workday.warp.MacroExampleSpec.c", b + 1)
d <- measure("com.workday.warp.MacroExampleSpec.d", c + 1)
} yield d
Note the match between the bound variable and the TestId on each line. We found it difficult to implement a macro that appropriately
targets minor AST differences across different scala versions, so we publish macros as a separate artifact com.workday.warp:warp-core-macros_2.13 that only targets
scala 2.13.