# Test/spec 0.1, a BDD interface for Test::Unit

**URL:** <https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499>\
**Category:** Ruby\
**Created:** [September 29, 2006, 6:35pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499 "2006-09-29T18:35:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cneuhaus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/34f0e0/32.png) [@cneuhaus](https://www.ruby-forum.com/u/cneuhaus)\
**Post date:** [September 29, 2006, 6:35pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499/1 "2006-09-29T18:35:13Z")

</div>

Hello,

today I’m releasing test/spec, a library to do BDD with Test::Unit.

== What is test/spec?

test/spec layers an RSpec-inspired interface on top of Test::Unit, so  
you can mix TDD and BDD (Behavior-Driven Development).

test/spec is a clean-room implementation that maps most kinds of  
Test::Unit assertions to a `should’-like syntax.

Consider this Test::Unit test case:

```
class TestFoo < Test::Unit::TestCase
  def test_should_bar
    assert_equal 5, 2 + 3
  end
end

```

In test/spec, it looks like this:

```
require 'test/spec'

context "Foo" do
  specify "should bar" do
    (2 + 3).should.equal 5
  end
end

```

test/spec does not include a mocking/stubbing-framework; use whichever  
you like to.

test/spec has no dependencies outside Ruby 1.8.

== Mixing test/spec and test/unit

test/spec and Test::Unit contexts/test cases can be intermixed freely,  
run in the same test and live in the same files. You can just add them  
to your Rake::TestTask, too. test/spec allows you to leverage your  
full existing Test::Unit infrastructure.

test/spec does not change Test::Unit with the exception of  
monkey-patching Test::Unit::TestSuite to order the test cases before  
running them. (This should not do any harm, but if you know a way  
around it, please tell me.)

You can use assert\_\* freely in specify-blocks; Object#should works in  
Test::Unit test cases, too, but doesn’t increase the assertion count.

== Wrapped assertions

assert\_equal: should.equal, should ==  
assert\_not\_equal: should.not.equal, should.not ==  
assert\_same: should.be  
assert\_not\_same: should.not.be  
assert\_nil: should.be.nil  
assert\_not\_nil: should.not.be.nil

assert\_in\_delta: should.be.close  
assert\_match: should.match, should =~  
assert\_no\_match: should.not.match, should.not =~

assert\_instance\_of: should.be.an.instance\_of  
assert\_kind\_of: should.be.a.kind\_of  
assert\_respond\_to: should.respond\_to

assert\_raise: should.raise  
assert\_nothing\_raised: should.not.raise  
assert\_throws: should.throw  
assert\_nothing\_thrown: should.not.throw  
assert\_block: should.satisfy

== Additional assertions

These assertions are not included in Test::Unit, but have been added  
to test/spec for convenience:

- should.not.satisfy
- a.should. (works like assert a.?)
- should.output, to check what is printed

== SpecDox and RDox

test/spec adds two additional test runners to Test::Unit, based on the  
console runner but with a different output format.

SpecDox, run with --runner=specdox (or -rs) looks  
like RSpec’s output:

```
spec.output
- works for print
- works for puts
- works with readline

```

RDox, run with --runner=rdox (or -rr) can be  
included for RDoc documentation (e.g. see SPECS):

```
== spec.output
* works for print
* works for puts
* works with readline

```

SpecDox and RDox work for Test::Unit too:

```
$ ruby -r test/spec test/testunit/test_testresult.rb -rs

Test::Unit::TC_TestResult
- fault notification
- passed?
- result changed notification

Finished in 0.106647 seconds.

3 specifications (30 requirements), 0 failures

```

== Thanks to

- Eero S. for writing should.output.
- Thomas F. for [script.aculo.us](http://script.aculo.us) BDD testing which convinced me.
- Dave A. for BDD.
- The RSpec team for API inspiration.
- Nathaniel T. for Test::Unit.

== Copying

Copyright (C) 2006 Christian N.  
[http://purl.org/net/chneukirchen](http://purl.org/net/chneukirchen)  
test/spec is licensed under the same terms as Ruby itself.

== Where can I get it?

You can download test/spec 0.1 at

```
    http://chneukirchen.org/releases/testspec-0.1.0.tar.gz

```

Alternatively, you can checkout from the development repository with:

```
       darcs get http://chneukirchen.org/repos/testspec

```

(Patches using “darcs send” are most welcome.)

== Links

Behavior-Driven Development:: [http://behaviour-driven.org/](http://behaviour-driven.org/)  
RSpec:: [http://rspec.rubyforge.org/](http://rspec.rubyforge.org/)  
[script.aculo.us](http://script.aculo.us) testing::  
[http://mir.aculo.us/articles/2006/08/29/bdd-style-javascript-testing](http://mir.aculo.us/articles/2006/08/29/bdd-style-javascript-testing)

Happy hacking and have a nice day,  
Christian N.

9861cf92ec39cce7a5e96504f1fdb6f0 testspec-0.1.0.tar.gz

---

<div class="post-metadata">

**Author:** ![cneuhaus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/34f0e0/32.png) [@cneuhaus](https://www.ruby-forum.com/u/cneuhaus)\
**Post date:** [September 29, 2006, 9:33pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499/2 "2006-09-29T21:33:35Z")

</div>

On 9/29/06, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hello,
> 
> today I’m releasing test/spec, a library to do BDD with Test::Unit.

What a nice coincidence ;=)

will try it soon.

Robert

–  
Deux choses sont infinies : l’univers et la bÃªtise humaine ; en ce qui  
concerne l’univers, je n’en ai pas acquis la certitude absolue.

- Albert Einstein

---

<div class="post-metadata">

**Author:** ![cneuhaus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/34f0e0/32.png) [@cneuhaus](https://www.ruby-forum.com/u/cneuhaus)\
**Post date:** [October 3, 2006, 3:33pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499/3 "2006-10-03T15:33:43Z")

</div>

On 9/29/06, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hello,  
> [snip]  
> You can use assert\_\* freely in specify-blocks; Object#should works in  
> Test::Unit test cases, too, but doesn’t increase the assertion count.  
> [/snip]  
> Happy hacking and have a nice day,  
> Christian N.
> 
> ## 9861cf92ec39cce7a5e96504f1fdb6f0 testspec-0.1.0.tar.gz
> 
> Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)[http://chneukirchen.org](http://chneukirchen.org)

Looks very interesting.

Is there a reason that calls to “should” don’t increase the assertion  
count? Seeing as they are sort of equivalent, and seeing the  
assertion count is a helpful thing, it would be nice. Or maybe there  
should be a general “verification count” that includes calls to  
should?

Here is one hack to do the assertion counts, btw:

> **[404 Error - Page Not Found](https://www.ironmountain.com/data-centers/~wazmo/blog/archives/2006_05.html)**
>
> 404 Error - Page Not Found

- rob

---

<div class="post-metadata">

**Author:** ![cneuhaus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/34f0e0/32.png) [@cneuhaus](https://www.ruby-forum.com/u/cneuhaus)\
**Post date:** [October 3, 2006, 4:01pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499/4 "2006-10-03T16:01:47Z")

</div>

On 10/3/06, Rob S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 9861cf92ec39cce7a5e96504f1fdb6f0 testspec-0.1.0.tar.gz  
> > should?

Interesting. We use an ad-hoc #should for BDD where I work:

(in our Rails test\_helper.rb ):

class Test::Unit::TestCase  
def self.should(behave,&block)  
mname = “test\_should\_#{behave}”  
if block  
define\_method mname, &block  
else  
define\_method mname do  
flunk “#{self.class.name.sub(/Test$/,‘’)} should #{behave}”  
end  
end  
end  
end

This allows us to write tests as such:

should “open the index page” do  
get ‘/’  
assert\_response :success  
end

As the method name is prefixed by ‘test\_’ it does get counted in the  
assertion count. If you’ll notice, too, the method name actually gets  
defined as:

‘test\_should\_open the index page’

which because of the way the method is created and called, is never a  
problem with the parser and makes for easier to read error messages.  
Maybe  
you can use this to help with counting your ‘shoulds’ in this library.

Jason

---

<div class="post-metadata">

**Author:** ![cneuhaus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/34f0e0/32.png) [@cneuhaus](https://www.ruby-forum.com/u/cneuhaus)\
**Post date:** [October 3, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/test-spec-0-1-a-bdd-interface-for-test-unit/70499/5 "2006-10-03T23:04:50Z")

</div>

“Rob S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> > –
> 
> Here is one hack to do the assertion counts, btw:  
> [404 Error - Page Not Found...](http://www.io.com/~wazmo/blog/archives/2006_05.html#000238)

This hack is done by the context/specify blocks, inside them, #shoulds  
are counted. However, I didn’t want to monkeypatch Test::Unit  
directly, so #shoulds in “ordinary” Test::Unit test\_\* method won’t be  
counted.

Since you usually want to use context/specify blocks, this is not a  
problem in practice.
