Bruker:Jeblad/Module:BDD/dok
- Note that the module is not ready for production, it is still under active development!
The purpose of this module is to support behavior-driven development (BDD), a software development process that emerged from test-driven development (TDD), in on-going development of Lua-based modules. It uses the assumption of a test module on a separate page, possibly a subpage, and presentation on the talk page.
The module mimics some ideas from RSpec [1], Jasmine [2], and Busted [3], all of which implements BDD.
The module is not built for great speed, it uses closures to build a number of small objects, that is methods returns a value that is wrapped in a closure. This makes a fairly efficient implementation for simple access, but it is not very efficient for caching larger structures. The module also avoids as much caching as possible, as this can poison the testing.
Usage
If you have a module like «Module:HelloWorld»
local p = {}
function p.helloWorld()
return "Hi there!"
end
return p
On the test page a call will then be something like the following
require 'Module:BDD'()
p = require 'Module:HelloWorld'()
describe('Hello world', function()
context('On all pages', function()
it('says hello', function()
expect('p.helloWorld()', p.helloWorld()).toBe("Hi there!");
end);
end);
end);
return result('Module:HelloWorld')
Further work
At present formatting does not work properly. It is expected to be fixed. ;)
Setup/teardown
There will be a solution whereby setup and teardown is chained. That means that the tests are somewhat isolated from each other at each test level, that is each time we define a describe, context, or it, the environment will be recreated. State can still leak between expectations though.
It is assumed that there will be no global setup and teardown as there is no resource allocation available from pages in Scribunto.
Pcall
All calls to provided functions should be protected in pcalls so a single exception does not make the whole test set to fail. A failed function should be marked as such in the report.
Actual function is xpcall, and it will always add a stack trace on our own stack. The entry might be without a message.
This is partially implemented, propper formatting remains unsolved.
Spy on public calls
Note that spying on public calls made before the module is available to the testing regime will not be possible.
- Carp
- Adds a message to stack without exiting the test, printing the callers name and its arguments.
- Cluck
- Like Carp, but also prints a stack trace starting one level up.
- Croak/Confess
- Like Carp, but also stops the running test (the user provided anonymous function). Because it throws an exception it will always trigger a stack trace.
Call would be like [carp|cluck|croak|confess](message, table, method)
.
Set up of spies are implemented, but they should be removed during teardown. Such cleanup must check if the struct is still available. This may happen if structs are created inside the test environment.
Stub public methods
It should be possible to stub public methods from the test page. This will not include private methods. (Is this something that should be part of a BDD module?)
Module return
At present an explicit return must be done. It seems to be possible to do an implicit return. This makes a slightly less error prone setup procedure.
Several options exist in literature, but it might be some limitations to what is actually allowed in Scribunto.
Test Anything Protocol
At some point the Test Anything Protocol (TAP) should be supported. The simplest solution is to use yet another page for that response, but it is also possible to test on the page name. This can be different if we transclude the talk page into some other page, or even constructs the page on the fly through the api. If the transcluded page name is "API" then we switch to a TAP response. This makes it possible to support several formats from a single page.