Effective End 2 End Testing in JavaScript with CodeceptJS

Written by davert | Published 2018/05/15
Tech Story Tags: javascript | testing | javascript-codeceptjs | codeceptjs | software-development

TLDRvia the TL;DR App

There are a variety of tools in modern JavaScript which are focused on end to end testing. However, when you need to choose one tool you can take up for a week evaluating pros and cons of different tools. You should consider their features, syntax, maintainability and in the end, you still have doubts if you are doing the right choice. Picking one library makes your tests bound to its implementation, as all end 2 end testing tools in JS have their own syntax.

Let’s say you wanted to run tests with Selenium and then you discovered that they are taking too slow and you just learned that there is a new tool Puppeteer from Google Chrome which allows driving tests faster. If you decided to migrate your tests you would need to rewrite them. What a pain!

That brings us to the first key idea of CodeceptJS. Your tests should not bound to your execution engine. Either you choose Selenium or Puppeteer your tests should look almost the same. But wait a minute… What is CodeceptJS?

Introducing CodeceptJS

You guessed it right! CodeceptJS is a testing framework. But unlike other testing tools for JavaScript, it uses most popular JS libraries to drive your browser and adds high-level API on top of them. That’s why a test written for webdriverio could be executed in Protractor or Puppeteer.

If once you feel the limitation of one engine you can easily switch your tests to other. And what about the second key idea, high-level API?

Let’s show the code:

As you see, the test is very easy to read. It can even be understood by the non-technical person.

So for instance, when you need to fill in a field you can specify a name, placeholder or a label of that field and CodeceptJS will find that for you. No need of fragile and long CSS or XPath locators, if your HTML is designed correctly you can match elements by their semantic values:

If you are experienced JavaScript developer you will notice something unusual in this code. There are no chained calls in the test scenarios. All actions are written one by one as a linear scenario.

Really, no promises, no async-awaits? How does it work?

No-await?

The problem is not about making the things work, the problem is in writing clean maintainable tests. JavaScript is very expressive language, however, maintaining codebase with dozens of then or await calls is not a simple task. Or brains are focused on handling promises and not on test scenarios themselves. That’s why CodeceptJS helps us reducing the visual noise. As the tests are linear in most cases we don’t need to know about promises and modern software is smart enough to handle all promises by itself.

So promises are handled by CodeceptJS, providing you with synchronous style experience. However, when you need to interrupt promise chain and get some values out of browser context you still can use async/await:

That’s the only reason why you may need async functions in CodeceptJS tests. And the only fact when you should you care about promises.

Writing a Test

First, we need to install CodeceptJS. To start testing we need to choose engine (WebDriverIO, Protractor, Puppeteer, Nightmare) and specify the base URL for all tests. Let’s test something very familiar to every developer here: https://github.com.

First test for `github.com` can start with two lines:

I.amOnPage(‘/’); — opens a website at base url (`[https://github.com`+`/`](https://github.com`+`/`))pause() — interrupts the execution and switches to interactive shell mode

Interactive Shell

In this mode, you can work with a browser side-by-side and control it with simple commands. Type `click` and choose an element to see if an element can be located that way and it can actually be clicked. If command passes — add it to your test. If not — try again with the different locator.

Interactive shell in action

So while working in Interactive Shell mode you can write down a complete test.

Also during debug, you can put a pause() in every line and switch to interactive shell. This feature works even in headless mode. Using Interactive shell is more powerful than debugging your application with breakpoints.

Scenario Driven Tests

Tests are designed to be written as a scenario told by a persona, user who interacts with a system. When executing such tests with `codecept run — steps` command you will see actual step-by-step output and failures when a step fails

Step-by-step output when running tests

In a report, you will always see what step has failed and as a bonus for each failed test, a screenshot of the last page is taken so you can easily review what went wrong and fix it.

More Testing!

As you have seen, CodeceptJS is quite easy to start. Also, CodeceptJS is a mature framework which you can stay with. It provides native support for Page Objects, it has tools to manage data for your tests, supports testing in several browsers (multi-session testing), and because of high-level API, you can even write tests in other languages!

No. That would be JavaScript anyway. But you can write tests in other languages than English!

How about some Portuguese tests?

Other translations are supported as well.

CodeceptJS can also execute mobile tests with Appium, run tests in parallel, and… Well, that goes far beyond the introductory post. So you should discover it for yourself.

If you never liked end to end testing — try CodeceptJS which makes testing fun and effective.


Published by HackerNoon on 2018/05/15