testing-toolbox
Additional expectations for chai
package and other utilities
Installation
Install the package with
npm install --save-dev o-testing-toolbox
Usage
Defining variables with letBe statements
For this extension to work first you need to install the following packages:
npm install --save-dev mocha
npm install --save-dev chai
First include the LetBeExtesion
plugin for chai
in your test file
const chai = const expect = const LetBeExtension = chai
Then define a variable with
letBe '/login'
(read it let loginUrl be '/login'
like in math: let O be a not empty set
)
If the value is a literal it is possible to use the shortcut
letBeloginUrl = '/login'
Note that using the shortcut does not assign the value. It wraps it with an initializer. It also freezes the constant to avoid errors caused by secondary effects on the variable object. As a rule of thumb always use the first form.
letBe definitions can be anywhere in the test:
- in the outer scope
- in the inner scope
- in the inner nested scope
- in the test scope
Avoid defining letBe statements out of a beforeEach
or before
block
// Not good. This assignment is global and it's executed only once when the file is requiredletBe '/login'
// Good. This assigment is loaded once when the file is required but it's evaluated before each test
To use a variable defined with letBe reference it like any other variable
It is possible to override letBe variables at any scope and still reference them from outer scopes
The differences between using a regular variable assigment
const loginUrl = '/login'
and a letBe definition are
- a letBe variable is lazily initialized on its first use, not on its definition
- (that means that) a letBe definition can reference other letBe definitions without caring about the order of declarations. That may or may not improve the understanding of the test but can be used to override letBe variables within inner scopes. See the previous example
- also, it means that if a letBe variable is not used in a test it won't be initialized in that tests. Keep it in mind if your variable has expected side effects like creating items in a database
- letBe variables can not be assigned with a value after its initialization. They behave like
const
variables - all letBe variables are always unset before and after each test run. That makes each test to start fresh and avoids side effects from previous tests
Defining helper methods with letBeMethod statements
If there is common or complex code in the tests is can be extracted to a method with the statement
letBeMethod { return a + b }
letBeMethod
statements behave exactly like letBe
variables.
Async expectation
Express expectations on Promises with
const chai = const expect = const LetBeExtension AsyncExtension = chaichai
The expectation must end with .endWith(done)
Collection expectations
These assertions are available in the CollectionExtension
const chai = const expect = const LetBeExtension CollectionExtension = chaichai
These expectations usually get along well with .satisfy
, .suchThat
and .expecting
and .samePropertiesThan
chain expectations
These assertions are available in the ChainExtension
const chai = const expect = const LetBeExtension ChainExtension = chaichai
suchThat expectation
To express custom expectations on a nested attribute do
const chai = const expect = const LetBeExtension ChainExtension = chaichai
make expectation
To assert that an action has some side effect on other objects do
const chai = const expect = const LetBeExtension ChainExtension = chaichai
Note that make
always takes a block as its parameter and not a value.
The reason is that a parameter would be evaluated before calling the .make
assertion
and therefore before the evaluation of the expect
block.
This expectation can be used to test state after some event like a click or receiving a request occurs.
after expectation
Changes the subject of the assertion chain setting it to the result of the evaluation of the given block
const chai = const expect = const LetBeExtension ChainExtension = chaichai
This expectation can be combined with .make
to express assertions like
const chai = const expect = const LetBeExtension ChainExtension = })
as a simple alternative to the use of mock assertions.
expecting expectation
Takes a block with the subject as its parameter to allow multiple assertions on the subject.
For example
const chai = const expect = const LetBeExtension ChainExtension =
With a regular assertions chain it would not be possible to make further assertions on the list
object after the .firstItem
assertion since it would have change the assertion subject.
After the evaluation of the block it is possible to continue with assertions on the original subject.
For example
const chai = const expect = const LetBeExtension ChainExtension =
equalTo, eqlTo and matching expectations
equalTo
, eqlTo
and matching
expectations are synonyms of equal
, eql
and match
.
They are meant to be used when they might make an assertion more readable, for example
expect(component).to.have.div.with.text.equalTo('A text')
Json expectations
Assert expectations on nested structures with
const chai = const expect = const LetBeExtension JsonExtension = chaichai
If you need only a partial match do
const chai = const expect = const LetBeExtension JsonExtension = chaichai
If you need to assert that the actual object does not have other properties than the expected ones do
const chai = const expect = const LetBeExtension JsonExtension = chaichai
If you need to assert on some nested property for a custom expectation use a function instead of a value:
const chai = const expect = const LetBeExtension JsonExtension = chaichai
This expectation block is useful to test for a text to match a regular expression and for a float to equal a constant
const chai = const expect = const LetBeExtension JsonExtension = chaichai
File expectations
Assert expectations on a file with
const chai = const expect = const LetBeExtension FileExtension = chaichai
The expected path
can be a String
or any other object that implements a .toString()
method.
Particularly it could be a Path
object with a path.toString()
method.
Disposable files helper
To create temporary files or directories during the tests use
const chai = const expect = const TmpDir =
The files and directories created through TmpDir
are unique for each test execution and reside in the /tmp
directory of your operative system and will be eventually discarded.
Skipping slow tests
For this extension to work first you need to install the following packages:
npm install --save-dev mocha
npm install --save-dev chai
Mocha reports tests that take longer to run than a configurable threshold.
In a regresion test you would like to run all tests but while you are developing a feature you may want to skip the slow ones.
To skip slow tests first run all the tests as usual to see which ones are reported to be slow
npm test
Once you have identified the slow ones on each slow test file include the SlowTestsExtension
plugin for chai
const chai = const expect = const SlowTestsExtension = chai
and replace the original test
with
It's also possible to flag an entire group as slow:
slow
Finally if you want to run the tests skipping the ones flagged as slow do
skip_slow=true npm test
To run all the tests execute
npm test
as usual.
Expected code styles
For this extension to work first you need to install the following packages:
npm install --save-dev mocha
npm install --save-dev chai
npm install --save-dev eslint
npm install --save-dev eslint-config-standard
npm install --save-dev eslint-plugin-import
npm install --save-dev eslint-plugin-node
npm install --save-dev eslint-plugin-promise"
npm install --save-dev eslint-plugin-standard"
To test that your source code complies with the coding standards and best practices create the test
const path = const chai = const expect = const LetBeExtension SourceCodeExtension SlowTestsExtension = chaichaichai
Replace the variable letBe.eslintConfigFile
with your own eslint
config file or delete it if you don't use a custom config file.
Expected code coverage
For this extension to work first you need to install the following packages:
npm install --save-dev mocha@7npm install --save-dev chai npm install --save-dev nyc
Note that for this extension mocha version must be mocha@7
due to breaking changes in version mocha@8
To test that the tests coverage is above an expected minimum create a new test file with the following contents:
const chai = const expect = const LetBeExtension SourceCodeExtension SlowTestsExtension = chaichaichai const linesCoverageTarget = 100
Notes:
- This test file is excluded for the coverage test otherwise it would create an infinite recursion.
- Replace the variable
letBe.mochaConfigFile
andnycConfigFile
with your ownmocha
andnyc
config files or delete them if you don't use a custom config file. - The coverage test is always flagged as slow. You can skip running the tests with
skip_slow=true npm test