Did you know that Codemagic now supports Linux instances too? Here’s yet another way to build and test React Native apps!
On Linux, you can build Android and other non-Mac workflows more quickly with out-of-the-box support for Android emulators with hardware acceleration. You can specify a Linux build machine by using linux
or linux_x2
as instance type
in codemagic.yaml
.
Linux can only be used in codemagic.yaml
configured workflows, so see the getting started guide or YAML cheat-sheet to migrate over any workflows you want to use on Linux.
Let’s look at how to build and test React Native apps on Linux instances.
Configure React Native Project
For our setup, we will install the Jest testing framework:
npm i jest --save-dev
npm install @testing-library/react-native --save-dev
npm install @react-navigation/native --save-dev
Add the details in the package.json
, as shown below:
"scripts": {
"test": "jest"
},
"jest": {
"preset": "jest-expo",
"setupFiles": ["<rootDir>/testing/jest-setup.js"]
}
Let’s prepare a simple app that has two screens. Your app would look something like this:
import React from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
export const HomeScreen = ({ navigation }) => (
<View style={styles.container}>
<Text>Home Screen</Text>
<Button title="Navigate to Detail Screen" onPress={() => navigation.push('DetailScreen')} />
<StatusBar style="auto" />
</View>
);
export const DetailScreen = () => (
<View style={styles.container}>
<Text>Detail screen</Text>
<StatusBar style="auto" />
</View>
);
const Stack = createStackNavigator();
export const AppStack = () => (
<Stack.Navigator>
<Stack.Screen name="HomeScreen" component={HomeScreen} />
<Stack.Screen name="DetailScreen" component={DetailScreen} />
</Stack.Navigator>
);
Writing Tests for React Native
Scenario 1: The Home Screen is the initial screen of the app, which has navigation enabled. The user is able to navigate to the Detail Screen by tapping on the button.
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import { NavigationContainer } from '@react-navigation/native';
import App, { HomeScreen, AppStack } from './App';
describe('HomeScreen’, () => {
it('navigates on button press', () => {
const push = jest.fn();
const { getByText } = render(<HomeScreen navigation={{ push }} />);
fireEvent.press(getByText('Go to Detail Screen'));
expect(push).toHaveBeenCalledWith(‘Detail Screen');
});
});
Scenario 2: Let’s say you want to check your Detail Screen for a text box that collects users’ emails for a newsletter. Jest will test the selected component in JSON format.
import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
let findTextElement = function(tree, element){
console.warn(tree)
return true;
}
it('Find text element', ()=>{
let tree = renderer.create(
<Home />
).toJSON();
expect(findTextElement(tree, 'email')).toBeDefined();
})
Running Tests for React Native
We will now create a testing setup file called testing/jest-setup.js
:
import 'react-native-gesture-handler/jestSetup';
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
Reanimated.default.call = () => {};
return Reanimated;
});
Testing on a local machine is simple – just go to your terminal and simply run npm test
. This will run the tests you just implemented. You should be able to see an output similar to this:
PASS ./App.test.js
Home Screen
✓ navigates on button press (40ms)
AppStack
✓ renders the correct screen (32ms)
Detail Screen
✓ email field found (94ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.62s, estimated 2s
Ran all test suites related to changed files.
Running Tests on Codemagic
Codemagic is a popular CI/CD solution that offers automated build pipelines to check continuous integration and run tests. To set up your React Native app on Codemagic, you can follow the steps provided here and sign up:
This time, we will build and test our React Native app on a newly available Linux instance. Let’s set up a codemagic.yaml
file to perform this.
workflows:
my-workflow:
name: My workflow name
instance_type: linux # specify linux or linux_2 for Linux instances
max_build_duration: 60
...
scripts:
- name: Install npm dependencies
script: npm install
...
- name: Tests # Insert before the build command
script: npm test
...
- name: Build Android app
script: cd android && ./gradlew assembleRelease
...
Once codemagic.yaml
is updated, you are ready to run your tests and build on Codemagic.
Codemagic can be configured to start the build process automatically after a commit or a pull request using build triggers. For now, we will trigger the build manually to start the tests and build process.
Just click on the “Start new build” button to trigger your build. Now, wait for the build to complete, and it will show you the step results, including the test run.
Conclusion
This is how you can build a React Native app on Codemagic’s Linux instance as well as test your app. Codemagic provides simple, straightforward, out-of-the-box solutions to achieve your tasks of building, testing and publishing apps without hassle.
Links and resources you might be interested in:
Sneh is a Senior Product Manager based in Baroda. He is a community organizer at Google Developers Group and co-host of NinjaTalks podcast. His passion for building meaningful products inspires him to write blogs, speak at conferences and mentor different talents. You can reach out to him over Twitter (@SnehPandya18) or via email (sneh.pandya1@gmail.com).