React 测试笔记 01 - 基础 UI 类

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React 测试笔记 01 - 基础 UI 类相关的知识,希望对你有一定的参考价值。

React 测试笔记 01 - 基础 UI 类

依稀记得去年找 Hooks 开发的时候还没这么多资料,感觉大半年过去之后科技立马跟上,@testing-library/react 已经成了 CRA 的内置包了……

别卷了,卷不动了.jpg

不过 React Testing Library 结合 jest-dom 确实提供了很多非常方便的测试函数,之后的需求也是项目需要更加正式一点,除了开发之外还要包含测试,那就……学起来吧。

基础 UI 测试

在测试文件中实现以下内容:

import  fireEvent, render, screen  from "@testing-library/react";

test("basic test", () => 
  render(<Component />);

  const btn = screen.getByRole("button",  name: /submit/i );
);

就能获得一个可以用来测试的 button 元素。

除了 getByRole 之外,React Testing Library 还提供了其他的 query 方法,包括 getByLabelText, getByPlaceholderText 等,具体内容可以看 About Queries 中列举的所有 queries。

getByRole 中接受的是 ARIA roles,这个定义不是出自 React Testing Library,具体的 roles 也可以在 MDN ARIA 文档 中找到。

第二个参数 name 是 W3C 定义的 Accessible Name,具体文档在 Accessible Name and Description Computation 1.1,比较通俗一点的理解就是 非自闭元素中的内容。以 const btn = screen.getByRole("button", name: /submit/i ); 为例,所渲染的 React Component 中必须要包含一个 <button>Submit</button>,否则就会报错:

注 1*: 这样对于 语义化(semantic) 的要求就更高了,尤其是在很多内容可能需要动态渲染的情况下,添加合适的 altText 之类 accessibility 和 usability 的要求会提升很多。

注 2*:一旦遇到报错信息,Test 会终止继续运行测试,即,不会执行剩下 test('', () => ) 中的代码,如:

其他 test() 和 test Suite 不受影响。

通过返回 Element 中提供的函数,如:

  • fireEvent

    这是一个交互函数,用法有两种:

    // 传入两个参数
    fireEvent(node: htmlElement, event: Event)
    
    // 或者
    fireEvent.click(node);
    

    第一种适合比较复杂的业务场景,或是有很多功能相同的 onclick 事件:

    const myEvent = createEvent.click(node,  button: 2 );
    fireEvent(node, myEvent);
    

    第二种比较适合只是需要触发某个点击事件,如:

    expect(btn).toBeEnabled();
    
    fireEvent.click(btn);
    
    expect(btn).toBeDisabled();
    
  • toBeEnabled() & toBeDisabled()

    用法上面有所展示

  • toHaveStyle()

    可以用来测试 CSS,如:

    expect(colorButton).toHaveStyle( backgroundColor: "blue" );
    
  • …其他

    这部分的功能由 jest-dom 提供,具体文档在 Custom matchers 中有列举。掐指一算有这么三四十个,完整的列一遍不太现实,之后边用边查边记录吧。

React Testing Library 结合 jest-dom 这样就可以完成比较基础的 UI 和功能测试。

一点测试代码

目前在写的简单测试:

import  fireEvent, render, screen  from "@testing-library/react";
import Page from "./index";

const initialization = () => 
  render(<Page />);

  return 
    btn: screen.getByRole("button"),
    check: screen.getByRole("checkbox"),
  ;
;

describe("Test click btn to enable/disable checkbox", () => 
  test("test checkbox check func", () => 
    const  btn, check  = initialization();

    expect(check).not.toBeChecked();

    fireEvent.click(btn);

    expect(check).toBeChecked();
  );
);

因为在做 TDD 的尝试,所以就是一片红:

Page 实现的代码为:

import React from "react";

const Page = () => 
  return (
    <>
      <button>Submit</button>
    </>
  );
;

export default Page;

因此 btn 是能够找到的,但是找不到 checkbox.

这个报错信息是我使用的另一个插件(需要付费我就不安利了)生成的,如果用 jest --watchAll 的话显示的报错信息也是一样。

TDD 的需求在于,先写完测试,根据测试去实现功能,这样不会 diverge 到其他自己脑袋一拍的需求(因为要写更多测试所以根本懒得做吧……)。

测试的一些 update

懒得继续修改了,所以这里更新一下修正的测试代码:

import  fireEvent, render, screen  from "@testing-library/react";
import Page from "./index";

const initialization = () => 
  render(<Page />);

  return 
    btn: screen.getByRole("button"),
    check: screen.getByRole("checkbox"),
  ;
;

describe("Checkbox & Btn interaction", () => 
  test("click btn enable/disable checkbox", () => 
    const  btn, check  = initialization();

    expect(check).toBeEnabled();
    fireEvent.click(btn);
    expect(check).toBeDisabled();

    fireEvent.click(btn);
    expect(check).toBeEnabled();
  );
);

这样才实现点击 btn 之后 enable/disable checkbox 的功能。

一些之后再看的需求

以上是关于React 测试笔记 01 - 基础 UI 类的主要内容,如果未能解决你的问题,请参考以下文章

react-router 学习笔记

react-router 学习笔记

React笔记2

React笔记2

材料UI。在React类组件中使用主题

react.js 各种小测试笔记