Skip to content

Latest commit

 

History

History
171 lines (124 loc) · 6.61 KB

testing.md

File metadata and controls

171 lines (124 loc) · 6.61 KB

Testing

Run tools/test to run all our test suites. This command is typically quite fast (5-10s, sometimes less), because it only rechecks tests related to the files you've changed.

You can run all our tests with tools/test --all. We run them this way in our CI, e.g. when you send a PR.

To see all options, run tools/test --help.

Unit tests: JS

tools/test jest runs our JS unit tests. These are written using Jest.

To write a test, place a Javascript file with the -test.js suffix in the __tests__ directory inside of any subfolder of /src. The test will be automatically picked up by the test runner.

The bulk of our JS code runs the same way on both iOS and Android, but some of it conditions on the platform. By default, tools/test runs our Jest tests just once, picking the platform arbitrarily, to avoid taking twice as long. (See architecture/testing.md for more discussion.) If you're testing code that does depend on the platform, use the --all or --platform option (see tools/test --help for details) to be sure to exercise the case of the relevant platform, or both of them.

Test style guide

  • New test files should be @flow strict-local, just like all our non-test code.

  • Tests should use the exampleData module as needed to produce objects of type User, Message, GlobalState, and our many other data types.

    • This typically allows a test to write out only the details relevant to it -- far less tedious than writing out lots of other properties that the application code expects to exist, but the given test doesn't care about the specific value of.

    • If exampleData doesn't already have code to produce the type you need, add to it.

  • Lots of existing tests aren't marked with @flow. If making substantial changes to a test file, first bring it up to our normal typing standards: add @flow strict-local and make it pass Flow.

    • Most of these tests build example data by hand, and to stay at a bearable level of tedium they leave out a lot of properties the real non-test objects would have, causing type errors.

      To convert such code to well-typed code, you'll want to use exampleData as described above.

  • Use deepFreeze to test functions which access redux state. This won't allow the object to be mutated and hence will eventually fail tests in case of mutation.

Native-code tests:

Android

We have a small, nascent suite of unit tests for our Android-native (Kotlin and Java) code.

tools/test native runs this suite, as well as building all the Android code.

Tests are written in Kotlin, using JUnit 4 and the Truth library. If you're writing Android unit tests:

  • Definitely read the short Android guide on principles of testing -- it's a good writeup.
  • Definitely also read the short Android guide on local unit tests, which has more concrete details about the APIs we use here.
    • (A "local unit test" is Android jargon for a genuine, self-contained unit test, specifically a test that doesn't require an Android device to run on. All our unit tests are "local unit tests".)

Other sources which might be helpful to read or refer to:

iOS

We don't yet have native-code tests for iOS. We should try it out! A good incremental step will be to at least check that the build completes without errors.

Functional tests

Functional tests have not been set up. We plan to use Appium.

Linting

We use ESLint to catch many kinds of style issues, together with Prettier to maintain consistent formatting.

Our lint config starts from the Airbnb guides (for ES6 and for React), with a number of specific changes.

Prettier is an "opinionated" tool, which is a euphemism for having virtually no configuration options; and unfortunately a few of its unchangeable "opinions" are outright harmful. So we use prettier-eslint to overrule it on those points; the details are in a small, formatting-only ESLint config file.

For proper results, always run ESLint or Prettier through our canonical interfaces:

  • tools/test (or tools/test lint prettier for these steps alone);
  • tools/test --fix, to actually modify the files to fix issues where possible; or
  • in your editor, with our recommended editor config.

If you find another interface more convenient, please send a PR and/or mention it in chat! We'll be interested to learn about it, and to see what we can do to support it.

Type checking with Flow

We use the Flow type-checker on our JS code, and flow-typed for community-maintained type definitions for many dependencies.

Flow is not among the world's best-documented software. If you don't find something in its docs, it's worth

  • searching its issues (including closed issues); sometimes a valuable feature is undocumented and the best discussion of it is where someone offers it as a workaround in an issue thread.
  • scanning this "cheat sheet" maintained by another Flow user, which provides an index of features both documented and undocumented.