Introduction to writing automated tests for Airtable Extensions
Support for automated testing is currently in open beta.
Implementation status
Not all operations are currently supported. In the course of writing tests, authors may find that
the Extension under test does not function as intended when induced to perform these operations.
Authors may request support from the SDK maintainers or implement the functionality they need as
part of their work (this document includes guidance on extending the testing API in a subsequent
section).
The following table describes the implementation status of each operation.
| Table - create | partial [1] | |
| Table - update | partial [1] | |
| Table - destroy | | :heavy_check_mark: |
| Field - create | partial [1] | |
| Field - update | partial [1] | |
| Field - destroy | | :heavy_check_mark: |
| View - create | | |
| View - update | | |
| View - destroy | | :heavy_check_mark: |
| Global Config - update | :heavy_check_mark: | n/a [2] |
| Cursor Data - update | | :heavy_check_mark: |
| Session Data - update | | |
| User permissions - update | :heavy_check_mark: | :heavy_check_mark: |
| click settings button | | |
| toggle full screen | | |
| expand record | | :heavy_check_mark: |
| Record - create | partial [3] | n/a [2] |
| Record - update | :heavy_check_mark: | n/a [2] |
| Record - destroy | :heavy_check_mark: | n/a [2] |
- [1] While the SDK's public API supports these operations, its capabilities are restricted.
Ideally they would be complemented by a more powerful testing API.
- [2] These operations can be initiated using the SDK's public API.
- [3] Unsupported operations: creating records for tables which have not yet been loaded,
creating records with data for fields which have not yet been loaded,
and creating records in specific views
Key concepts
Test fixture data is a representation of the state of an Airtable Base, including descriptions
of Tables, Views, Fields, and Records. It is written by test authors and in terms of
JSON-serializable values.
The Extension Test Fixtures Airtable Extension
allows developers to generate this data from the state of an authentic Base. This Extension is not
ready for beta yet.
TestDriver is the JavaScript interface for creating and manipulating a simulated Airtable
Extensions environment. It implements methods for performing operations which are not available in
the SDK.
AirtableInterface is the layer of the SDK which mediates between the models and the backend.
In production environments, it operates via asynchronous message passing with the Extension's parent
web browser frame. In testing environments, no transmission occurs, but the AirtableInterface
behaves as though it is receiving relevant messages in order to simulate production behavior.
Mutations are instructions which describe changes to the Base. Mutations travel through the
AirtableInterface, which sends them to the backend in production environments only.
Writing tests
As of January 2021, Airtable Extensions must be written using the React framework. These
instructions take the presence of React for granted.
Every test file must import TestDriver through the @airtable/blocks-testing module to ensure that
the environment is correctly instrumented for automation.
Each test will typically perform the following steps:
-
Create a TestDriver instance, providing valid fixture data:
const testDriver = new TestDriver({
});
-
Create an instance of the Extension under test by rendering the Extension's Component as a child
of the TestDriver#Container Component.
render(
<testDriver.Container>
<MyExtension />
</testDriver.Container>,
);
-
Provide some input to the Extension. This may be in the form of a simulated user interaction
(e.g. via
the @testing-library/user-event library)
const input = screen.getByLabelText('Cheeses');
const option = screen.getByText('Gruyere');
userEvent.selectOptions(input, [option]);
...or a simulated backend behavior (e.g. via
the Blocks SDK or the TestDriver API).
await testDriver.base.createTableAsync('a new table', [
{name: 'address', type: FieldType.EMAIL},
]);
-
Verify that the Extension responded to the input as expected. For many kinds of interactions,
the Extension's response will be discernible by some change in the UI.
The @testing-library/react library is
a good choice for inspecting the state of the user interface.
const checkbox = screen.getByRole('checkbox');
expect(checkbox.checked).toBe(true);
...while the TestDriver API can be used to verify Extension behaviors which do not influence
the UI:
const recordIds = [];
testDriver.watch('expandRecord', ({recordId}) => recordIds.push(recordId));
expect(recordIds).toEqual(['reca']);
The automated test suite for the To-do List example Extension
demonstrates this pattern.
Extending the Testing API
In order to provide predictable behavior, the Airtable testing platform relies on simulations of
Base operations. Every simulation requires some amount of support in the testing platform. Some
simulations also require a dedicated testing API.
Implementing internal support Every Base operation requires some amount of simulation code in
order to support scripting in test environments.
For some operations, this simulation may be as limited as a "no-op" implementation of an internal
method. These operations include mutations which the SDK applies optimistically and messages with no
direct effect on the Extension.
Other operations will require more advanced simulation logic. Operations of this type generally rely
on the backend's response to determine their effect on the Base. The simulated behavior should be
predictable, mimicking the expected response in production.
Implementing a dedicated API A dedicated testing API is not necessary for any operation which
can be expressed through the public API of the SDK (e.g. "create many records" or "delete a table").
When a test author wishes to script such an operation, they should use the SDK directly. This is
valid because an Extension cannot distinguish between operations initiated by the backend and
operations initiated by a test script using the SDK.
Many other operations cannot be expressed via the public API of the SDK. The TestDriver API must
be extended to allow test authors to simulate these operations.
Some of these restrictions are circumstantial, owing to the fact that as of January 2021, the SDK is
incomplete and under active development. This includes an API to delete a Field. Other restrictions
are fundamental to the design of the Extensions platform. For instance, the SDK intentionally omits
a method for an Extension to change the permissions of the current user. This distinction may inform
the decision to introduce a testing API, since doing so will increase maintenance responsibilities
in a way that may be obviated by future extensions to the SDK's public API.