@testing-library/react TDD,react-bootstrap:这种测试有用还是只是时间宽松

Yoa*_*amb 6 tdd reactjs jestjs react-bootstrap react-testing-library

我尝试用 TDD 视图编写代码,我一直遇到同样的问题,我应该测试什么,不应该测试什么,目标是使用 TDD 制作一个基于 React-bootstrap 的导航栏,我的组件将只是一个具有较少属性的包装器,以使其变得简单,我从react-bootstrap中Navbar的品牌子组件开始。最终目标是测试反映用户应该测试的内容,例如导航中存在具有良好 src 和 alt 属性的品牌徽标 img。

这些测试有趣还是应该避免?

我的测试

import React from 'react';
import { render } from '@testing-library/react';
import BrandNav from './BrandNav';

test('testing brand navigation', () => {
    const altProp = 'message to show if image unavailable',
        srcProp = 'relativeFilePath',
        host = window.location;

    const { getByAltText } = render(<BrandNav alt={altProp} src={srcProp} />);

    const brandLogo = getByAltText(altProp);
    expect(brandLogo.src).toEqual(`${host}${srcProp}`);
});
Run Code Online (Sandbox Code Playgroud)

我的组件

import React from 'react';
import { Navbar } from 'react-bootstrap';

const BrandNav = ({ alt, src }) => {
    return (
        <Navbar.Brand>
            <img alt={alt} src={src} />
        </Navbar.Brand>
    );
};

export default BrandNav;
Run Code Online (Sandbox Code Playgroud)

hel*_*joe 5

React 测试大致分为两类:

  1. 断言您的组件已正确连接在一起
  2. 断言您的组件正确处理内部逻辑

您的测试属于第一类,因为它确保您将 props 正确传递给底层 HTML 元素。当您将道具传递到不止一层时,它通常更有价值,但这是一个很好的测试。这是非常基本的,但它不应该妨碍,并且作为 TDD 过程的一部分编写这样的测试是有意义的。

如果您发现某个测试的弊大于利,您可以随时将其删除。

第二种类型的测试的示例如下:

// BrandNav.js
const BrandNav = ({ alt, src, textOnly }) => {
    return (
        <Navbar.Brand>
            {textOnly ? <span>My Brand</span> : <img alt={alt} src={src} />}
        </Navbar.Brand>
    );
};

//BrandNav.test.js
test('shows only image when textOnly is FALSE', () => {
    const altProp = 'message to show if image unavailable';
    const srcProp = 'relativeFilePath';

    const { getByAltText, queryByText } = render(
      <BrandNav
        alt={altProp}
        src={srcProp}
        textOnly={false}
      />
    );

    const brandLogo = getByAltText(altProp);
    expect(brandLogo.src).toMatch(srcProp);
    expect(queryByText('My Brand')).toBeFalsy();
});

test('shows only text when textOnly is TRUE', () => {
    const altProp = 'message to show if image unavailable';
    const srcProp = 'relativeFilePath';

    const { queryByAltText, queryByText } = render(
      <BrandNav
        alt={altProp}
        src={srcProp}
        textOnly
      />
    );

    expect(queryByAltText(altProp)).toBeFalsy();
    expect(queryByText('My Brand')).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)

同样,这非常简单,但是随着逻辑变得更加复杂,它会告诉您您的组件仍然正常工作,并且如果您首先构建组件测试,那么这肯定是有意义的。

编辑:在尝试决定应该编写多少测试时要考虑的其他一些因素(这可能有助于回答您的第二个问题):

1. 该项目的使用范围有多大?如果这是一个个人项目,您可能不需要那么多测试。如果您正在编写一个供其他人使用的库,您将需要更高的测试覆盖率。例如,他们的 GitHub 存储库react-bootstrap中有很多简单的测试。他们想知道是否有任何部件出现故障,甚至是最小的单元,因为许多人都依赖其组件正常工作。您还可以看到他们的测试涵盖了您所询问的一些内容(“存在测试品牌”),因此您无需编写测试来涵盖这一点。

2. 您对编写测试的总体熟悉程度如何?如果您刚刚学习编写测试,我认为编写这样的简单测试是有价值的,原因如下:

A. 你会更加熟悉测试库 B. 你可能最终会编写一些太多的测试,感受到这个痛点,并知道将来可以避免哪些测试。

测试不仅仅对于覆盖范围有用。我现在找不到它,但在另一篇 StackOverflow 帖子中有一段令人难忘的引言,大意是:“TDD 的好处是不需要进行一堆测试。这是一个很好的副作用。TDD 的好处是拥有设计更简洁的代码。”

您编写测试的经验越多,您就越知道要避免什么。用 Kent Beck(《实例驱动开发》的作者)的话来说,“我并不总是为非常小的步骤编写测试,但是当事情变得奇怪时,很高兴知道我可以。”