Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load redux store initial state in Detox Testing

Problem

We have a quite complex application and we don't want in each test case to go through the whole process to get to specific screen to test it, alternatively we just want to jump to specific one with some state stored in redux store.


What I've tried

I made multiple initial states which loads specific screen so I can test it directly and for each run of detox test I load different mocha.opts to select this portion of test cases and used 'react-native-config' so I can load different state in each run so for example for loading a screen I will do the following:

  1. Create initialState for redux store that has all the details of the screen I'm currently testing.
  2. Create mocha.opts to run only this test case by specifying the -f flag in it.
  3. Create .env.test.screenX file which will tell the store which initial state to load according to which ENVFILE I select.
  4. Create different configuration to each screen in detox so it can load the correct mocha opts through the detox CLI.
  5. each time I run the command ENVFILE=env.test.screenX react-native run-ios so the project would be built using this configuration and I can then run the detox test -c .

Question

My method is so complex and require alot of setup and overhead to run test for each screen so I was wondering if any one had the same issue and how could I solve it? In general how can I deal with the react native thread in detox?

like image 433
AFGhazy Avatar asked Mar 16 '18 12:03

AFGhazy


People also ask

How do I set Redux state to initial state?

You can set it at the reducers . Reducers can also set initialState by looking at the incoming state argument (which would be undefined if createStore is not called with initialState ) and returning the values they would like to use as default.

How do you reset state in Redux?

Redux-persist keeps a copy of your state in a storage engine, and the state copy will be loaded from there on refresh. First, you need to import the appropriate storage engine and then, to parse the state before setting it to undefined and clean each storage state key.

Should I keep all component's state in Redux store?

There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state.

What state should I store in Redux?

For the most part if you have a react-redux app I would avoid local state entirely unless you can trying to solve a very component specific problem. For example I would use local state if my component does something on a setInterval and so it is keeping its own timer.


1 Answers

I think there is no way detox can communicate with react native thread in runtime and change state, so I thought of a little hack that uses mocking technique as Leo Natan mentioned, it could be useful in your case

you could mock your App.js file with a screen (App.e2e.js) that has some buttons with known testIDs each button dispatch all the actions needed to load a specific state to store, you can start each test suite by pressing one of the buttons in the beforeEach method then you can start your normal test flow after that

for example:

if you want to test a screen that is far away (requires too many clicks to reach when the user actually use the app) and requires authentication you could have the following structure:

App.e2e.js has 2 buttons:

  • one for authentication that dispatch an action like onAuthenticationSuccess(user, authToken)
  • another one for navigation to that screen this.navigation.navigate("screenName")

test.js

describe("Screen work as intended", () => {
  beforeEach(async () => {
    await device.reloadReactNative();
    await element(by.id("authButtonID")).tap();
    await element(by.id("navigateButtonID")).tap();
  });

  it("should do something", async () => {
    //user is loaded in store
    //current screen is the screen you want to test
  });
});
like image 103
mina sameh Avatar answered Sep 17 '22 21:09

mina sameh