本篇使用的JavaScript 框架是Jest,所以在开始前要先了解一些Jest 基本语法,才会比较快理解喔!
虽然Jest 本身有提供很多测试方法,但在测试上都比较偏向逻辑测试,像是a + b 是否等于c。而实际上我们所需要的测试有一大部分也包含UI 的测试,像是画面上有没显示正确文字,或是使用者点击有没有跳出视窗等等,这时候就是Testing Library出马的时候了!
它的官网介绍就很明确地告诉你
The @testing-library family of packages helps you test UI components in a user-centric way.
也就是@testing-library 系列的套件可以帮助你以用户为中心的方式测试UI 元件。
Testing Library 不只提供可以共通使用的测试套件,还有专为各个框架所出的套件,基本的三大框架react、vue、angular 都有属于他们的测试UI 套件。而比较新的框架像是Preact、Svelte 也都有在持续更新。
以React 来说,搭配Jest 会需要的Testing Libary 有以下几个:
1. @testing-library/react - 模拟React 渲染,Ex:render、screen
2. @testing-library/jest-dom - 扩充jest 的断言库,Ex:toBeInTheDocument、toHaveClass
3. @testing-library/user-event - 模拟使用者操作,Ex:useEvent.click、userEvent.type
接下来来各别介绍这三个的使用时机:
主要是提供模拟渲染UI 画面的函式,比较常用的有
就如同React 中的render,就是模拟渲染React 元件,假设有一个<Home/>元件:
export const Home = () => {
return <h1>Home Page</h1>
};
要测试元件的DOM 元素时,就可以使用render()函式。
import { render } from '@testing-library/react'
describe('testing home component', () => {
it('show Home Page in the home component', () => {
const {getByText} = render(<Home/>);
expect(getByText('Home Page')).toBeTruthy(); //使用 getByText 判斷抓到文字的元素是否存在
});
});
render() 函式会回传一个物件包含一些属性对象:
Query:getBy、queryBy、findBy、getAllBy、queryAllBy、findAllBy,取得元件内的元素。
container:渲染的DOM 节点。
debug:侦错函式,可以显示当前的DOM 结构。
rerender:重新渲染元件。
unmount:取消渲染。
Query 有很多不同的取元素方法,有get、find、query,各自都有取得多元素的all 方法
Query 种类\结果 | 没有符合 | 一项符合 | 大于一个符合 | 是否为非同步函式 |
getBy... | Throw error | 回传元素 | Throw error | ❌ |
queryBy... | 回传null | 回传元素 | Throw error | ❌ |
findBy... | Throw error | 回传元素 | Throw error | ✅ |
getAllBy... | Throw error | 回传阵列元素 | 回传阵列元素 | ❌ |
queryAllBy... | 回传[] | 回传阵列元素 | 回传阵列元素 | ❌ |
findAllBy... | Throw error | 回传阵列元素 | 回传阵列元素 | ✅ |
看起来很容易搞混,不过他们都有各自使用的时机
getBy...:大部分都可以使用,判断元素是否存在。
queryBy...:因为找不到会回传null的特性,所以常用来判断元素是否一开始不存在。
findBy...:非同步函式,可以判断需等待的元素是否存在,例如api 回传才会显示在画面上。
虽然render()解决了模拟UI 的情况,不过只能根据render()的内容进行测试,如果有多个render()函式测起来就会比较麻烦,这时候就可以使用screen()。
其实screen()算是@testing-library/dom 所提供,而所有框架的@testing-library 底层都有@testing-library/dom,所以这边才可以直接做使用。
而screen()所抓取的元素是<body></body> 内的所有DOM 元素。
import { render, screen } from '@testing-library/react'
describe('testing home component', () => {
it('show Home Page in the home component', () => {
render(<Home/>);
render(<Home/>);
expect(getAllByText('Home Page')).toBeTruthy(); //使用 getAllByText 一次判斷兩個 Home 元件元素是否存在
});
});
个人在抓元素时是比较常用 screen()胜过于使用render()回传的方法,使用起来也比较方便。
顾名思义就是去模拟客制化的React Hook,假设今天有一个计数器的customhook
import { useState } from 'react';
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return { count, increment, decrement };
}
export default useCounter;
要测试这个hook 就可以使用renderHook(),他可以传入两个参数,第一个就是要测试的函式,第二是传入函式的参数(非必要)。
import useCounter from './useCounter';
import { renderHook, act } from '@testing-library/react';
it("should increment and decrement the counter", () => {
const { result } = renderHook(useCounter);
expect(result.current.count).toBe(0);
act(() => {
result.current.increment(); // 呼叫 + 1 函式
});
expect(result.current.count).toBe(1);
act(() => {
result.current.decrement(); // 呼叫 -1 函式
});
expect(result.current.count).toBe(0);
});
renderHook()会回传一个物件,可以使用result属性利用 result.current去操控函式的回传物件。
如果有更改state的操作,就需要使用act包起来,这样才可以即时更新state的状态。
@testing-library/jest-dom 提供给Jest 很多DOM 元素的扩充判断,让我们在抓元素时,有更多的方法去测试,比较常用的像是toBeInTheDocument、toHaveClass等等。
以刚刚的<Home/>渲染测试为例
import { render } from '@testing-library/react'
describe('testing home component', () => {
it('show Home Page in the home component', () => {
const {getByText} = render(<Home/>);
expect(getByText('Home Page')).toBeInTheDocument(); //判斷元素是否存在於 Document
});
});
或是
import { render } from '@testing-library/react'
describe('testing div', () => {
it('test div classname is hide', () => {
render(<div className='hide'>test</div>);
expect(screen.getByText('test')).toHaveClass('hide'); //判斷元素是否含有指定的 class name
});
});
最后一个就是模拟使用着操作,user-event 常常跟另一个@testing-library/react 的fireEvent 拿来比较,fireEvent 就是在程式码中会用的事件处理,像是click 或是change,而user-event的底层就是fireEvent,不过userEvent 能更贴合使用者的模拟情况,像是同样是在input 输入文字,如果使用fireEvent 就会使用change 的事件。
fireEvent:
import { fireEvent } from '@testing-library/react';
fireEvent.change(inputElement, { target: { value: 'Hello, world!' } });
不过如果是用userEvent 就会使用type 的事件。
userEvent:
import userEvent from '@testing-library/user-event';
const user = userEvent.setup()
user.type(inputElement, 'Hello, world!');
乍看之下没有什么不一样,不过userEvent 的type 还包含使用者点击input,输入文字的keydown、keyup 事件,比起fireEvent 的change,更贴近实际的使用者操作情况。
除此之外,userEvent 还有提供很多实用的方法像是:
dblClick:点击两次
tripleClick:点击三次
type:input 输入
upload:上传
hover/unhover:指标移进移出
copy/paste:复制/贴上
详细的可以参考User Interactions
Jest的未来看起来非常令人激动!看到Jest推陈出新如此快速,我感觉它将很快成为整个React生态系统中大部分项目的首选工具。我建议,应该把测试迁移到Jest上去。
如果您正在测试前端应用程序,则应该了解前端测试金字塔。在本文中,我们将看到前端测试金字塔是什么,以及如何使用它来创建全面的测试套件。
作为前端开发,我们不仅需要满足产品需求功能的实现,同时也需要对自己做的网站进行安全、易用性、性能等方面的考虑。随着目前技术不断进步,web页面的性能测试工具也在不断完善,通过这些工具,我们可以客观的评价web网站的质量水平。
jest 是 facebook 开源的,用来进行单元测试的框架,可以测试 javascipt 和 react。jest 提供了非常方便的 API,可以对下面的场景方便的测试:一般函数、异步函数、测试的生命周期、react 测试
web测试大全,测试web网站有哪些点呢?主要包括:功能测试、兼容性测试、安全测试、输入框测试、用户权限测试等
前端性能测试工具都有哪些:Favicon、Open Graph、图片优化-压缩图像、CSS 优化-Autoprefixer、Purifycss、minify CSS、减少载入时间、GZIP、CDN、优化平台-Sentry、Google Tag Manager
本文你将了解到:1、接口测试基本概念,包含什么是接口,什么是接口测试,为什么要做接口测试;2、接口测试用例设计,3、怎样不用写代码,也能快速的根据开发的API文档完成接口自动化测试脚本
在自动化元素定位操作中经常使用智能等待来加强定位的强壮性,主要就是因为WebDriver没有提供页面加载场景的方法;在使用JavaScript知识的突然心生灵感,可以使用JavaScript来配合验证页面加载,结果发现我真是井底之蛙。
在写测试代码时,以往我们需要翻阅文档,学习各种 API 才能明白如何操作断言。而现在我们可以透过 power-assert 的 assert 方法来减轻调试压力。不仅如此,它还提供更加直观,具体的运行效果,帮助 DEBUG。写测试代码,其实可以很容易。
在网站上线发布之前,我们除了必要的安全、功能测试外,往往还需要进行压力测试。通过模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件。包括:Apache JMeter 、LoadRunner、NeoLoad等
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!