module Spec

Overview

Crystal's built-in testing library. It provides a structure for writing executable examples of how your code should behave. A domain specific language allows you to write them in a way similar to natural language.

The Crystal compiler has a spec command with tools to constrain which examples get run and tailor the output.

A basic spec looks something like this:

require "spec"

describe Array do
  describe "#size" do
    it "correctly reports the number of elements in the Array" do
      [1, 2, 3].size.should eq 3
    end
  end

  describe "#empty?" do
    it "is empty when no elements are in the array" do
      ([] of Int32).empty?.should be_true
    end

    it "is not empty if there are elements in the array" do
      [1].empty?.should be_false
    end
  end

  # lots more specs

end

Test files are structured by use of the describe or context methods. Typically a top level describe defines the outer unit (such as a class) that is to be tested by the spec. Further describe calls can be nested within the outer unit to specify smaller units under test (such as individual methods). describe can also be used to set up a certain context - think empty Array versus Array with elements. The context method behaves just like the describe method and may be used instead, to emphasize context to the reader.

Within a describe block, concrete test cases are defined with it . A descriptive string is supplied to it describing what the test case tests specifically.

Specs then use the should method to verify that the expected value is returned. See the example above for details.

By convention, specs live in the spec directory of a project. You can compile and run the specs of a project by running crystal spec.

# Run  all specs in files matching spec/**/*_spec.cr
crystal spec

# Run all specs in files matching spec/my/test/**/*_spec.cr
crystal spec spec/my/test/

# Run all specs in spec/my/test/file_spec.cr
crystal spec spec/my/test/file_spec.cr

# Run the spec or group defined in line 14 of spec/my/test/file_spec.cr
crystal spec spec/my/test/file_spec.cr:14

Focusing on a group of specs

A describe, context or it can be marked with focus: true, like this:

it "adds", focus: true do
  (2 + 2).should_not eq(5)
end

If any such thing is marked with focus: true then only those examples will run.

Defined in:

spec/dsl.cr
spec/item.cr
spec/context.cr
spec/example.cr
spec/expectations.cr
spec/filters.cr
spec/formatter.cr
spec/junit_formatter.cr
spec/source.cr
spec.cr

Class Method Summary

Class Method Detail

def self.add_formatter(formatter) #

[View source]
def self.add_split_filter(filter) #

[View source]
def self.after_each(&block) #

Instructs the spec runner to execute the given block after each spec, regardless of where this method is invoked.

If multiple blocks are registered they run in the reversed order that they are given.

For example:

Spec.after_each { puts 1 }
Spec.after_each { puts 2 }

will print, just after each spec, 2 and then 1.


[View source]
def self.after_suite(&block) #

Instructs the spec runner to execute the given block after the entire spec suite.

If multiple blocks are registered they run in the reversed order that they are given.

For example:

Spec.after_suite { puts 1 }
Spec.after_suite { puts 2 }

will print, just after the spec suite ends, 2 and then 1.


[View source]
def self.before_each(&block) #

Instructs the spec runner to execute the given block before each spec, regardless of where this method is invoked.

If multiple blocks are registered they run in the order that they are given.

For example:

Spec.before_each { puts 1 }
Spec.before_each { puts 2 }

will print, just before each spec, 1 and then 2.


[View source]
def self.before_suite(&block) #

Instructs the spec runner to execute the given block before the entire spec suite.

If multiple blocks are registered they run in the order that they are given.

For example:

Spec.before_suite { puts 1 }
Spec.before_suite { puts 2 }

will print, just before the spec suite starts, 1 and then 2.


[View source]
def self.override_default_formatter(formatter) #

[View source]
def self.root_context #

[View source]