ISpec

From IokeWiki
Revision as of 02:38, 26 January 2009 by Cv (talk | contribs)
Jump to: navigation, search

ISpec is a minimal port of the Ruby RSpec framework for behavior-driven development. It supports the bare minimum to allow testing of Ioke itself. The current Ioke test suite is completely written in ISpec, and it seems to be a capable environment.

The ispec command line tool takes one argument -- "-f" to specify which format to print in. The default is "p" for progress, which only shows one dot for each test run. The "s" alternative shows the longer spec format. To run all tests in a directory with spec format:

ispec -fs test_dir

This command will find all files ending in _spec.ik and run the specs defined in them. If a single file is specified, only the tests in that file will run. If more than one directory or file is specified on the command line, all the tests will be run together. Provided the spec files all use the ispec module, the files can be run directly with the ioke-command too.

A full test file utilizing most of the parts of ISpec looks like this:

use("ispec")

describe(Foo,
  it("should have the correct kind",
    Foo should have kind("Foo")
    Foo kind should == "Foo"
    Foo kind should match(#/Fo+/)
  )

  it("should be possible to mimic",
    m = Foo mimic
    m should have kind("Foo")
    m should not be same(Foo)
    m should mimic(Foo)
  )

  describe("aMethod",
    it("should not return nil",
      Foo aMethod should not be nil
    )

    it("should return a number that can be multiplied",
      (Foo aMethod * 2) should == 12
    )
  )

  describe("aBadMethod",
    it("should signal a condition",
      fn(Foo aBadMethod) should signal(Condition Error BadBadBed)
    )
  )
)

This code first makes sure to use ISpec, then describes Foo. The describe method takes either kinds or texts describing what's under test. This can be nested arbitrarily deep. A test is defined with the "it" method, which takes a text describing the test first, and the implementation of the test as the second argument. If the second argument is left out, the test is considered pending.

Assertions are done using the "should" method. This returns an expectation that can check several different things against the original receiver. Using == is the simplest expectation and checks that a value equals another. By adding the not method call inbetween, the expectation is inversed. There are some predefined expectations. Except for ==, these are mimic, match and signal. The signal expectation makes sure that a condition is signalled in the code. The match expectation will check a text value against a regular expression. The mimic expectation checks whether an object mimics another.

The words "be" and "have" are ignored in the expectations. They are so called fluff words - that are only there to make it more readable.

If an expectation receives a message it doesn't know about, it uses pass to check a dynamic property. For example, something like "foo should be same(x)" will end up calling "same?" with x as an argument. The same thing happens in the above code to check for kind. There exists no kind expectation. Instead the kind checking will go check for "kind?".