浏览器环境测试
浏览器环境测试
很多自动化测试都是基于Node环境,但是当涉及到使用浏览器API的场景时,就需要模拟浏览器环境进行相关测试。
在通过npx jest --init生成Jest配置文件时,环境要选择jsdom,并且需要安装jest-environment-jsdom依赖(Jest V28版本开始):
yarn add jest @types/jest ts-jest jest-environment-jsdom -D
修改配置文件:
{
"preset": "ts-jest",
"testEnvironment": "jsdom",
}
模拟storage
jest-environment-jsdom,这个依赖提供了localStorage、sessionStorage、window等全局对象之类的API,其核心作用就是在Node环境中模拟浏览器的环境。
如下示例测试localStorage的存储与取值:
- src/utils/storage.ts
- __test__/stroage.spec.ts
const KEY = 'my-app-'
function set(key: string, value: string) {
localStorage.setItem(KEY + key, value)
}
function get(key: string) {
return localStorage.getItem(KEY + key)
}
export default {
get,
set
}
import storage from './src/utils/storage.ts'
test('Test localStorage', () => {
storage.set('name', 'Nancy')
expect(storage.get('name')).toBe('Nancy')
})
模拟location
虽然jest-environment-jsdom可以模拟很多浏览器的API,但是也有一些浏览器API的实现是缺失的,因此遇到这种情况,需要通过额外的依赖库或自定义依赖库来完成模拟。
例如,jest-environment-jsdom并没有location对象的模拟实现,可通过jest-location-mock库来模拟:
yarn add jest-location-mock -D
- src/utils/tools.ts
- __test__/location.spec.ts
function getSearchObj() {
const { search } = window.location
const searchStr = search.slice(1)
const pairs = searchStr.split('&')
const searchObj: Record<string, string> = {}
pairs.forEach((pair) => {
const [key, value] = pair.split('=')
searchObj[key] = value
})
return searchObj
}
export { getSearchObj }
import { getSearchObj } from '../ts/utils/tools'
import 'jest-location-mock'
describe('Test getSearchObj', () => {
test('with search string', () => {
// window.location.href = "https://www.baidu.com?a=1&b=2";
window.location.assign(
'https://www.baidu.com?a=1&b=2'
)
const result = getSearchObj()
expect(result).toEqual({
a: '1',
b: '2'
})
expect(window.location.search).toBe('?a=1&b=2')
})
test('no search string', () => {
window.location.assign('https://www.baidu.com')
const result = getSearchObj()
expect(result).toEqual({})
expect(window.location.search).toBe('')
})
})
模拟fetch
Fetch API在Node环境下原生支持,但在模拟浏览器环境下需要通过jest-fetch-mock库来模拟:
yarn add jest-fetch-mock -D
- src/utils/tools.ts
- __test__/fetch.spec.ts
async function fetchData(id: number) {
return fetch(
`https://jsonplaceholder.typicode.com/todos/${id}`
)
.then((res) => res.json())
.then((res) => res)
}
export {
fetchData
}
import { fetchData } from '../ts/utils/tools'
import 'jest-fetch-mock'
test('Test fetch', async () => {
const result = await fetchData(1)
expect(result).toHaveProperty('userId')
expect(result).toHaveProperty('id')
expect(result).toHaveProperty('title')
expect(result).toHaveProperty('completed')
})