Intern has always taken a different path in the pursuit of flexible automated web app testing.

In the early days, Intern leveraged AMD modules when most other testing frameworks were not modular or only supported CommonJS modules, allowing Intern to support modular code in any environment. Intern was also one of the first tools to leverage Istanbul to support code coverage analysis, and its flexible architecture supports integration into a variety of CI/CD environments.

Intern was one of the first JavaScript testing systems to adopt Promises, providing better flexibility for asynchronous testing. Possibly its most significant distinction, though, has been its support for a broad range of testing use cases in a consistent paradigm within a single testing framework — unit tests in Node.js, browsers, and mobile devices, functional tests, integration tests, and the flexibility to support performance and visual regression tests.

While other testing tools address some of these use cases, Intern is the only one (that we’re aware of) that addresses all of them. Every project is different, and some projects certainly benefit from the deeper support for particular workflows that specific tools may provide. However, we believe there’s significant value in having a single unifying testing framework to address the most common testing use cases.

Testing in Node and Browsers

Some of the most popular testing tools, such as Jest and AVA, only run in specific environments like Node.js, and use DOM emulation for testing browser-based code. Cypress, another popular tool, primarily supports Chromium-based browsers (Firefox support is in beta). Intern supports both Node.js and various browsers, including a wide range of desktop and mobile browsers.

Not only can Intern run in a range of environments, but it can also manage the testing process in those environments. Other testing systems that can run in browsers, such as Jasmine and Mocha, require a separate test runner such as Karma to actually manage the browsers in an automated testing flow. This functionality is built into Intern, which downloads the drivers needed to control browsers and to set up remote test sessions.

Integrated Cross Browser Testing through WebDriver

Most of the popular testing frameworks are focused on unit testing and assume developers will use separate tools to deal with functional testing. (Not many functional testing tools make it onto the “popular tools” lists because functional testing is more challenging.) Intern was designed to help developers write tests for the entire testing lifecycle, from TDD unit tests to large-scale integration tests. To that end, Intern uses the WebDriver standard to control remote browsers, allowing it to load and run unit tests in browsers as well as interact with them like an actual end user.

When used for functional tests, WebDriver lets Intern drive a browser, so that Intern’s actions appear to be those of a normal user. A well-implemented WebDriver driver will interact with a browser using native operating system events, which is the next best thing to having a real user at the controls.

WebDriver also allows Intern to interact with a wide range of devices. Some of the most popular functional testing tools, such as Cypress and Puppeteer, only work with a limited set of browsers. By using WebDriver, Intern can interact with all popular desktop browsers, as well as Android browsers and mobile Safari, and even Electron.

Supporting Modern and Legacy Modules

Running tests in different environments means dealing with different module loading situations. Node.js has a native loader, so tests written for Node.js-only frameworks or applications generally assume the presence of a loader. Browsers, on the other hand, only recently added native module loading support. Applications have been using modules for quite some time, and a number of third-party loaders, such as the Dojo loader and SystemJS, have been developed over the years to support modular code in browsers.

Intern supports the CommonJS, Dojo, and SystemJS loaders out of the box. It also has basic support for ES modules in the browser (for browsers with ES module support), and its pluggable loader system makes adding support for new loaders relatively simple. Intern can even work with non-modular test suites; as long as code can call Intern’s test registration functions, it can work with Intern. Of course, the most popular non-native module loader right now is webpack, and Intern works with that, too.

Intern 5 and Beyond: Continuing Improvements & Development

The next version of Intern is currently in development. Some great new features are planned, like a built in file-watching mode and a more ergonomic command-line client. However, many of the changes in the next release are internal, focused on streamlining Intern’s development process, simplifying the codebase, and updating some core functionality. These changes will allow further development to continue at a more regular pace.

Beyond Intern 5, development will focus on more visible enhancements like test parallelization (which will significantly speed up test runs), integrated jsdom support, and IDE plugins. Intern’s core goal, however, remains to help users write and run tests for a broad range of use cases through a consistent framework.