Core specification classes and traits provide the foundation for creating immutable (functional-style) test specifications in specs2. These are the main entry points for acceptance-style testing where the specification structure is defined declaratively.
Main specification class for immutable specifications.
abstract class Specification extends SpecificationLikeUsage Example:
class MySpec extends Specification { def is = s2"""
This is my specification
example 1 $e1
example 2 $e2
"""
def e1 = 1 + 1 must beEqualTo(2)
def e2 = "test" must have size(4)
}Core trait that provides all specification functionality.
trait SpecificationLike extends ImmutableSpecificationStructure
with SpecificationCreation
with SpecificationFeaturesThis trait combines:
ImmutableSpecificationStructure: Basic structure definitionSpecificationCreation: Methods for creating specification fragmentsSpecificationFeatures: Advanced features like tagging, grouping, execution controlLightweight specification class with minimal imports.
abstract class Spec extends SpecLikeUsage Example:
class SimpleSpec extends Spec { def is = s2"""
Simple specification
basic test $e1
"""
def e1 = true must beTrue
}Lightweight trait with essential functionality only.
trait SpecLike extends ImmutableSpecificationStructure
with S2StringContext1
with AcceptanceDsl1
with MustMatchers1
with ArgumentsCreation
with ArgumentsShortcuts
with FormattingFragments
with StandardResults
with StandardMatchResultsIncludes minimal imports:
S2StringContext1: Basic string interpolation for s2"" syntaxAcceptanceDsl1: Essential DSL methods for examples and structureMustMatchers1: Core matchers onlyArgumentsCreation: Methods for creating Arguments configurationsArgumentsShortcuts: Shortcut methods for common argument patternsFormattingFragments: Support for formatting and layout fragmentsStandardResults: Standard result types (Success, Failure, Error, etc.)StandardMatchResults: Standard matcher result handlingBase trait defining the structure of all specifications.
trait SpecificationStructure {
def is: SpecificationStructure
def content: Fragments
def header: String
def arguments: Arguments
}Structure trait for functional-style specifications.
trait ImmutableSpecificationStructure extends SpecificationStructure {
def map(f: Fragment => Fragment): ImmutableSpecificationStructure
def flatMap(f: Fragment => Fragments): ImmutableSpecificationStructure
}Specifications are built from fragments - the basic building blocks.
sealed trait Fragment
case class Text(text: String) extends Fragment
case class Example(description: String, body: Execution) extends Fragment
case class Step(action: () => Any) extends Fragment
case class Action(action: () => Any) extends Fragment
case class Tab(n: Int = 1) extends Fragment
case class Backtab(n: Int = 1) extends Fragment
case class Br() extends Fragment
case class End() extends FragmentCollection and manipulation of fragments.
case class Fragments(fragments: Vector[Fragment]) {
def append(other: Fragments): Fragments
def prepend(other: Fragments): Fragments
def insert(index: Int, fragment: Fragment): Fragments
def map(f: Fragment => Fragment): Fragments
def filter(p: Fragment => Boolean): Fragments
}Methods for creating specification content.
trait SpecificationCreation {
def title(t: String): Fragment
def text(t: String): Fragment
def example(desc: String)(body: => Any): Fragment
def step(action: => Any): Fragment
def action(action: => Any): Fragment
}Factory methods for creating fragments.
object DefaultFragmentFactory {
def text(t: String): Fragment
def example(desc: String, body: Execution): Fragment
def step(action: => Any): Fragment
def action(action: => Any): Fragment
def break: Fragment
def tab(n: Int = 1): Fragment
def backtab(n: Int = 1): Fragment
def end: Fragment
}Advanced specification capabilities.
trait SpecificationFeatures extends Groups
with Debug
with Level
with SpecificationInclusionCreates Arguments configurations for controlling specification execution.
trait ArgumentsCreation {
def args(
plan: Boolean = false,
skipAll: Boolean = false,
stopOnFail: Boolean = false,
sequential: Boolean = false,
isolated: Boolean = false,
threadsNb: Int = Runtime.getRuntime.availableProcessors,
specs2ThreadsNb: Int = Runtime.getRuntime.availableProcessors
): Arguments
}Convenient shortcut methods for common argument patterns.
trait ArgumentsShortcuts {
def sequential: Arguments
def isolated: Arguments
def skipAll: Arguments
def stopOnFail: Arguments
def plan: Arguments
}Support for formatting and layout fragments in specifications.
trait FormattingFragments {
def tab(n: Int = 1): Fragment
def backtab(n: Int = 1): Fragment
def br: Fragment
def p: Fragment
def end: Fragment
}Standard result types used throughout specs2.
trait StandardResults {
def success: Success
def success(message: String): Success
def failure: Failure
def failure(message: String): Failure
def pending: Pending
def pending(message: String): Pending
def skipped: Skipped
def skipped(message: String): Skipped
}Standard matcher result handling and utilities.
trait StandardMatchResults {
def createMatchResult[T](
expectable: Expectable[T],
message: String,
negatedMessage: String,
isSuccess: Boolean
): MatchResult[T]
}Grouping examples for organization and selective execution.
trait Groups {
def group(name: String): Fragment
def section(name: String): Fragment
}Execution context for examples.
trait Context {
def apply[T: AsResult](a: => T): Result
}
trait BeforeEach extends Context {
def before: Any
}
trait AfterEach extends Context {
def after: Any
}
trait AroundEach extends Context {
def around[T: AsResult](t: => T): Result
}Using s2 string interpolation for embedded examples:
class UserSpec extends Specification { def is = s2"""
User management system
should create valid users $createUser
should validate email format $validateEmail
should handle duplicates $handleDups
"""
def createUser = {
val user = User("john", "john@example.com")
user.name must beEqualTo("john")
}
def validateEmail = {
User("jane", "invalid-email") must throwA[ValidationException]
}
def handleDups = {
val users = List(User("bob", "bob@test.com"), User("bob", "bob@test.com"))
users.distinct must have size(1)
}
}Control execution mode:
class SequentialSpec extends Specification { def is = sequential ^ s2"""
These examples run one after another
step 1 $step1
step 2 $step2
step 3 $step3
"""
// examples implementation...
}Configure specification behavior:
class ConfiguredSpec extends Specification { def is =
args(sequential = true, stopOnFail = true) ^ s2"""
Configured specification behavior
example 1 $e1
example 2 $e2
"""
// examples implementation...
}Modular specification composition:
class MainSpec extends Specification { def is = s2"""
Main specification
${"UserSpec"}
${"OrderSpec"}
${"PaymentSpec"}
"""
}