Basics

CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The test is written as a linear scenario of user's action on a site.

Feature('CodeceptJS demo');

Scenario('check Welcome page on site', (I) => {
  I.amOnPage('/');
  I.see('Welcome');
});

Tests are expected to be written in ECMAScript 7.

Each test is described inside a Scenario function with I object passed into it. I object is an actor, an abstraction for a testing user. I is a proxy object for currently enabled Helpers.

Architecture

CodeceptJS bypasses execution commands to helpers. Depending on helper enabled your tests will be executed differently. If you need cross-browser support you should choose Selenium-based WebDriver or Protractor, if you are interested in speed - use Chrome-based Puppeteer, or Electron-based Nightmare. Those engines can run tests in window mode or headlessly and doesn't require additional tools to be installed.

Here is the diagram of CodeceptJS architecture

All helpers share the same API so it's easy to migrate tests from one backend to other. However, because of difference in backends and their limitations, they are not guarantted to compatible between each other. For instance, you can't set request headers in WebDriver or Protractor, but you can do so in Puppteer or Nigthmare.

Please note, you can't run tests by different helpers at once. You can't use some APIs from WebDriver and some from Nightmare. You should pick one helper, as it definses how tests are executed. If requirements change it's easy to migrate to another, but don't use few helpers at once. It's just not possible.

A helper should be enabled in main config. Configuration (like base url) should be provided as well:

  "helpers": {
    "WebDriver": {
      "url": "http://localhost",
      "browser": "chrome"
    }
  }

In this config config all methods of I will be taken from WebDriver helper.

Writing Tests

Tests are written from user's perspective. There is an actor (represented as I) which contains actions taken from helpers. A test is written as a sequence of actions performed by actor:

I.amOnPage('/');
I.click('Login');
I.see('Please Login', 'h1');
// ...

To list all available commands for current configuration run codeceptjs list or enable auto-completion by generating TypeScript definitions.

For most helpers basic actions like amOnPage, fillField, click are the same. Proceed to Acceptance Testing Chapter to learn how to use them.

How It Works

Tests are written in synchronous way. This improves readability and maintainability of tests. While writing tests you should not think about promises. You should focus on test scenario.

However, behind the scene all actions are wrapped in promises inside the I object. Global promise chain is initialized before each test and all I.* calls will be appended to it as well as setup and teardown.

If you want to get information from a running test you can use await inside async function and special methods of helpers started with grab prefix.

Scenario('try grabbers', async (I) => {
  let title = await I.grabTitle();
});

then you can use those variables in assertions:

var title = await I.grabTitle();
var assert = require('assert');
assert.equal(title, 'CodeceptJS');

Running Tests

To launch tests use run command. To execute tests in multiple browsers or multiple threads use run-multiple.

Level of Detail

To see step-by-step output of running tests, add --steps flag:

codeceptjs run --steps

To see more detailed output add --debug flag:

codeceptjs run --debug

To see very detailed output system use --verbose flag:

codeceptjs run --verbose

Filter

A single test file can be executed if you provide a relative path to such file:

codeceptjs run github_test.js

# or

codeceptjs run admin/login_test.js

To filter a test by name use --grep parameter. Which will execute all tests with names matching the regex pattern.

To run all tests with slow word in it

codeceptjs run --grep "slow"

It is recommended to filter tests by tags.

For more options see full reference of run command.

Comments

There is a simple way to add additional comments to your test scenario. Use say command to print information to screen:

I.say('I am going to publish post');
I.say('I enter title and body');
I.say('I expect post is visible on site');

Use second parameter to pass in color value (ASCII).

I.say('This is red', 'red'); //red is used
I.say('This is blue', 'blue'); //blue is used
I.say('This is by default'); //cyan is used

IntelliSense

If you are using Visual Studio Code or other IDE that supports TypeScript Definitions, you can generate step definitions with

codeceptjs def

Now you should include /// <reference path="./steps.d.ts" /> into your test files to get method autocompletion while writing tests.


Next: Acceptance Testing >>>