siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
222 lines (145 loc) • 7.59 kB
Markdown
Structuring the test suite
====================
Siesta supports writing tests with BDD syntax. We recommend to look at BDD as just a way of structuring
your tests and not put extra ceremony in it. While it is possible to write your tests in the way,
that test suite will output a readable documentation for your system in the console, it is not the main goal.
Main goal is to write coverage for the features your application have, to sort of "freeze" the spec in
certain state. That means we'll need to write and maintain a lot of tests, so one need to structure them
somehow. We found the following structuring scheme, to suite practical needs very well.
## The tree of sub-tests
A single test file can be organized as several nested sub-tests (in BDD terminology these are called "specs").
Traditionally, { Siesta.Test.BDD#describe describe} is used to denote "big", top-level sections:
StartTest(t => {
t.describe("My system", t => {
...
})
})
And { Siesta.Test#it it} is used to denote tests for smaller, more specific functionality.
StartTest(t => {
t.describe("My system", t => {
t.it("Should allow user to log in", t => {
...
})
})
})
The difference between `describe` and `it` is pure semantically - codewise they are the same, both are just sub tests,
forming a tree, with the top-level test file as the root. Sub tests can be nested arbitrarily, `it` section can contain `describe`
and vice-versa.
Every sub test receives a new { Siesta.Test} instance as the 1st argument, which should be used inside the test.
See also { Siesta.Test.getSubTest getSubTest} method.
## Isolation
Best practice will be to make every section standalone, somewhat limited and not depending on others. Then you have a lot of small such sections.
This makes the test more readable and limits the scope of every testing scenario.
We found, that readability of tests is optimal, when nesting is not more than 2-3 levels. If you need more levels, then may be its a good idea
to start a new test file instead. You may need to make some functionality re-usable,
by <a href="#!/guide/extending_test_class">extending the Siesta.Test class</a>.
You can use { Siesta.Test#beforeEach beforeEach}/{ Siesta.Test#afterEach afterEach} methods to add
common setup/cleanup code. Overall, usually it looks like this:
StartTest(t => {
// global variable accessed by all subtests
let store
t.beforeEach(function () {
// do setup, return some fixed dataset for example:
store = new DataStore({ data : [ { foo : 'bar'} ] })
})
t.it("Should fire load event", t => {
store.load()
// `store` instance will be "fresh" not shared with others "it" sections
t.firesOk(store, "load", 1, "Exactly one load event fired")
...
})
t.it("Should sort correctly", t => {
// again `store` here will be newly created instance
store.sort()
// verify sorting
...
})
})
In the "beforeEach" function you can also for example render some components or do something else (like clear the DB).
Sometimes the "beforeEach" function has to be async:
StartTest(t => {
var store
// declare the `beforeEach` with 2 arguments, 2nd is the callback
t.beforeEach((t, next) => {
store = new DataStore({ data : [ { foo : 'bar'} ] })
// call the provided `next` callback when the `beforeEach` action has completed
// in this case it is asyncronous store loading
store.load({ callback : next })
})
t.it("Should do this", t => {
// `store` instance will be already loaded
t.expect(store.getCount()).toBeGreaterThan(0)
})
t.it("Should do that", t => {
// `store` instance will be already loaded
...
})
})
## Skipping
You can also easily test just one sub-test by adding the extra letter in the beginning: { Siesta.Test#iit iit},
{ Siesta.Test#ddescribe ddescribe}) or exclude some sub-test ({ Siesta.Test#xit xit}, { Siesta.Test#xdescribe xdescribe}).
See also { Siesta.Project.failOnExclusiveSpecsWhenAutomated failOnExclusiveSpecsWhenAutomated} method.
## Expectations
Assertions in BDD terminilogy are called *expectations*.
<p class="side-note">
Siesta supports the expectations syntax as described below. We found it less self-explanatory though, as failed assertions
lack any context and sometimes its harder to find, what exactly has failed. You can use any of the assertions styles,
or mix both.
</p>
Expectation can be created with the { Siesta.Test.BDD#expect expect} method.
StartTest(t => {
t.describe("My system", t => {
t.it("Should allow user to log in", t => {
t.expect(MyApp.LoginManager.isLoggedIn()).toBe(false)
MyApp.LoginManager.login()
t.expect(MyApp.LoginManager.isLoggedIn()).toBe(true)
})
t.describe("Report engine of my system", t => {
t.it("Should allow generate reports in PDF", t => {
...
})
})
})
})
Please refer to the { Siesta.Test.BDD.Expectation} for the list of supported expectations.
## Spies
Siesta implements spies with the same functionality and syntax as seen in Jasmine along with small improvements.
One can spy on a function property of some object or create a standalone spy, suitable for event listener or similar.
StartTest(t => {
...
let spy = t.spyOn(obj, 'process')
// or, if you need to call the original 'process' method
let spy = t.spyOn(obj, 'process').and.callThrough()
// call the method
obj.process('fast', 1)
t.expect(spy).toHaveBeenCalled();
t.expect(spy).toHaveBeenCalledWith('fast', 1);
})
Please refer to the { Siesta.Test.BDD#spyOn} method and { Siesta.Test.BDD.Spy} class.
Buy this product
---------
Visit our store: <https://bryntum.com/store/siesta>
Support
---------
Ask a question in our community forum: <https://www.bryntum.com/forum/viewforum.php?f=20>
Subscribers can post expedited questions in Premium Forum: <https://www.bryntum.com/forum/viewforum.php?f=21>
Please report any bugs through the web interface at <https://www.assembla.com/spaces/bryntum/support/tickets>
See also
---------
Siesta web-page: <https://bryntum.com/products/siesta>
Other Bryntum products: <https://bryntum.com/products>
Attribution
---------
This software contains icons from the following icon packs (licensed under Creative Common 2.5/3.0 Attribution licenses)
- <http://www.famfamfam.com/lab/icons/silk/>
- <http://led24.de/iconset/>
- <http://p.yusukekamiyamane.com/>
- <http://rrze-icon-set.berlios.de/index.html>
- <http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/>
- <http://www.doublejdesign.co.uk/products-page/icons/super-mono-icons/>
- <http://pixel-mixer.com/>
Thanks a lot to the authors of the respective icons packs.
COPYRIGHT AND LICENSE
---------
Copyright (c) 2009-2022, Bryntum & Nickolay Platonov
All rights reserved.