使用Jest快照测试api

你知道什么很烦人吗?API不匹配。 有一天,后台开发人员在没有通知前端开发人员的情况下更改了其中一个api。“我们认为dateCreated这个名字比created_at更好,”他们说。“我们昨天在单口相声会上不是告诉过你吗?” 然后,一切都崩溃了。 有涵盖UI代码的单元测试。有涵盖后端代码的单元测试。所有这些都已经过去了。然而,这个应用程序已经坏了。 在这篇文章中,我们将介绍如何使用Jest编写API测试,使用很少的代码,从而避免这种混乱。 没有端到端测试 缺少的是一组检查前端和后端是否正确集成的测试。 这些被称为端到端测试或验收测试,它们通常在浏览器级别上完成。像Selenium、Nightwatch或Capybara这样的工具可以驱动一个无头浏览器来登录、点击、填写表单,并确保一切正常运行。 但是,端到端(E2E)测试存在一些问题——它们速度慢、容易出错和脆弱。编写好selenium样式的浏览器自动化是需要技巧的。狡猾的计时错误可能会潜入,导致测试间歇失败。 如果测试显示: 加载用户配置文件页面并断言标记具有文本用户配置文件 如果你把它改成an,测试就会失败。 因此,在编写这样的测试时需要一种很好的平衡——您需要足够好的断言来验证功能,但又不需要太过具体,当您引入额外的命令时它们就会崩溃。什么的。 一个折衷方案:快照API测试 Facebook的Jest工具支持一种称为快照测试的测试方式,基本上: 您可以手动验证代码是否正常工作。编写一个快照测试并运行它。它保存了事物的文本表示。将快照签入源代码控制。之后,每次运行测试时,都会根据磁盘上的旧快照验证结果。如果它们不匹配,测试就会失败。 这通常应用于React组件(您可以在这里读到关于快照测试React组件的内容),但是可以获取任何内容的快照。任何JS对象都可以快照。 也就是说,你可以: 为结果做一个API调用快照,知道如果API快照通过,你的UI和后端是一致的 注意事项 如果您以前编写过单元测试,那么您可能已经模拟了API,使其不进行任何调用。在这些测试中,我们将其颠倒过来。我们希望对真实的服务器进行真实的API调用。 这意味着您需要运行一个后端服务器来运行这些测试。这有点复杂,但在贸易中,你会更有信心。 您还需要了解测试数据库,并确保在执行类似“创建3个事务,并验证GET /transactions返回3个事务”这样的操作之前,将其重置为一个已知的状态。在不清理数据库的情况下运行两次,测试将失败。 我不会在这里深入讨论如何设置所有这些,因为它将在很大程度上依赖于您自己的后端设置、CI设置等。 如果您决定尝试这种方法,请从简单的开始:针对“登录”或“创建”之类的内容编写测试,这些内容将对脏数据库具有弹性。如果您喜欢这种方法,那么您可以考虑解决数据库/CI/等问题。 例子 测试登录 这里有一些测试的理论“登录”服务: 隐藏,收缩,复制Code

import * as API from 'api';

test('failed login (bad password)', async () => {
  let data;
  try {
    data = await API.login('[email protected]', 'wrong_password');
    fail();
  } catch(e) {
    expect(e.response.data.error).toMatchSnapshot();
  }
});

test('failed login (bad username)', async () => {
  let data;
  try {
    data = await API.login('[email protected]', 'password');
    fail();
  } catch(e) {
    expect(e.response.data.error).toMatchSnapshot();
  }
});

test('good login', async () => {
  try {
    const response = await API.login('[email protected]', 'supersecret!');
    expect(response).toMatchSnapshot();
  } catch(e) {
    fail();
  }
});

这些测试利用异步/等待使代码读取更像同步代码。 这里并没有发生太多奇妙的事情:每个测试都进行一个API调用,并断言结果(或错误)与快照匹配。 请记住,在第一次运行快照测试之前,必须验证API调用是否在工作。它们通常会与测试JS文件一起保存在其余的snapshots__文件夹中,所以你也可以检查它们的正确性(你也应该这样做)。 测试变化的事物 有时API响应可能包含一个自动递增的ID或时间戳。这些事情将导致快照测试每次都失败。 为了解决这个问题,下面是一个sanitize函数的示例,该函数接受一个对象和一个要进行sanitize的键数组。因为它使用了lodash的set函数,所以键可以引用“深层”属性,比如user.orders[0]。created_at如果必要的话。 隐藏,复制Code

import * as _ from 'lodash';
import * as API from 'api';

function sanitize(data, keys) {
  return keys.reduce((result, key) => {
    const val = _.get(result, key);
    if(!val || _.isArray(val) || _.isObject(val)) {
      return result;
    } else {
      return _.set(_.cloneDeep(result), key, '[SANITIZED]');
    }
  }, data);
}

test('createOrder', async () => {
  let order = await API.createOrder('Camera', 47, 19.84);
  order = sanitize(order, ['id', 'created_at']);
  expect(order).toMatchSnapshot();
});
code>

试试 我只是刚刚开始在我自己的项目中实现这种测试方法,但到目前为止它似乎很有前途。试一试吧,如果你这么做了,请留下评论。:) Jest快照测试api最初由Dave Ceddia于2017年9月18日在Dave Ceddia上发布。 CodeProject上 本文转载于:http://www.diyabc.com/frontweb/news29970.html

你可能感兴趣的:(使用Jest快照测试api)