ekke v1.1.0
EKKE
Ekke-Ekke-Ekke-Ekke PTANG Zoo Boing! Z' nourrwringmm...
ekke a unique new test runner for React-Native. Unlike other testing
frameworks, it doesn't execute your tests in Node.js, with a bunch of mocks, but
instead, it orchestrates the bundling and execution of tests directly inside
your React-Native application.  ekke allows your tests to fully access every
API to the platform has to offer.
Why should you adopt Ekke for React-Native testing?
- Platform independent The test runner does not contain any native code that means that every platform that React-Native supports now, or in the future will work out of the box.
- Code confidence Tests run in the environment of your production code. No need to rely on imperfect mocks. Tests run on devices to guarantee API's match specifications.
- Different test runners At its core, Ekke is nothing more than an orchestration tool. We have built-in support for different test runners.
- Rendering It's not just unit tests. Ekke provides a rendering API that allows you to mount and render components in your test suite.
Installation
The module is released in the public NPM Registry and can be installed by running:
npm install --save ekkeAfter installation, you can integrate ekke into your project.
Table of Contents
Integration
Ekke needs a host application to run. That can either be the application you are
currently developing or fresh installation of react-native init.
Not sure what to pick?
- Application developers Using the application that you're currently
developing is recommended. This allows your test suites to execute in
precisely the same environment. Also, it will enable your test suites to
leverage any NativeModulethat your application might be consuming.
- Library authors It depends on the library you're developing. If you are
building a native add-on, or include NativeModulesas dependencies, it's advised to create an example application in your project that has all native libraries linked. TODO: What is the alternative here, if there is one?
Integrating is as easy as importing ekke, and including the component in
your app!
import { Ekke } from 'ekke';
function App() {
  return (
    <>
      <Ekke />
      <View>
        <Text>Your App Here</Text>
      </View>
    </>
  )
}You can now run your tests by executing the run command of the ekke CLI:
# Make sure that the simulator of your choice is running.
react-native run-ios # or react-native run-android
ekke run glob/pattern/*.test.js more/test/files.js --using mochaAnd now watch the magic unfold on your app.
If you are worried about shipping
Ekkein your application, the component is using process.env.NODE_ENV to switch between development and production builds. Production builds will completely removeEkkefrom your code. You can also conditionally include it{ __DEV__ && <Ekke /> }.
Runners
At its core, Ekke is nothing more than an orchestration tool, it runs Metro bundler with a specific configuration, executes code automatically in the React Native environment, and reports back in the CLI. To run the test, we need to know which test runner you prefer so we can bundle it with the tests. The following runners are available:
mocha
To use Mocha make sure you have the testing framework as well as an assertion framework installed in your project:
npm install --save-dev mocha
npm install --save-dev assume # or any other assert framework, e.g. chaiOnce all your dependencies finish installing, you can start writing your tests.
import { describe, it } from 'mocha';
import { render } from 'ekke';
import assume from 'assume';
describe('The best test suite in the world', function () {
  it('is amazing', function () {
    const amazing = 'amazing';
    assume(amazing).is.a('string');
    assume(!!amazing).is.true();
  });
});Provide mocha as value to the --using flag to select it as test runner.
ekke run test.js --using mochaThe following Mocha options can be customized using the follow CLI flags:
- --mocha.fgrepOnly run tests containing this string. Defaults to- ''.
- --mocha.grepOnly run tests matching this string. Defaults to- ''.
- --mocha.invertInverts grep and fgrep matches. Defaults to- false.
- --mocha.uiSpecify user interface. Defaults to- bdd.
- --mocha.reporterSpecify reporter to use. Defaults to- spec.
- --mocha.slowSpecify "slow" test threshold (in milliseconds). Defaults to- 75.
- --mocha.timeoutSpecify the test timeout threshold (in milliseconds). Defaults to- 2000.
- --mocha.bailAbort ("bail") after first test failure. Defaults to- true.
- --mocha.colorForce-enable color output. Defaults to- true.
- --mocha.inlineDiffsDisplay actual/expected differences inline within each string. Defaults to- true.
ekke run test.js --using mocha --mocha.reporter min --mocha.timeout 5000Tape
Using tape as the test runner is pretty
self-explanatory. You import tape into your test files and write your tests
and assertions using provided by the framework.
import { render } from 'ekke';
import test from 'tape';
test('one', function (t) {
  t.plan(2);
  t.ok(true);
  setTimeout(function () {
    t.equal(1+3, 4);
  }, 100);
});Once the tests are completed, simple tell ekke that you're --using tape to
run the tests.
ekke run test.js --using tapeThe will run your tests, and output the TAP (Test. Anything. Protocol) to your
terminal which you can pipe to any of the Pretty Tap
Reporters that you might
have installed. For example, if you want to use tap-spec:
ekke run test.js --using tape | tap-specAPI
The API exposes the following methods:
Component
import { Ekke } from 'ekke';The Ekke component controls the orchestration, execution, and rendering of the
test suite. The component can be used as a wrapper, or as a regular component
and be included in your application.
The component accepts the following optional properties:
- interval, String, The component doesn't know when you are using the CLI, so it polls at a given interval, with an HTTP request, to the server that runs in the CLI to figure out if it's active and is waiting for tests to run. The lower the interval, the quicker your tests will be picked up by the component, but also the more performance it takes away from your app. Defaults to- 10 seconds.
- hostname, String, The hostname of your machine that the CLI server is running on. Defaults to- localhoston iOS and- 10.0.2.2on Android.
- port, Number, The port number that the CLI server is running on. Defaults to- 1975.
- alive, Function, Function to execute when the- Ekketest runner is activated and is about to run the test suites.
//
// Stand alone.
//
<Ekke />
//
// Or wrap your app with it, you decide what is best for your application.
//
<Ekke>
  <App />
</Ekke>To see an example of the implementation, take a look at our index.js file. It's what we use to test our code.
render
import { render } from 'ekke';The render method allows you to render any React-Native component on the screen of the application.
import { View } from 'react-native';
import { render } from 'ekke';
import React from 'react';
describe('test', function () {
  it('renders a red square', function () {
    const ref = React.createRef();
    await render(<View style={{
      backgroundColor: 'red',
      width: 100,
      height: 100
    }} ref={ ref } />);
    //
    // You can now use ref.current to access the rendered view.
    // Not only that, but there's big red square on your app as well.
    //
  });
});CLI
The ekke CLI is automatically installed in your node_modules when you
install ekke in the project as a dependency. We use the CLI to communicate
between the <Ekke /> component that you included in your application and the
terminal.
The CLI should not be globally installed. Instead, you directly reference
the locally installed binary from your package.json.
{
  "name": "your-super-awesome-package",
  "scripts": {
    "test": "ekke run test/*.js --using mocha"
  }
}And run the scripts using npm.
npm test
# You can use the double dash support from npm to send additional flags:
# npm test -- --watchAlternatively, you can use the npx command to execute the commands as well
without the requirement of global installation of ekke:
npx ekke <commands here>The following CLI commands are available:
run
ekke run <glob or files to run> --flagsThe run command allows you to run your specified tests on the device that
included the <Ekke /> React component. When you run the command, we will
execute the following:
- Start up the Metro bundler on the specified hostnameandport.
- Attach a WebSocket server on the created Metro bundler, for communication purposes.
- Find all the test files you want to include based on the supplied glob.
- Wait for the poll request from the <Ekke />component.
- Bundle all your tests, and the specified library using Metro Bundler.
- Listen to progress events that are sent by <Ekke />component over the WebSocket connection.
- Proxy all the console.*,process.stdoutto your terminal.
- Close the CLI again with error code 0or1depending on if your tests pass.
The run command assumes that all CLI arguments after the run command are the
test files that need to execute inside React-Native. We allow single or multiple
files, a glob pattern, or a combination of files and globs.
# Executes test/1.js, test/2.js, and then test/2.js using the mocha runner.
ekke run test/1.js test/2.js test/3.js --using mocha
# The same above, but done using a glob pattern to fetch all .js files
# from the test directory
ekke run test/*.js --using mocha
# Executes test/1.js and then all the .test.js files
ekke run test/1.js test/*.test.js --using tapeYou can use the following CLI flags to change the behavior of the command:
- --using {runner}This tells Ekke which runner should be used to execute your tests. Defaults to- mochaSee Runners for all runners.
- --watchBy default, we close the process with either an exit code- 0or- 1as an indication of the test results (0 passes, 1 failure). If you do not want the process to exit, you can use the- --watchflag to keep the CLI process alive. Defaults to false.
- --reset-cacheThe Metro Bundler caching system is enabled by default so that tests run in a performant way and don't always rebuild. Using this flag will disable the cache. Defaults to false.
- --cache-locationWe already made sure that the Metro Bundler cache of your test doesn't collide with your test cache, but if you like to store it somewhere else you can change it with this flag. Defaults to- os.tempdir()/ekke-cache.
- --no-silentWe silence the output of the Metro bundler by default, this allows you to see the Metro bundler output again. Defaults to false.
- --hostnameThe hostname we should attach our Metro Bundler on. The hostname should be accessible by React-Native application. Defaults to- localhost.
- --portThe port number we should use for the Metro Bundler, we don't want to clash with the Metro bundler of your- react-native startcommand so it should be different, but still accessible by your React-Native application. Defaults to- 1975(The year Monty Python and the Holy Grail got released)
- --requireFiles that should be required before your test suites are required Defaults to ¯_(ツ)_/¯, nothing
In addition to these default flags, any flag that you prefix with the name of the runner will be considered as options and used as configuration:
ekke run test.js --using mocha --mocha.timeout 3000See the Runners for their specific configuration flags.
help
Display a list of all the available command their supported CLI flags. The help
message is visible when you run ekke without, an unknown, or the help
command:
ekke (v1.0.2)
Ekke-Ekke-Ekke-Ekke-PTANG. Zoo-Boing. Z' nourrwringmm...
COMMANDS:
run      Run the given glob of test files.
         --port           Port number that Metro Bundler should use.
         --hostname       Hostname that Metro Bundler should use.
         --using          Name of the test runner to use.
         --watch          Don't exit when the tests complete but keep listening.
         --no-silent      Do not suppress the output of Metro.
         --require        Require module (before tests are executed).
         --reset-cache    Clear the Metro cache.
         --cache-location Change the Metro cache location.
help             Displays this help message.
         --no-color       Disable colors in help message.
EXAMPLES:
$ ekke run ./test/*.test.js --using mochaThe output contains colors by default if you wish to remove those you can use
the --no-color flag.
Debugging
Both the CLI and the react-native code bases use diagnostics under the
hood for logging purposes. The logs are disabled by default but can be enabled
by using the DEBUG feature flags. They both log under the ekke:* namespace.
The Ekke CLI
DEBUG=ekke* ekke <your command here>React Native Component
import { AsyncStorage } from 'react-native';
AsyncStorage.setItem('debug', 'ekke*', function () {
  //
  // Reload your app, and the debug logs will now be enabled.
  //
});For more detailed information about diagnostics, please see their project page.
Development
- Fork Fork the repository to create a copy to your own GitHub account.
- Clone Clone the newly created GitHub repo to your local machine.
- Branch Create a fresh new branch from the master branch.
- Install Run npm installto install dependencies and devDependencies.
- Setup Run npm run setupto create development specific folders.
- Hack Make your changes. Write tests covering your changes.
- Test Run both npm testandnpm test:ekketo ensure nothing got broken.
- Push Commit and push your changes to fork.
- Pull Request Create a pull request from your created branch to our master.
- Review We'll review your change, and ask for updates if need.
- Merge Virtual high fives are exchanged when your PR lands.