如何在最新版本中配置 Detox 生命周期挂钩?

Posted

技术标签:

【中文标题】如何在最新版本中配置 Detox 生命周期挂钩?【英文标题】:How to configure Detox lifecycle hooks in the latest version? 【发布时间】:2021-03-15 12:08:29 【问题描述】:

我在17.13.2 版本中运行detoxjest-circus 作为测试运行器。我的主要问题是应用程序在我运行测试之后或之前都没有重置,这导致应用程序的状态不一致。

我的测试文件:

import  by, device, element, expect, waitFor  from "detox"

describe("Login", () => 
  beforeEach(async () => 
    await device.reloadReactNative()
  )

  it("should login with correct data", async () => 
    await element(by.id("login_email_input")).typeText("ch.tietz@gmail.com")
    await element(by.id("login_password_input")).typeText("12345678")
    await element(by.id("login_submit_button")).tap()

    await waitFor(element(by.id("workout_screen"))).toBeVisible()

    // additional test steps

  )
)

现在,如果登录确实有效,但在后续步骤之一中测试失败,则应用用户的状态仍将是“登录”。

据我了解,实际上无法更改应用程序状态,例如通过清除AsyncStorage 或直接与状态管理工具交互。相反,建议重新安装应用程序 - 但这正是我苦苦挣扎的地方。

我尝试了很多方法,但都没有奏效。是什么让configuration is that detox completely changed how the configuration works 变得很难理解并切换到jest-circus 作为主要测试运行者。

我的设置基本上是由jest init -r jest 创建的。据我了解,这已经包含了detox.init()detox.cleanup() 的一些默认值:


  "detox": 
    "behavior": 
      "init": 
        "reinstallApp": true,
        "launchApp": true,
        "exposeGlobals": true
      ,
      "cleanup": 
        "shutdownDevice": false
      
    
  

但是,这似乎不足以在运行测试后实际擦除应用状态。

我尝试使用setupFilesAfterEnv 的初始化脚本,它会在测试套件运行后调用cleanup()。实际上,这适用于仍然使用 jasmine 2 作为测试运行器的旧项目。

import  cleanup, init  from 'detox';
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');

const config = require('../package.json').detox;

// Set the default timeout
jest.setTimeout(120000);

jasmine.getEnv().addReporter(adapter);

// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level.
// This is strictly optional.
jasmine.getEnv().addReporter(specReporter);

beforeAll(async () => 
  await init(config,  launchApp: false );
, 300000);

beforeEach(async () => 
  await adapter.beforeEach();
);

afterAll(async () => 
  await adapter.afterAll();
  await cleanup();
);

首先,它抱怨没有定义茉莉花。我猜那是因为实际上在这种情况下adapter 应该是DetoxAdapterCircus,但它不是,即使在我的配置文件中我指定:


    "preset": "react-native",
    "testEnvironment": "./environment.ts",
    "testRunner": "jest-circus/runner",
    "testTimeout": 120000,
    "testRegex": "\\.e2e\\.ts$",
    "reporters": ["detox/runners/jest/streamlineReporter"],
    "verbose": true

"testRunner": "jest-circus/runner"

另一个想法是更改 CustomDetoxEnvironment,但我不明白如何访问 detox 生命周期挂钩。

const 
  DetoxCircusEnvironment,
  SpecReporter,
  WorkerAssignReporter,
 = require("detox/runners/jest-circus")

class CustomDetoxEnvironment extends DetoxCircusEnvironment 
  constructor(config) 
    super(config)

    // should I access the hooks here now?

    // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
    // This is strictly optional.
    this.registerListeners(
      SpecReporter,
      WorkerAssignReporter,
    )
  


module.exports = CustomDetoxEnvironment

Tl;dr:我不知道在最新版本的 Detox 中将可重复使用的生命周期挂钩放在哪里。另外,我想知道是否甚至需要这些自定义配置来重新安装应用程序并在每个测试套件之前擦除应用程序数据。

【问题讨论】:

【参考方案1】:

你仍然可以使用setupFilesAfterEnv,但你不应该像以前那样调用相同的钩子/清理(参见https://github.com/wix/Detox/issues/2410#issuecomment-744387707)。

下面是我们的初始化脚本示例:

// init.ts
// with "setupFilesAfterEnv": ["./init.ts"] in the conf

beforeAll(async () => 
  // to reset the state
  await device.clearKeychain();

  // we are launching the app manually
  await device.launchApp(
    permissions:  notifications: 'YES', location: 'inuse' ,
  );

  await device.setURLBlacklist([
    // ...
  ]);
);

【讨论】:

以上是关于如何在最新版本中配置 Detox 生命周期挂钩?的主要内容,如果未能解决你的问题,请参考以下文章

如何以角度创建“ngOnActive”生命周期挂钩?

如何在 Jest 单元测试中模拟在 `created` Vue 生命周期挂钩中调用的方法,而不使用`shallowMount` 中已弃用的`methods` 参数? [复制]

模板未获取计算属性的内容,但在生命周期挂钩中记录正常

用于从 Vue 组件中的 Firebase 检索数据的生命周期挂钩

单击元素按钮时是不是会调用 Angular 8 中的生命周期挂钩

自动挂钩到 Activity 生命周期方法的异步任务库