Skip to content

Commit

Permalink
feat: unit testing infrastructure for mobile app (#1832)
Browse files Browse the repository at this point in the history
Add unit testing (distinct from integration/snapshot testing) to the application, improve organization of test code, and add documentation of testing setup to readme. Unit tests can be run with npm run test:unit, others can be run with npm run test:integration. npm run test is still a supported command, which runs both test projects.

Also add basic unit testing for some color computation code, and do some refactoring supported by those tests.
  • Loading branch information
tm-ruxandra authored Jul 23, 2024
1 parent bb9551d commit e903fcc
Show file tree
Hide file tree
Showing 34 changed files with 543 additions and 63 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,21 @@ Once all of the dependencies are installed, you'll need to do the following to e
- See the `settings.py` value `JWT_EXCHANGE_PROVIDERS`. You will need to set the environment variable `GOOGLE_MOBILE_CLIENT_ID`
5. Set up mobile config to connect to backend
- See [Android emulator networking](https://developer.android.com/studio/run/emulator-networking.html) for details on how to connect to your backend instance

# Testing

We use Jest for testing. Project tests are partitioned into **unit** (fast, no external dependencies), and **integration** (slow, may rely on disk access or network calls etc). You can run unit tests with `npm run test:unit` and integration tests with `npm run test:integration`; run all tests with `npm run test`. Tests are run automatically on GitHub and must pass for a PR to be eligible for merging.

### Configuration

Unit and integration tests have their own Jest configuration files to reflect their needs. Unit tests are covered by the `jest.unit.config.js`, while integration tests are covered by `jest.integration.config.js`. The `jest` section of `package.json` lists these both as projects for Jest to run, which is how `npm run test` runs them all.

Unit tests are written inline in `src` and should live parallel to the source files they cover. Unit tests must be suffixed with `.test.ts/tsx/js/jsx` for the test runner to recognize them.

Integration tests exist separately in `__tests__`. Any file containing test definitions in this directory will be picked up by the integration test runner.

Additionally, both suites of tests have access to the `jest` directory, which contains utility and common setup code. This directory is mapped to the `@testing` import path via `jest` configuration.

### Snapshot tests

A subset of our integration tests are **snapshot tests**, which are organized under `__tests/snapshot`. These run application screens in a stubbed-out test harness and compare the resulting React Native DOM tree against one stored in a corresponding snapshot file, highlighting any differences. If a snapshot needs to be updated as a result of a change, you can run `npm run test -- -u` to automatically update them from the results of a test run.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import {testState} from '@testing/data';
import {render} from '@testing/utils';
import {testState} from '@testing/integration/data';
import {render} from '@testing/integration/utils';

import {CreateProjectScreen} from 'terraso-mobile-client/screens/CreateProjectScreen/CreateProjectScreen';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {render} from '@testing/utils';
import {render} from '@testing/integration/utils';

import {CreateSiteScreen} from 'terraso-mobile-client/screens/CreateSiteScreen/CreateSiteScreen';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import {testState} from '@testing/data';
import {render} from '@testing/utils';
import {testState} from '@testing/integration/data';
import {render} from '@testing/integration/utils';

import {LocationDashboardScreen} from 'terraso-mobile-client/screens/LocationScreens/LocationDashboardScreen';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {render} from '@testing/utils';
import {render} from '@testing/integration/utils';

import {LoginScreen} from 'terraso-mobile-client/screens/LoginScreen';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import {testState} from '@testing/data';
import {render} from '@testing/utils';
import {testState} from '@testing/integration/data';
import {render} from '@testing/integration/utils';

import {ProjectViewScreen} from 'terraso-mobile-client/screens/ProjectViewScreen';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {testState} from '@testing/data';
import {render} from '@testing/utils';
import {testState} from '@testing/integration/data';
import {render} from '@testing/integration/utils';

import {methodRequired} from 'terraso-client-shared/soilId/soilIdSlice';
import {collectionMethods} from 'terraso-client-shared/soilId/soilIdTypes';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import {testState} from '@testing/data';
import {render} from '@testing/utils';
import {testState} from '@testing/integration/data';
import {render} from '@testing/integration/utils';

import {SoilScreen} from 'terraso-mobile-client/screens/SoilScreen/SoilScreen';

Expand Down
37 changes: 37 additions & 0 deletions dev-client/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

module.exports = {
displayName: 'integration',
testMatch: ['**/__tests__/**/*[.-]test.[jt]s?(x)'],
preset: 'jest-expo',
setupFilesAfterEnv: [
'@testing-library/jest-native/extend-expect',
'@rnmapbox/maps/setup-jest',
'./node_modules/react-native-mmkv-storage/jest/mmkvJestSetup.js',
'<rootDir>/jest/integration/setup.ts',
],
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|react-native-cookies|uuid|react-native-mmkv-storage|react-native-autocomplete-input|expo(nent)?|@expo(nent)?/.*)|expo-constants|@rnmapbox/)',
],
moduleNameMapper: {
'\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.ts',
'^@testing/(.*)': '<rootDir>/jest/$1',
'^terraso-mobile-client/(.*)': '<rootDir>/src/$1',
},
};
31 changes: 31 additions & 0 deletions dev-client/jest.unit.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

module.exports = {
displayName: 'unit',
testMatch: ['**/src/**/*.test.[jt]s?(x)'],
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/jest/unit/setup.ts'],
clearMocks: true,
moduleNameMapper: {
'\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.ts',
'^@testing/(.*)': '<rootDir>/jest/$1',
'^terraso-mobile-client/(.*)': '<rootDir>/src/$1',
},
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions dev-client/jest/unit/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

// fill me in if you need special config for unit testing
Loading

0 comments on commit e903fcc

Please sign in to comment.