qunit-bdd
BDD-style testing for QUnit.
NOTE: This library should be considered deprecated in favor of using Mocha, which offers a similar BDD API. You're welcome to use it, but please do not expect a response to issues or pull requests.
;
Installation
# Install via Yarn. $ yarn add --dev qunit-bdd # Install via NPM. $ npm install [--save-dev] qunit-bdd # Install from Git. $ git clone https://github.com/square/qunit-bdd.git$ cp qunit-bdd/lib/qunit-bdd.js my-project/vendor/qunit-bdd.js
Requirements
QUnit must be installed alongside this package.
qunit-bdd | Supported QUnit Versions |
---|---|
v1.x | v1.x |
v2.x | v2.0 - v2.5.1 |
v3.x | v2.6+ |
Usage
qunit-bdd has describe
and context
, just like Mocha and Jasmine. It also
provides an assertion syntax similar to expect.js.
;
qunit-bdd also has before
and after
to run blocks of code before an after
each test run within a context:
// This example uses sinon.js, not included with qunit-bdd.;
Additionally, qunit-bdd ships with support for RSpec-style per-context let
values, called lazy
values in qunit-bdd. This is very useful when you want to
declare how to set up a complex object in a top-level context, overriding parts
of that setup in nested contexts:
;
The benefit to this approach over setting up your test objects in before
is
that you can override parts of the built objects declaratively in nested
contexts, something you might have used a bunch of helper functions to do with
QUnit's default module
/test
functions.
You can also use helper
to define helper functions that have access to
everything defined on the test context. This is useful for reusing a
piece of code between tests that have different setups. Example:
;
Async
qunit-bdd supports async
functions as before
, after
, or it
callbacks.
You may also return Promise
objects from before
, after
, and it
blocks as
a means of writing async tests. We rely on QUnit's own mechanism for this
functionality, which means we require at leastd QUnit v1.16. Here's a basic
example:
;
You can write this using explicit Promise
syntax if you prefer:
;
Configuration
It's still QUnit, so you can write some tests using the module
/test
style,
complete with the usual ok
/equal
/deepEqual
assertions, if you find it
more appropriate sometimes. Also, you can export as much or as little of
qunit-bdd to the global scope as you like:
// Turn off `lazy` and `context` exports.// Make sure to set this before loading qunit-bdd.js.QUNIT_BDD_OPTIONS = GLOBALS: lazy: false // don't use lazy expect: false // use the regular QUnit assertions (or another set altogether) ;
Randomness
By default your tests will run in the order in which they are defined. This is
usually desirable for interactive development and debugging. But for continuous
integration you may want to run your tests in a random order to reveal any
hidden dependencies between your tests that may be causing them not to work as
expected. To turn this on, set QUNIT_BDD_OPTIONS.randomize
to true
. Doing
so will first shuffle your describe
s, then shuffle the it
s within.
If you want to use a particular randomizer, pass a function that takes an array
and returns a shuffled array instead of true
. For example, here's how to
configure qunit-bdd to use chance.js with a random (but
repeatable, for reproducing failures locally) seed:
var seed = Math;console;var chance = seed;QUNIT_BDD_OPTIONS = { return chance; };
Skipping Tests
You can also configure which tests are run, which can aid in debugging. To skip
a particular test (or context), use it.skip()
instead of it()
(or
describe.skip()
instead of describe()
). To run only a particular test (or
context), use it.only()
instead of it
(or describe.only()
instead of
describe()
).
Expectations / Assertions
You can configure the built-in assertion expect()
function to add your own
custom assertions or override the built-in ones:
expect;
Note that the expect()
function can still be used as you would while writing
QUnit tests the normal way, i.e. as expect(4)
to set the number of expected
assertions.
Status
Community
Come chat on our Google Group page or use the qunit-bdd tag on Stack Overflow.
Contributing
Setup
First, install the development dependencies:
$ yarn
Then, try running the tests:
$ yarn test
Development
As you make changes you may find it useful to have everything automatically
compiled and ready to test interactively in the browser. You can do that using
the develop
script:
$ yarn run develop
Then go to http://localhost:8000/test in your browser (run with PORT={port}
to override the default port).
Pull Requests
Contributions via pull requests are very welcome! Follow the steps in Developing above, then add your feature or bugfix with tests to cover it, push to a branch, and open a pull request.
Any contributors to the master qunit-bdd repository must sign the Individual Contributor License Agreement (CLA). It's a short form that covers our bases and makes sure you're eligible to contribute.
When you have a change you'd like to see in the master repository, send a pull request. Before we merge your request, we'll make sure you're in the list of people who have signed a CLA.
Why?
QUnit is a well-tested testing framework used by projects such as jQuery and Ember. It works very well for unit-style testing with fairly simple inputs and outputs. It is less well suited to acceptance or integration testing, where you often want to test slight variations of the same thing. The nested context of the BDD style translate well to this sort of need.
You might be wondering, "Why not just use Pavlov?" That is a reasonable
question. Pavlov has been around for some time and has reached the point, much
like QUnit itself, where not much changes. Both are stable and reliable.
Unfortunately, Pavlov has a number of assumptions that did not work well with
how we test applications at Square. We wanted the ability to use multiple
before
and after
blocks per describe
(for shared examples). We wanted
async to be a first-class citizen, not something to be avoided. Pavlov runs
before
blocks synchronously from the outermost to the innermost describe
.
We needed to be able to pause until the before
in an outer describe finished
before running the before
in the next inner describe
. Finally, we wanted an
equivalent to RSpec's let
to give us a more declarative style for our objects
under test, complete with easy overrides in nested contexts. This is lazy
in
qunit-bdd.