How to unittest Firefox 57 WebExtensions?
Asked Answered
G

2

6

The older Firefox "Add-ons" API had a built-in unittest layer sdk/test that allowed testing. This doesn't seem to be available any more.

Additionally the use of "package/require" allowed code to be separated into "js code-only" packages that were testable using node.js. The new, highly structured javascript doesn't share this.

My priorities are (highest to lowest):

  1. Algorithms, "business logic", e.g. parsing input data - no APIs needed - just JavaScript
  2. Internal logic - e.g. background scripts interacting with settings, etc.
  3. UI interactions - I can live without this, but would be nice to test

So how do people test their WebExtensions?

Galileo answered 15/11, 2017 at 10:24 Comment(0)
R
1

Check out webextension-geckodriver for a worked example of functional testing.

If you want to test interaction with the webextension API you can either do it live (have a test page for your extension and get geckodriver to visit it, for example) or use a fake like sinon-webextension through webextension-jsdom.

To unit test algorithms, just import the functions using jest, mocha, or whatever node unit testing framework you prefer or add them to a test page that you can visit in the browser.

A complete, but old, worked example of webext testing is here: example-webextension.

An example of tests in a real webextension using another fake: vim-vixen

Rockefeller answered 10/6, 2018 at 15:54 Comment(0)
D
1

It is still possible to run unit tests in NodeJs.

To illustrate the idea, let us take a look at the Cliqz extension, whose source code is open (Github link: cliqz-oss/browser-core). In comparison other extensions that I have seen so far, the code base is quite large.

In other words, it is not a toy example, but a realistic use case. The drawback, of course, is that due to the complexity, it is harder to understand how the test setup works (how mocking works, the integration into the build system, etc).

To get an idea how tests look like, here is one example:

To explain the details of how the mocking works is hard because you would need to dive deep into the build system. From a high level perspective, you will notice that in the test it uses a function called describeModule, which does all the mocking of dependencies.

In the implementation of describeModule, you can see that it uses systemjs to dynamically load ES modules. That trick makes it possible to run the unit tests with NodeJs.

My priorities are (highest to lowest):

  1. Algorithms, "business logic", e.g. parsing input data - no APIs needed - just JavaScript

For these kind of tests, the unit test infrastructure described above is the preferred way. For local development, NodeJs is used to run the tests.

  1. Internal logic - e.g. background scripts interacting with settings, etc.

This is not so different. The idea is still that you can mock dependencies and then do classical unit tests.

It might require some work to allow dependencies to be replaced. As mentioned, as the code base in this example has to run in different environments (e.g., Firefox, Chrome, Edge, ReactNative), platform APIs have to be abstracted (that includes also browser APIs).

  1. UI interactions - I can live without this, but would be nice to test

For testing the UI, there are additional integration tests. I do not want to go into details, but there are examples in the code.

What is important is that the integration tests are not executed with NodeJs, but they require a real browser environment (e.g., Firefox, Chrome). In addition, a local HTTP server is started which can be used to mock API calls.


As a side-note, linters are extremely useful and in comparison easy to setup. Also consider using a typed language (TypeScript), especially when the project becomes bigger and more people are working on it.

You will still need tests, as static analysis will not be able to find logical bugs. However, it helps to eliminate certain types of simple bugs like typos and the overhead (fixing linter errors or adding type annotations) is not very high.

Dagostino answered 11/10, 2019 at 0:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.