Description
An expectation library with [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) requirement levels π₯
Spectus alternatives and similar gems
Based on the "Testing" category.
Alternatively, view spectus alternatives based on common mentions on social networks and blogs.
-
vcr
Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests. -
minitest
minitest provides a complete suite of testing facilities supporting TDD, BDD, mocking, and benchmarking. -
timecop
A gem providing "time travel", "time freezing", and "time acceleration" capabilities, making it simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call. -
Spork
A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state. -
Konacha
Test your Rails application's JavaScript with the mocha test framework and chai assertion library -
Fabrication
DISCONTINUED. This project has moved to GitLab! Please check there for the latest updates. -
Knapsack
Knapsack splits tests evenly across parallel CI nodes to run fast CI build and save you time. -
ActiveMocker
Generate mocks from ActiveRecord models for unit tests that run fast because they donβt need to load Rails or a database. -
Wrong
Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail. -
RR
RR is a test double framework that features a rich selection of double techniques and a terse syntax. βΊ -
turbo_tests
Run RSpec tests on multiple cores. Like parallel_tests but with incremental summarized output. Originally extracted from the Discourse and Rubygems source code. -
RSpecTracer
RSpec Tracer is a specs dependency analyzer, flaky tests detector, tests accelerator, and coverage reporter tool for RSpec. It maintains a list of files for each test, enabling itself to skip tests in the subsequent runs if none of the dependent files are changed. It uses Ruby's built-in coverage library to keep track of the coverage for each test.
Scout Monitoring - Performance metrics and, now, Logs Management Monitoring with Scout Monitoring
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Spectus or a related project?
README
Spectus
Expectation library with RFC 2119 requirement levels π₯
Installation
Add this line to your application's Gemfile:
gem "spectus"
And then execute:
bundle
Or install it yourself as:
gem install spectus
Overview
Assuming that an expectation is an assertion that is either true
or false
,
qualifying it with MUST
, SHOULD
and MAY
, we can draw up several scenarios:
Requirement levels | MUST | SHOULD | MAY |
---|---|---|---|
Implemented & Matched | true |
true |
true |
Implemented & Not matched | false |
true |
false |
Implemented & Exception | false |
false |
false |
Not implemented | false |
false |
true |
When an expectation is evaluated by Spectus,
- in case of a passed expectation, a
Spectus::Result::Pass
instance is returned; - in case of a failed expectation, a
Spectus::Result::Fail
exception is raised.
Usage
The Spectus library is basically a module containing an it
instance method that accept a block representing the actual value to be evaluated through an expectation.
The Spectus
module can be included inside a class and used as follows:
require "spectus"
class Spec
include ::Spectus
attr_reader :subject
def initialize(subject)
@subject = subject
end
def test_a
it { subject.upcase }.MUST eql "FOO"
end
def test_b
it { subject.blank? }.MAY be_true
end
def test_c
it { subject.length }.SHOULD equal 42
end
end
t = Spec.new("foo")
t.test_a # => Spectus::Result::Pass(actual: "FOO", error: nil, expected: "FOO", got: true, matcher: :eql, negate: false, level: :MUST)
t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for "foo":String>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY)
t.test_c # => Spectus::Result::Pass(actual: 3, error: nil, expected: 42, got: false, matcher: :equal, negate: false, level: :SHOULD)
t = Spec.new(4)
t.test_a # => raises an exception:
# Traceback (most recent call last):
# 3: from ./bin/console:8:in `<main>'
# 2: from (irb):23
# 1: from (irb):11:in `test_a'
# Spectus::Result::Fail (NoMethodError: undefined method `upcase' for 4:Integer)
t.test_b # => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for 4:Integer>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY)
t.test_c # => raises an exception:
# Traceback (most recent call last):
# 3: from ./bin/console:8:in `<main>'
# 2: from (irb):25
# 1: from (irb):19:in `test_c'
# Spectus::Result::Fail (NoMethodError: undefined method `length' for 4:Integer.)
More examples
To make Spectus available:
require "spectus"
include Spectus
All examples here assume that this has been done.
Absolute Requirement
There's only one bat:
it { "π¦".size }.MUST equal 1
# => Spectus::Result::Pass(actual: 1, error: nil, expected: 1, got: true, matcher: :equal, negate: false, level: :MUST)
Absolute Prohibition
The true from the false:
it { false }.MUST_NOT be_true
# => Spectus::Result::Pass(actual: false, error: nil, expected: nil, got: true, matcher: :be_true, negate: true, level: :MUST)
Recommended
A well-known joke. An addition of 0.1
and 0.2
is deadly precise:
it { 0.1 + 0.2 }.SHOULD equal 0.3
# => Spectus::Result::Pass(actual: 0.30000000000000004, error: nil, expected: 0.3, got: false, matcher: :equal, negate: false, level: :SHOULD)
Not Recommended
The situation should still be under control:
it { BOOM }.SHOULD_NOT raise_exception SystemExit
Traceback (most recent call last):
2: from ./bin/console:8:in `<main>'
1: from (irb):8
Spectus::Result::Fail (NameError: uninitialized constant BOOM.)
Optional
An empty array is blank, right?
it { [].blank? }.MAY be_true
# => Spectus::Result::Pass(actual: nil, error: #<NoMethodError: undefined method `blank?' for []:Array>, expected: nil, got: nil, matcher: :be_true, negate: false, level: :MAY)
Damn, I forgot to load activesupport. π€¦ββοΈ
That said, the test is passing due to the not-implemented-like raised exception: NoMethodError
.
Code Isolation
When executing expectations, side-effects may occur. Because they may or may not be desired, each requirement level has 2 versions:
- if it does not end with
!
, its test is performed without isolation; - if it ends with
!
, its test is performed in isolation.
Example of test without isolation:
greeting = "Hello, world!"
it { greeting.gsub!("world", "Alice") }.MUST eql "Hello, Alice!"
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST)
greeting # => "Hello, Alice!"
Example of test in isolation:
greeting = "Hello, world!"
it { greeting.gsub!("world", "Alice") }.MUST! eql "Hello, Alice!"
# => Spectus::Result::Pass(actual: "Hello, Alice!", error: nil, expected: "Hello, Alice!", got: true, matcher: :eql, negate: false, level: :MUST)
greeting # => "Hello, world!"
Contact
- Home page: https://github.com/fixrb/spectus
- Bugs/issues: https://github.com/fixrb/spectus/issues
Versioning
Spectus follows Semantic Versioning 2.0.
License
The gem is available as open source under the terms of the MIT License.
This project is sponsored by:
*Note that all licence references and agreements mentioned in the Spectus README section above
are relevant to that project's source code only.