shared-examples

Shared Examples

Shared examples let you package up a set of it blocks under a name and reuse them across any number of describe or context groups. They're useful when several types or implementations should satisfy the same behavior contract (a "counter," a "comparable," a "queue") without copy-pasting the its into every spec.

shared-examples, include-examples, and it-behaves-like are exported from BDD::Behave.

Shared examples are a complement to Shared Contexts: a shared context contributes setup (lets and hooks), while shared examples contribute the assertions themselves.

Defining shared examples

shared-examples takes a name and a block. The block typically contains one or more it blocks, but it can call any DSL helper that's legal inside a group:

use BDD::Behave;

shared-examples 'a counter', {
  it 'starts at zero', {
    expect(:start).to.be(0);
  }

  it 'has an increment step', {
    expect(:step).to.be(1);
  }
};

The block does nothing on its own: it's stored under the given name and only runs when a group asks for it.

it-behaves-like: wrap shared examples in a nested group

The most common form is it-behaves-like 'name'. It creates a nested behaves like 'name' group inside the current describe and runs the shared block there. The wrapper group keeps the shared examples visually grouped in the runner's output:

describe 'an integer counter', {
  let(:start, { 0 });
  let(:step,  { 1 });

  it-behaves-like 'a counter';
}

Output:

⮑  'an integer counter'
  ⮑  'behaves like 'a counter''
    ⮑  'starts at zero'
      ⮑  SUCCESS
    ⮑  'has an increment step'
      ⮑  SUCCESS

The shared examples see let definitions, hooks, and shared-context contributions from every ancestor group (including the describe they're invoked from) exactly the same way ordinary nested examples do.

include-examples: merge shared examples into the current group

include-examples 'name' is the lower-ceremony form: the shared block runs directly in the current group, so its its become siblings of any locally-defined its instead of being wrapped in a new group.

describe 'an integer counter', {
  let(:start, { 0 });
  let(:step,  { 1 });

  include-examples 'a counter';

  it 'is initialized', {
    expect(:start).to.be(0);
  }
}

Use it-behaves-like when you want the contract to show up as its own labeled subgroup in the output. Use include-examples when the shared its are conceptually part of the surrounding group.

Parameterizing shared examples

The shared block can take positional parameters. Pass them after the name:

shared-examples 'a sized collection', -> $expected {
  it "reports its size as $expected", {
    expect($*LET-RUNTIME.value('size')).to.be($expected);
  }
};

describe 'a three-element list', {
  let(:size, { 3 });

  it-behaves-like 'a sized collection', 3;
}

Both it-behaves-like and include-examples forward extra arguments to the shared block.

Reusing shared examples across multiple groups

Shared examples are typically defined once at the top of a spec file (or in a shared helper file) and referenced from many describes. Each call to it-behaves-like or include-examples is independent, so you can mix and match per-group setup:

shared-examples 'a counter', {
  it 'starts at zero', { expect(:start).to.be(0); }
  it 'has an increment step', { expect(:step).to.be(1); }
};

describe 'an integer counter', {
  let(:start, { 0 });
  let(:step,  { 1 });
  it-behaves-like 'a counter';
}

describe 'a fractional counter', {
  let(:start, { 0 });
  let(:step,  { 1 });
  it-behaves-like 'a counter';
  it-behaves-like 'a counter';   # multiple invocations are fine
}

Errors

  • Calling it-behaves-like or include-examples with an unregistered name dies with Unknown shared examples: '<name>'.

  • Calling it-behaves-like or include-examples outside a describe or context block dies: shared examples can only be instantiated inside a group.

BDD::Behave v0.9.4

Behavior driven development framework

Authors

  • Greg Donald

License

Artistic-2.0

Dependencies

Provides

  • BDD::Behave
  • BDD::Behave::Benchmark
  • BDD::Behave::Benchmark::Baseline
  • BDD::Behave::Benchmark::Format
  • BDD::Behave::Bisect
  • BDD::Behave::Colors
  • BDD::Behave::Configuration
  • BDD::Behave::Coverage
  • BDD::Behave::DSL
  • BDD::Behave::Diff
  • BDD::Behave::DocExtractor
  • BDD::Behave::DryRun
  • BDD::Behave::Expectation
  • BDD::Behave::Failure
  • BDD::Behave::FailureStore
  • BDD::Behave::Failures
  • BDD::Behave::Files
  • BDD::Behave::Formatter
  • BDD::Behave::Formatter::Documentation
  • BDD::Behave::Formatter::HTML
  • BDD::Behave::Formatter::JSON
  • BDD::Behave::Formatter::JUnit
  • BDD::Behave::Formatter::JsonEvents
  • BDD::Behave::Formatter::Progress
  • BDD::Behave::Formatter::Registry
  • BDD::Behave::Formatter::TAP
  • BDD::Behave::Formatter::Tree
  • BDD::Behave::LetRuntime
  • BDD::Behave::Matcher
  • BDD::Behave::Matcher::Async
  • BDD::Behave::Matcher::Boolean
  • BDD::Behave::Matcher::Change
  • BDD::Behave::Matcher::Collection
  • BDD::Behave::Matcher::Core
  • BDD::Behave::Matcher::Custom
  • BDD::Behave::Matcher::Exception
  • BDD::Behave::Matcher::Numeric
  • BDD::Behave::Matcher::String
  • BDD::Behave::Matcher::Type
  • BDD::Behave::Mock::Allow
  • BDD::Behave::Mock::ArgMatcher
  • BDD::Behave::Mock::Double
  • BDD::Behave::Mock::HaveReceived
  • BDD::Behave::Mock::Spy
  • BDD::Behave::Mock::Stub
  • BDD::Behave::Parallel
  • BDD::Behave::Parallel::Distribution
  • BDD::Behave::Parallel::EventStream
  • BDD::Behave::Parallel::Manifest
  • BDD::Behave::Parallel::Queue
  • BDD::Behave::Parallel::WorkerPool
  • BDD::Behave::Runner
  • BDD::Behave::SharedContexts
  • BDD::Behave::SharedExamples
  • BDD::Behave::Slang
  • BDD::Behave::SpecLoader
  • BDD::Behave::SpecRegistry
  • BDD::Behave::SpecTree
  • BDD::Behave::SpecTree::Core
  • BDD::Behave::SpecTree::Example
  • BDD::Behave::SpecTree::ExampleGroup
  • BDD::Behave::SpecTree::Suite
  • BDD::Behave::Time
  • BDD::Behave::TypeName
  • BDD::Behave::Version
  • BDD::Behave::Watch
  • BDD::Behave::Watch::Session
  • BDD::Behave::Watch::SmartSelector
  • BDD::Behave::Watch::UI
  • BDD::Behave::Watch::Watcher
  • BDD::Behave::Worker

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.