Skip to content


annotation Athena::Spec::TestCase::DataProvider

Tests can be defined with arbitrary arguments. These arguments are provided by one or more DataProvider.

A data provider is a method that returns either a Hash, NamedTuple, Array, or Tuple.

NOTE: The method's return type must be set to one of those types.

If the return type is a Hash or NamedTuple then it is a keyed provider; the key will be used as part of the description for each test.

If the return type is an Array or Tuple it is considered a keyless provider; the index will be used as part of the description for each test.

NOTE: In both cases the value must be a Tuple; the values should be an ordered list of the arguments you want to provide to the test.

One or more DataProvider annotations can be applied to a test with a positional argument of the name of the providing methods. An it block will be defined for each "set" of data.

Data providers can be a very powerful tool when combined with inheritance and abstract defs. A parent test case could define all the testing logic, and child implementations only provide the data.

require "athena-spec"

struct DataProviderTest < ASPEC::TestCase
  def test_squares(value : Int32, expected : Int32) : Nil
    (value ** 2).should eq expected

  # A keyed provider using a Hash.
  def get_values_hash : Hash
      "two"   => {2, 4},
      "three" => {3, 9},

  # A keyed provider using a NamedTuple.
  def get_values_named_tuple : NamedTuple
      four: {4, 16},
      five: {5, 25},

  def test_cubes(value : Int32, expected : Int32) : Nil
    (value ** 3).should eq expected

  # A keyless provider using an Array.
  def get_values_array : Array
      {2, 8},
      {3, 27},

  # A keyless provider using a Tuple.
  def get_values_tuple : Tuple
      {4, 64},
      {5, 125},

ASPEC.run_all # =>
# DataProviderTest
#   squares two
#   squares three
#   squares four
#   squares five
#   cubes 0
#   cubes 1
#   cubes 0
#   cubes 1