MochaSuite

About

Each group of tests — a suite — is represented by an instance of this class. Suites can have child suites and thus you can define a hierarchy of test groups.

You do not instantiate MochaSuite directly; instances are created as needed when you call various test functions.

API

.after()

.after(func : Callable { ; …funcN : Callable })

This function adds one or more Callables to the list of functions to be called after all of the tests in this suite are run. You would typically use this for teardown of resources that you set up in .before().


.afterEach()

.afterEach(func : Callable { ; …funcN : Callable })

This function adds one or more Callables to the list of functions to be called after each test in this suite is run. You would typically use this for teardown of resources that you set up in .beforeEach().

When suites are created, they inherit the .afterEach() list from their parent.


.before()

.before(func : Callable { ; …funcN : Callable })

This function adds one or more Callables to the list of functions to be called before any of the tests in this suite are run. You would typically use this for setting up resources or for setting .context values used by multiple tests.


.beforeEach()

.beforeEach(func : Callable { ; …funcN : Callable })

This function adds one or more Callables to the list of functions to be called before each test in this suite is run. You would typically use this for setting up resources or for setting .context values that must be initialized fresh for each test.

When suites are created, they inherit the .beforeEach() list from their parent.


.context

.context : Object

Each suite has a .context object property you can use to pass values to tests. Typically you would only use .context in a .before() or .beforeEach() formula.

Example

Function testConfig($suite : cs.MochaSuite)
  var $it : cs.MochaSuite

  $it:=$suite.describe(".loadConfig()")

  $it.before(\
    Formula(_.loadConfig()); \
    Formula(This.context.fixture:=_.json("{'foo': 'bar', 'bar': { 'baz': 13.27 }}"))\
    )

  $it.should(\
    "load the default 4d.config.json from /RESOURCES/config"; \
    Formula(This.expect(_.config).to.equal(This.context.fixture))\
    )

.describe()

.describe(title : Text) : cs.js.MochaSuite

This function create a new child suite with the given title. Most of the time .describe() is used to group tests.

Example

Function testCapitalize($suite : cs.js.MochaSuite)
  var $it : cs.js.MochaSuite
  $it:=$suite.describe("capitalize()")

  $it.should(\
    "capitalize only the first character by default"; \
    Formula(This.expect(_.capitalize("bAR")).to.strict.equal("BAR"))\
  )

  $it.should(\
    "capitalize the first character and lowercase the rest if $lowercase is true"; \
    Formula(This.expect(_.capitalize("bAR"; True)).to.strict.equal("Bar"))\
  )

.exclusive

.exclusive : Boolean

Returns whether .only() has been called for this suite. This property is read-only.


.only()

.only() : cs.js.MochaSuite

Sometimes it is useful to limit the number of tests that are run when you are working through multiple iterations of the same code. If .only() has been called on any child suites within a parent suite, only those suites will be run. Note that more than one suite can be marked with .only().

The current suite is returned for chaining.

Example

Function testCapitalize($suite : cs.js.MochaSuite)
  var $it : cs.js.MochaSuite

  // We want to run only this sets of tests within the parent $suite
  $it:=$suite.describe("capitalize()").only()

  $it.should(\
    "capitalize only the first character by default"; \
    Formula(This.expect(_.capitalize("bAR")).to.strict.equal("BAR"))\
  )

.should()

.should(description : Text; func : Callable { ; …funcN : Callable }) : cs.js.MochaTest

This is a convenience function that does the same as .specify(), but prepends description with "should ". This allows you to use a natural sounding syntax when writing tests. This is usually the main function you call to create tests.

Example

Function testCapitalize($suite : cs.js.MochaSuite)
  var $it : cs.js.MochaSuite

  // We want to run only this test within $suite
  $it:=$suite.describe("capitalize()")

  // Next two tests are equivalent
  $it.should(\
    "capitalize only the first character by default"; \
    Formula(This.expect(_.capitalize("bAR")).to.strict.equal("BAR"))\
  )

  $it.specify(\
    "should capitalize only the first character by default"; \
    Formula(This.expect(_.capitalize("bAR")).to.strict.equal("BAR"))\
  )

Why do we wrap the assertion in a Callable?

There are several reasons why assertions are wrapped in a Callable:

  • The test runner has two phases. In the first phase, it collects all of the tests and their assertions. In the second phase, it runs the tests. The Callable is used to defer the execution of the assertion until the second phase.

  • .skip() and .only() would not work if the assertions were run immediately.

  • If a test has multiple assertions, it skips the rest of the assertions if one of them fails. If the assertions were run immediately, because 4D does not have real exceptions, it would be up to you to check for failure after each assertion.


.skip()

.skip() : cs.js.MochaSuite

Sometimes it is useful to temporarily exclude some tests that are failing when you are working through multiple iterations of the same code. If .skip() has been called on any child suites within a parent suite, those suites will not be run. Note that more than one suite can be marked with .skip().

The current suite is returned for chaining.

Example

Function testCapitalize($suite : cs.js.MochaSuite)
  var $it : cs.js.MochaSuite

  // The test that follows will not be run
  $it:=$suite.describe("capitalize()").skip()

  $it.should(\
    "capitalize only the first character by default"; \
    Formula(This.expect(_.capitalize("bAR")).to.strict.equal("BAR"))\
  )

.specify()

.specify(description : Text; func : Callable { ; …funcN : Callable }) : cs.js.MochaTest

Use this function to create a test with one or more Callables (usually Formula) that call This.expect. The Callables will be called in the order they are passed, with This set to the MochaTest instance returned by this function. If a test fails, the remaining tests are skipped.

Because test results are presented like a checklist, for readability description should state what the thing you are testing does or has. For example, you would want the test results to look like this:

foobar
  ✔ does foo when passed "bar"
  ✔ has bar

or this:

foobar
  ✔ should do foo when passed "bar"
  ✔ should have bar

If you are using the "should" form, then it is easier to use .should() instead of .specify(), since that prepends "should " for you in description. If you don’t want to use "should" or description is in a language other than English, use this function.

Last Updated:
Contributors: Aparajita