首页 > 解决方案 > 创建 Redux 多动作集成测试

问题描述

我有一个 Redux 应用程序,我想在其中创建一个集成测试来涵盖一些复杂的交互。下面是我的功能代码,但我想知道是否有更好或更惯用的方法来实现相同的目标。

我的方法如下:

  1. 添加记录每个动作和应用动作后状态的中间件
  2. 在应用程序中手动执行所需的步骤
  3. 将记录的对象数组转储{ action, state }到 JSON 文件中
  4. 运行一个集成测试:
    1. 读取 JSON 文件
    2. 从动作/状态数组中的第一项建立初始状态(忽略第一个动作)
    3. 通过根 reducer 运行每个后续操作以获取新状态,并根据 JSON 文件中记录的值检查新状态

中间件如下所示:

const actionStateTestMiddleware = (store) => (next) => (action) => {
    if (window && !window.actionStateTestLog) {
        window.actionStateTestLog = [];
    }
    if (action) {
        console.log('Logging action ', action.type);
    }
    const result = next(action);
    window.actionStateTestLog.push({
        action,
        state: store.getState()
    });
    return result;
};

测试看起来像:

describe('some integration test', () => {

    let tests;

    before(async() => {
        let buffer;
        try {
            buffer = await fsp.readFile(path.join(
                __dirname,
                '../path/to/integrationTest.json'
            ));
        } catch (err) {
            console.error('Unable to read test case JSON file');
            throw err;
        }
        tests = JSON.parse(buffer.toString());
    });

    it('should maintain the expected state through all actions', () => {
        let state = tests[0].state;

        for (let t = 1; t < tests.length; t++) {
            state = rootReducer(state, tests[t].action);
            assert.deepStrictEqual(state, tests[t].state);
        }
    });
});

上述方法有效,但感觉远非理想。主要问题是:

  1. 开发者必须临时添加自定义中间件
  2. JSON 文件是为每个操作重复的整个存储,因此即使对于有限的测试用例也有大约 50k 行
  3. 任何影响商店任何部分的代码更改都会使此测试无效,因此需要:
    1. 重新运行生成测试的手动过程,尽管再次执行完全相同的步骤是不可行的
    2. 自动从测试用例重新生成 JSON 文件,查看更改的差异,并使用最佳判断来接受或拒绝。对于重大变化,这种差异可能难以理解。

有一个更好的方法吗?

标签: javascripttestingreduxautomated-testsintegration-testing

解决方案


推荐阅读