-
Notifications
You must be signed in to change notification settings - Fork 148
Writing Tests
Added by Rodrigo B. de Oliveira
In a project like boo there are a lot of components and areas of functionality that need to be individually tested: the classes in the class library, the parser, the error checking code, the code emitter just to cite a few. The integration among these various components needs to be properly and thoroughly tested as well.
We use NUnit as our testing framework. If you don't know NUnit yet please take some time to familiarize yourself with it. You'll be glad you did.
The current tests can always be found here.
Class library test cases are vanilla NUnit test fixture classes written in boo preferably.
The Boo.Lang.List fixture is a great example. <<<--- CAN'T FIND IT
Whenever a bug is found a set of test cases should be written to both prove the bug exists in the first place and make sure it will never pop up again after corrected.
A regression test case is simply a boo script that uses the NUnit API and is placed in the tests/testcases/regression directory. The script should be named after its related jira issue (which is also to say that all bugs should be recorded in jira first).
The following test case was saved as BOO-46-1.boo since it is related to the BOO-46 bug.
import NUnit.Framework
class Foo:
_prefix as object
def constructor(prefix):
_prefix = prefix
def call(c as ICallable):
return c()
def foo():
return "$_prefix - foo"
def run():
return call(foo)
Assert.AreEqual("bar - foo", Foo("bar").run())
![info](http://boo.codehaus.org/s/en_GB/3278/15/_/images/icons/emoticons/information.png) the test case just need to be in the tests/testcases/regression directory and _it will be automatically picked up and run by the build_.
Writing tests for the parser involves three simple steps:
- writing a boo module with the code you want to make sure the parser is able to handle correctly
- adding the roundtrip form of this same code as the module's documentation string
- saving the module in the tests/testcases/parser/roundtrip directory
Example:
"""
import Gtk from 'gtk-sharp'
import FooBar from 'foo-bar'
"""
import Gtk from "gtk-sharp"
import FooBar from 'foo-bar'
![info](http://boo.codehaus.org/s/en_GB/3278/15/_/images/icons/emoticons/information.png) the test case just need to be in the tests/testcases/parsers/roundtrip directory and it will be automatically picked up and run by the build.
A error checking test case is a boo module whose docstring contains all the errors that are expected to be reported by the compiler.
The test case must be saved in the tests/testcases/errors directory with a name in the form <error code>-<sequential number>.boo.
"""
BCE0005-1.boo(9,11): BCE0005: Unknown identifier: local.
"""
def foo():
local = "foo"
bar()
def bar():
print(local)
![info](http://boo.codehaus.org/s/en_GB/3278/15/_/images/icons/emoticons/information.png) the test case just need to be in the tests/testcases/errors directory and it will be automatically picked up and run by the build.
Integration test cases test the whole compilation pipeline all the way from the parser to the emitter to the interaction between the generated code and the class libraries.
A integration test case can either use the NUnit API to assert the expected behavior of the generated program or include its expected output as the module's documentation string.
The test case should be named after the feature it tests and placed in the tests/testcases/integration.
Take for instance one of the integration test cases for the and operator:
"""
True
True
3
evaluated
False
evaluated
evaluated
True
True
0
"""
def fun(value):
print('evaluated')
return value
a = null and true
print(a is null)
b = true and 3
print(b isa int)
print(b)
c = fun(false) and fun(true)
print(c)
d = fun(true) and fun(null)
print(d is null)
e = 0 and false
print(e isa int)
print(e)
![info](http://boo.codehaus.org/s/en_GB/3278/15/_/images/icons/emoticons/information.png) the test case just need to be in the tests/testcases/integration directory and it will be automatically picked up and run by the build.