Load redux在排毒测试中存储初始状态

时间:2018-03-16 12:40:36

标签: react-native redux react-redux detox redux-store

问题

我们有一个非常复杂的应用程序,我们不希望在每个测试用例中通过整个过程来到特定的屏幕来测试它,或者我们只想跳转到具有存储在redux存储中的某个状态的特定的一个。

我尝试了什么

我做了多个初始状态,加载特定的屏幕,所以我可以直接测试它和每次排毒测试运行我加载不同的mocha.opts选择这部分测试用例并使用'react-native-config'所以我可以加载不同的状态在每次运行中,例如,为了加载屏幕,我将执行以下操作:

  1. 为redux store创建initialState,其中包含我正在测试的屏幕的所有详细信息。
  2. 通过在其中指定-f标志,创建mocha.opts以仅运行此测试用例。
  3. 创建.env.test.screenX文件,该文件将告诉商店根据我选择的ENVFILE加载哪个初始状态。
  4. 在排毒中为每个屏幕创建不同的配置,以便它可以通过排毒CLI加载正确的mocha opts。
  5. 每次我运行命令ENVFILE = env.test.screenX react-native run-ios所以项目将使用此配置构建,然后我可以运行排毒测试-c。
  6. 问题

    我的方法非常复杂,需要很多设置和开销才能为每个屏幕运行测试,所以我想知道是否有任何人有同样的问题,我怎么能解决它?一般来说,我如何在排毒中处理反应原生线程?

2 个答案:

答案 0 :(得分:4)

我认为排毒无法与运行时的本机线程进行通信并改变状态,因此我想到了一个使用模拟技术的小骇客,如Leo Natan所述,它可能对你的情况有用

您可以使用屏幕(App.e2e.js)模拟您的App.js文件,该屏幕具有一些已知testID的按钮,每个按钮都会调度加载特定状态以存储所需的所有操作,您可以通过以下方式启动每个测试套件:按下beforeEach方法中的一个按钮,然后您可以在此之后开始正常的测试流程

例如:

如果您想测试距离较远的屏幕(当用户实际使用该应用时需要点击次数太多)并且需要身份验证,则可以采用以下结构:

App.e2e.js有2个按钮:

  • 一个用于分发onAuthenticationSuccess(user, authToken)
  • 等操作的身份验证
  • 另一个用于导航到该屏幕的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
  });
});

答案 1 :(得分:0)

如果您使用的是Expo,并且使用release-channels指定环境,则可以执行以下操作:

  1. 创建方法resetStorage,如此处建议的那样: How to reset the state of a Redux store?(您可能已经在logout中实现了)
  2. 在App.js中导入resetStorage方法
  3. 在App.js中添加:import { Constants } from 'expo'
  4. 然后在您的testID="resetStorageBtn"方法中添加一个带有render的按钮,您可以将其用于测试目的,并且在生产发布通道中将不可见。 因此render看起来可能与此类似:

    return (
      <Root>
        {Constants.manifest.releaseChannel !== 'production' &&
            (<View>
              <Button onPress={() => resetStorage()} testID="resetStorageBtn">
                <Text>Reset storage</Text>
              </Button>
            </View>
          )}
        <View>
          <AppNavigator />
        </View>
      </Root>
    );