Current example
You can reference the example object, and access its metadata, using the block
argument provided to: it
, subject
, let
, and the before
, after
, andaround
hooks.
RSpec provides a way to tag tests with metadata that provides additional information about the test. This metadata can be used to filter or organize tests and to provide additional context for the test.
Metadata is specified using the metadata
method in RSpec. It takes a hash of key-value pairs where the key is a symbol that represents the metadata label and the value is the metadata value.
For example, consider the following RSpec test:
rubyCopy codeRSpec.describe MyClass do
describe "#my_method", metadata: { type: :slow } do
it "should take a long time to run" do
# test code
end
end
end
In this example, we have tagged the #my_method
test with metadata indicating that it is a :slow
test. This metadata can be used to filter the test suite to only run :slow
tests or to exclude :slow
tests.
You can also specify multiple metadata labels for a test:
rubyCopy codeRSpec.describe MyClass do
describe "#my_method", metadata: { type: :slow, author: "Alice" } do
it "should take a long time to run" do
# test code
end
end
end
In this example, we have added an additional :author
metadata label to the #my_method
test.
RSpec also provides built-in metadata labels that can be used to tag tests:
:focus
: Indicates that the test should be focused and run exclusively.:skip
: Indicates that the test should be skipped.:example_group
: Specifies a custom label for the test group.
You can filter tests by metadata labels using the --tag
or -t
command line option. For example, to run only the :slow
tests, you can use the following command:
bashCopy coderspec --tag type:slow
In summary, RSpec metadata allows you to tag tests with additional information that can be used to filter or organize tests and provide additional context for the test.
Access the `example` object from within an example
RSpec.describe "example as block arg to it, before, and after" do
before do |example|
expect(example.description).to eq("is the example object")
end
after do |example|
expect(example.description).to eq("is the example object")
end
it "is the example object" do |example|
expect(example.description).to eq("is the example object")
end
end
RSpec.describe "example as block arg to let" do
let(:the_description) do |example|
example.description
end
it "is the example object" do |example|
expect(the_description).to eq("is the example object")
end
end
RSpec.describe "example as block arg to subject" do
subject do |example|
example.description
end
it "is the example object" do |example|
expect(subject).to eq("is the example object")
end
end
RSpec.describe "example as block arg to subject with a name" do
subject(:the_subject) do |example|
example.description
end
it "is the example object" do |example|
expect(the_subject).to eq("is the example object")
expect(subject).to eq("is the example object")
end
end
WhenI run rspec spec/example_spec.rb
Thenthe example should pass
The Described class
If the first argument to the outermost example group is a class, the class is exposed to each example via the described_class()
method.
In RSpec, the describe
method is used to define a test suite, which groups together a set of tests that are related to a specific behavior or functionality of the code being tested. The argument to describe
is typically the class or module being tested, and it can also include a string that describes the behavior being tested.
For example, consider the following RSpec test:
rubyCopy codeRSpec.describe MyClass do
describe "#my_method" do
it "should return the correct value" do
# test code
end
end
end
In this example, we are testing a class called MyClass
, and we have defined a test suite using the describe
method. Within the test suite, we have defined a test for the #my_method
method using the it
method.
The describe
block is used to provide context for the tests that are defined within it. By default, RSpec assumes that the argument to describe
is a class or module being tested, and it uses the class name to provide context for the tests. In this case, RSpec will use the string "MyClass"
as the context for the test suite.
If you provide a string as an additional argument to describe
, RSpec will use that string to provide additional context for the tests. For example:
rubyCopy codeRSpec.describe MyClass, "when initialized" do
describe "#my_method" do
it "should return the correct value" do
# test code
end
end
end
In this example, we have added the string "when initialized"
as additional context for the test suite. This can make the test output more readable and provide additional information about the behavior being tested.
In summary, describe
is used to define a test suite in RSpec, and it typically takes a class or module as its argument. The describe
block is used to provide context for the tests defined within it, and it can include an additional string to provide more specific context for the tests.
Access the described class from the example
RSpec.describe Fixnum do
it "is available as described_class" do
expect(described_class).to eq(Fixnum)
end
end
User-defined metadata
You can attach user-defined metadata to any example group or example. Pass a
hash as the last argument (before the block) to describe
, context
or it
. RSpec supports many configuration options that apply only to certain examples or groups based on the metadata.
Metadata defined on an example group is available (and can be overridden) by any sub-group or from any example in that group or a sub-group.
In addition, you can specify metadata using just symbols. Each symbol passed as an argument to describe
, context
or it
will be a key in the metadata hash, with a corresponding value of true
.
In RSpec, user-defined metadata allows you to tag your tests with custom labels that provide additional information about the tests. This metadata can be used to filter or organize tests and to provide additional context for the test.
To define user-defined metadata, you can use the metadata
method, which takes a hash of key-value pairs where the key is a symbol that represents the metadata label and the value is the metadata value.
For example, consider the following RSpec test:
rubyCopy codeRSpec.describe MyClass do
describe "#my_method", my_custom_metadata: "foo" do
it "should return the correct value" do
# test code
end
end
end
In this example, we have tagged the #my_method
test with user-defined metadata indicating that it has a my_custom_metadata
label with the value of "foo"
. This metadata can be used to filter the test suite to only run tests with the my_custom_metadata
label.
You can also specify multiple user-defined metadata labels for a test:
rubyCopy codeRSpec.describe MyClass do
describe "#my_method", my_custom_metadata: "foo", author: "Alice" do
it "should return the correct value" do
# test code
end
end
end
In this example, we have added an additional author
metadata label to the #my_method
test.
You can filter tests by user-defined metadata labels using the --tag
or -t
command line option, similar to built-in metadata labels. For example, to run only the tests with the my_custom_metadata
label, you can use the following command:
cssCopy coderspec --tag my_custom_metadata
In summary, user-defined metadata allows you to tag your tests with custom labels that provide additional information about the tests. This metadata can be used to filter or organize tests and to provide additional context for the test.
Define group metadata using a hash
RSpec.describe "a group with user-defined metadata", :foo => 17 do
it 'has access to the metadata in the example' do |example|
expect(example.metadata[:foo]).to eq(17)
end
it 'does not have access to metadata defined on sub-groups' do |example|
expect(example.metadata).not_to include(:bar)
end
describe 'a sub-group with user-defined metadata', :bar => 12 do
it 'has access to the sub-group metadata' do |example|
expect(example.metadata[:bar]).to eq(12)
end
it 'also has access to metadata defined on parent groups' do |example|
expect(example.metadata[:foo]).to eq(17)
end
end
end
Define example metadata using a hash
RSpec.describe "a group with no user-defined metadata" do
it 'has an example with metadata', :foo => 17 do |example|
expect(example.metadata[:foo]).to eq(17)
expect(example.metadata).not_to include(:bar)
end
it 'has another example with metadata', :bar => 12, :bazz => 33 do |example|
expect(example.metadata[:bar]).to eq(12)
expect(example.metadata[:bazz]).to eq(33)
expect(example.metadata).not_to include(:foo)
end
end
Override user-defined metadata
RSpec.describe "a group with user-defined metadata", :foo => 'bar' do
it 'can be overridden by an example', :foo => 'bazz' do |example|
expect(example.metadata[:foo]).to eq('bazz')
end
describe "a sub-group with an override", :foo => 'goo' do
it 'can be overridden by a sub-group' do |example|
expect(example.metadata[:foo]).to eq('goo')
end
end
end
Less verbose metadata
RSpec.describe "a group with simple metadata", :fast, :simple, :bug => 73 do
it 'has :fast => true metadata' do |example|
expect(example.metadata[:fast]).to eq(true)
end
it 'has :simple => true metadata' do |example|
expect(example.metadata[:simple]).to eq(true)
end
it 'can still use a hash for metadata' do |example|
expect(example.metadata[:bug]).to eq(73)
end
it 'can define simple metadata on an example', :special do |example|
expect(example.metadata[:special]).to eq(true)
end
end