Recently I decided to write tests for my expo react native app written in typescript. Having done this in Reactjs, I didn't expect its native counterpart to be such a pain. I did the usual reading of documentations, checking StackOverflow and there was nothing. I couldn't find any working test or a proper documentation for setting up tests for expo react native apps written in typescript. I must add that I initialised my expo app using a blank template. Using either the tabs or the minimal template automatically sets up test for you (I learnt this much matter).
Luckily after about 2 weeks, I came across an npm package expo-template-typescript-jest [https://www.npmjs.com/package/expo-template-typescript-jest] created by [https://github.com/elgsantos]
It seemed like it was recently put there as an answer to my prayer. I had to take it for a spin. Ah!! yes it worked. Also, seeing that I didn't want to use its template, I had to study the repo and replicate the configurations used in my already existing expo app.
let me walk you through how I added jest and react-test-renderer to my already existing expo app in 4 simple steps.
LIST OF DEPENDENCIES USED
1) React-test-renderer
2) jest
3) jest-expo
4) ts-jest
5) jest-coverage-badges
6) @types/jest
7) @types/react-test-renderer
STEPS:
1) Install all the listed dependencies above best with --save-dev flag to see these in your devDependencies.
2) Add a jest configuration file.
//jest.config.js
module.exports = {
testEnvironment: "jsdom",
preset: "jest-expo",
globals: {
"ts-jest": {
tsconfig: {
jsx: "react",
},
},
},
transform: {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
"^.+\\.tsx?$": "ts-jest",
},
testMatch: ["**/?(*.)+(spec|test).ts?(x)"],
collectCoverageFrom: [
"**/*.{ts,tsx}",
"!**/coverage/**",
"!**/node_modules/**",
"!**/babel.config.js",
"!**/jest.setup.js",
],
moduleFileExtensions: ["js", "ts", "tsx"],
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|sentry-expo|native-base)",
],
coverageReporters: ["json-summary", "text", "lcov"],
})
3) Add "esModuleInterop": true to your tsconfig.json file. Your final configuration file should look like the one below.
//tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"jsx": "react-native",
"lib": ["dom", "esnext"],
"moduleResolution": "node",
"noEmit": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"strict": true,
"esModuleInterop": true
}
}
4) Add scripts for running your tests in different modes in your package.json.
//package.json
"test": "jest",
"test:watch": "npm run test --watch",
"test:ci": "npm run test --coverage",
"test:badges": "npm run test:ci && jest-coverage-badges --input coverage/coverage-summary.json --output __badges__"
Now we can go ahead to check if this works
I will have two files here: App.tsx and App.test.tsx
1) App.tsx
//App.tsx
import { StatusBar } from "expo-status-bar"
import React from "react"
import { StyleSheet, Text, View, Image } from "react-native"
export default function App() {
return (
<View style={styles.container}>
<Image
source={require("./assets/adaptive-icon.png")}
style={styles.logo}
/>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
logo: {
width: 120,
height: 120,
margin: 10,
},
})
2) App.spec.tsx
//App.spec.tsx
import React from "react"
import renderer from "react-test-renderer"
import App from "./App"
describe("<App />", () => {
it("has 2 child", () => {
const tree: any = renderer.create(<App />).toJSON()
expect(tree?.children?.length).toBe(2)
})
})
You can go ahead and test with npm run test.
To have a better overview of the code and template used here, you can check out the repo below.
elgsantos / expo-template-typescript-jest
🔥 A React Native Template using Expo, Typescript and Jest
React Native Template Expo Typescript with Jest
A React Native Template using Expo, Typescript and Jest
Explore the docs »
Report Bug
·
Request Feature
Table of Contents
Table of Contents
About The Project
This template was developed to facilitate the creation of a new project using Expo, React Native and Jest.
Built With
Getting Started
To get this template up and running follow these simple steps.
Prerequisites
Installation
Create a project with this template:
expo init --template expo-template-typescript-jest
(It will prompt you to enter a project name)
Usage
- Navigate to the created directory
- Start the project:
yarn start
- Then develop your app, creating files
.tsx
for React Native components and.ts
for plain typescript files.
Testing
There are some…
Top comments (2)
As now (Jun 3 2022) some packages are to be installed,
jest-environment-jsdom is no more shipped by default it will be required to install as a dev dependency also metro-babel-register, hence it will cause a Validation Error: Test environment jest-environment-jsdom cannot be found. Make sure the testEnvironment configuration option points to an existing node module.
or "Cannot find module 'metro-babel-register'".
Tip: Consider updating this Article @ajulibe .
Thank you so much! I have been looking everywhere about this and your article finally made jest work for my project.