国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

記錄使用vue-test-utils + jest 在uniapp中進(jìn)行單元測試

這篇具有很好參考價值的文章主要介紹了記錄使用vue-test-utils + jest 在uniapp中進(jìn)行單元測試。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前情

  • uniapp推薦了測試方案@dcloudio/uni-automator,屬于自動化測試,api提供的示例偏重于渲染組件,判斷當(dāng)前渲染的組件是否和預(yù)期一致
  • vue推薦的測試方案vue test utils,屬于單元測試,可以搭配jest、mocha等單測運行器

我選了方案2???

關(guān)于vue的組件測試,vue官方提到:

你的 Vue 應(yīng)用中大部分內(nèi)容都應(yīng)該由組件測試來覆蓋,我們建議每個 Vue 組件都應(yīng)有自己的組件測試文件。
當(dāng)進(jìn)行測試時,請記住,測試這個組件做了什么,而不是測試它是怎么做到的

對于 視圖 的測試:根據(jù)輸入 prop 和插槽斷言渲染輸出是否正確。
對于 交互 的測試:斷言渲染的更新是否正確或觸發(fā)的事件是否正確地響應(yīng)了用戶輸入事件

本身的測試寫起來很簡單,就是挺多東西需要配置的,比較麻煩,記錄在后文

安裝依賴

  • @vue/test-utils
    vue2項目安裝:
    npm install --save-dev @vue/test-utils@1
    不指定的話默認(rèn)安裝最新,適合vue3項目吧
  • jest
  • vue-jest:為了處理.vue文件
    npm install --save-dev @vue/vue2-jest@29 (最后寫jest版本)
  • babel-jest
  • jest-environment-jsdom

jest版本在27以上,是要安裝jest-environment-jsdom
其他版本下如果報錯:

[vue-test-utils]: window is undefined, vue-test-utils needs to be run in a browser environment. 
    You can run the tests in node using jsdom 

可以嘗試:
npm install --save-dev jsdom jsdom-global

// 在測試的設(shè)置 / 入口中
require('jsdom-global')()

package.json配置

加一條就好

"scripts": {
	"test": "jest"
},

jest配置

可以配在package.json的jest選項中
也可以新建jest.config.js,我選了后者

module.exports = {
  moduleFileExtensions: [
      'js',
      'vue'
  ],
  transform: {
      '^.+\\.vue$': '<rootDir>/node_modules/@vue/vue2-jest',
      '^.+\\.js$': '<rootDir>/node_modules/babel-jest'
  },
  moduleNameMapper: { // webpack中設(shè)置了別名,@設(shè)置為/src 的別名,就需要配這個
      '^@/(.*)$': '<rootDir>/src/$1'
  },
  testMatch: ['**/__tests__/**/*.spec.js'],
  transformIgnorePatterns: ['<rootDir>/node_modules/'],
  testEnvironment: "jsdom" // jest v27以上要加
}

??:
官網(wǎng)提到的一個注意點:

如果你使用了 Babel 7 或更高版本,
你需要在你的 devDependencies 里添加 babel-bridge 
($ npm install --save-dev babel-core@^7.0.0-bridge.0)

我在運行時有相關(guān)的報錯提示,所以我也按照這樣安裝了
如果你也有的話,可以參考一下

測試文件目錄

新建__tests__目錄,放在src目錄下可以,根目錄下也可以
(注意別少打s)
目錄下的測試文件擴(kuò)展名應(yīng)該是.spec.js或者test.js ,我選了前者
這個也可以改,想改去找jest文檔————

編寫setup.js

通常用于執(zhí)行一些全局的設(shè)置或引入一些測試所需的全局依賴,以確保這些設(shè)置和依賴在所有測試文件中都可用!

jest.config.js中新加一條:
setupFiles: ["./__tests__/setup.js"]

__test__文件夾下新建setup.js

1.項目中用到的uni或者wx的api是識別不了的,所以放在這里預(yù)先配置一下
2.在Vue.prototype上掛載的比如$toast、$api,$store、直接用this.調(diào)用的時候也是識別不了的,也要在這配置一下

localVue可以理解成創(chuàng)建本地的vue實例,可以使用localVue.prototype掛載一些東西而不會污染到真正的Vue.prototype,我在這掛到全局了,實際上可以在每個單獨的測試文件中都create新的

import { createLocalVue } from "@vue/test-utils";
import Vuex from 'vuex'
import axios from 'axios'

const CODE = '用戶登錄憑證';
// 創(chuàng)建的一個 Vue 的本地拷貝
const localVue = createLocalVue()

localVue.use(Vuex)
const store = new Vuex.Store({
  state: {},
  mutations: {
    // 這里如果只是為了代碼里不卡住,直接jest.fn()就可以
    login: jest.fn((state, userInfo) => state.userInfo = userInfo),
    setFlag: jest.fn((state,param) => state.flag = param.flag),
    logout: jest.fn((state) => state.userInfo = {})
  }
})
localVue.prototype.$store = store
localVue.prototype.$toast = jest.fn()
// 后面很多場景的使用是const {confirm} = await this.$modal(xxx), 這里直接模擬cofirm為true
localVue.prototype.$modal = jest.fn(() => Promise.resolve({ confirm: true }))
localVue.prototype.$api = {
  student: {
    studentLogin: jest.spyOn(axios, 'post')
  },
}

global.uni = {
  showLoading: jest.fn(),
  hideLoading: jest.fn(),
  navigateTo: jest.fn(),
  switchTab: jest.fn(),
  getStorageSync: jest.fn(),
  setStorageSync: jest.fn(),
  login: jest.fn(() => Promise.resolve([,CODE]))
}
global.setValue = (target, value) => {
  target.element.value = value
  target.trigger('input')
}
global.wx = global.uni
global.localVue = localVue

ps:這里掛了一個全局的方法setValue,因為官方的那個我使用會報錯顯示沒有setValue(),查看setValue(),不知道是不是因為我的input是小程序的??

編寫第一個測試文件

對組件StudentLogin.vue,新建studentLogin.spec.js

變更一個響應(yīng)式屬性之后,為了斷言這個變化,測試需要等待 Vue 完成更新,可以

  1. await vm.nextTick() 2. await 操作,比如trigger
import { shallowMount } from "@vue/test-utils";
import StudentLogin from '@/pages/student-login/student-login'

 const TEST_VALUE = '123456'
 const TEST_TIP = {
    NO_NUMBER: '請?zhí)顚憣W(xué)號!',
    NO_PASSWORD: '請?zhí)顚懨艽a!'
  }
// describe(name, fn): 表示一組測試,如果沒有describe,那整個測試文件就是一個describe。name是這組測試的名字,fn是這組測試要執(zhí)行的函數(shù)。
describe('StudentLogin.vue', () => {
  let wrapper;
  beforeEach(() => {
    // shallowMount和mount區(qū)別在于不會掛載子組件,比較適合單元測試,子組件的測試邏輯單獨寫
    wrapper = shallowMount(StudentLogin, {
      localVue
    })
  })
 
  // formSubmit觸發(fā)時,輸入賬號沒輸入密碼,提示請?zhí)顚懨艽a!
  test('if formSubmit triggered with number but no password, show tip', async () => {
    setValue(wrapper.find('input[name="number"]'), TEST_VALUE)
    await wrapper.vm.$nextTick();
    await wrapper.find('.submit-btn').trigger('click')
    expect(localVue.prototype.$toast).toBeCalledWith('error', TEST_TIP.NO_PASSWORD)
  })
  // formSubmit調(diào)用后,應(yīng)該發(fā)起請求
  it('if formSubmit done, send request', async () => {
    setValue(wrapper.find('input[name="number"]'), TEST_VALUE)
    setValue(wrapper.find('input[name="password"]'), TEST_VALUE)
    await wrapper.vm.formSubmit()
    expect(localVue.prototype.$api.student.studentLogin).toBeCalled();
    expect(localVue.prototype.$api.student.studentLogin).toBeCalledWith(TEST_VALUE, TEST_VALUE, CODE)
  })
  // 銷毀所有被創(chuàng)建的 Wrapper 實例
  enableAutoDestroy(afterEach)
})

jest.fn()和jest.spyOn()

承接上文:
輕輕記錄一下jest.fn()jest.spyOn()
他們都是用來模擬函數(shù)的行為,都會跟蹤函數(shù)的調(diào)用和傳參
區(qū)別:jest.fn()是創(chuàng)建一個全新的模擬函數(shù),jest.spyOn()一般是模擬對象上的現(xiàn)有方法

比如
頁面需要axios發(fā)請求,但是我們測試的時候不需要實際調(diào)用,
就可以利用

localVue.prototype.$api = {
  student: {
    studentLogin: jest.spyOn(axios, 'post')
  },
}

使用場景非常多,后文也會涉及
他們兩返回的其實就是mockFn,在jest官網(wǎng)有非常多對mockFn的操作
指路:mockFn

我常用的一個mockFn.mockResolvedValue(value)
例如:
測試這個函數(shù),是否成功發(fā)送請求,但我們無需發(fā)送真的請求,就可以模擬返回值

async getList() {
	const { data } = await this.$api.student.getData()
	this.list = data
}
// test.spec.js
test('', async () => {
	localVue.prototype.$api.student.getData.mockResolvedValue({
		list: [1,2,3]
	})
	await wrapper.vm.getList()
	expect(wrapper.list.length).toBe(3)
})

??提醒一下自己,注意:
比如說我們要斷言,trigger某個操作或者更新了頁面之后,某個函數(shù)應(yīng)該要被調(diào)用
會使用

const spy = jest.spyOn(wrapper.vm, 'someFunction')
expect(spy).toBeCalled()

但要注意這個必須要寫在更新操作之前,如果寫在之后是會斷言錯誤的
?? jest.spyOn寫在了trigger之后,也就是開始跟蹤的時候已經(jīng)觸發(fā)完了,
那么expect(infoSpy).toBeCalled()就會失敗

 test('if term picker triggered', async () => {
   const picker = wrapper.findComponent('picker')
   await picker.trigger("change", 1);
   const infoSpy = jest.spyOn(wrapper.vm, 'getInfo')
   expect(wrapper.vm.termIndex).toBe(1)
   expect(infoSpy).toBeCalled()
 })

jest 解析scss失敗

比如這個頁面有引入scss:
import { THEME_COLOR } from "@/uni.scss";
如果不做配置的話就會報錯

解決方法:
新建一個styleMock.js

// styleMock.js
module.exports = {
  process() {
    return {
      code: `module.exports = {};`,
    };
  },
};

然后在jest.config.js中配置transform

transform: {
   '^.+\\.vue$': '<rootDir>/node_modules/@vue/vue2-jest',
   '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
   '\\.(css|less|scss|sass)$': '<rootDir>/styleMock.js',
},

然后運行npm run test,如果還是沒生效,可以試試關(guān)閉編輯器重新啟動

測試vuex

這里不提官網(wǎng)有的部分,有需要可自查
在組件中測試vuex

目前場景是這個組件在計算屬性中使用了mapState

computed: {
	... mapState(['flag', 'userInfo'])
}

然后當(dāng)userInfo.level = 1 && flag = 1時候要渲染某容器,我需要測試這個,那么就需要修改state中的數(shù)據(jù)
由于前面在setup.js中已經(jīng)在localVue上安裝了vuex,這里就通過localVue來訪問

localVue.prototype.$store.state.flag = 1
localVue.prototype.$store.state.userInfo = { level: 1 }

如果使用$store.commit()的話,就要在setup.js中l(wèi)ocalVue.prototype.$store上用jest.fn()具體實現(xiàn)mutation中的方法了,只是簡單的用jest.fn()模擬是不生效的
像這樣??

const store = new Vuex.Store({
  state: {},
  mutations: {
    // 這里如果只是為了代碼里不卡住,直接jest.fn()就可以
    login: jest.fn((state, userInfo) => state.userInfo = userInfo),
    setFlag: jest.fn((state,param) => state.flag = param.flag),
    logout: jest.fn((state) => state.userInfo = {})
  }
})

??:更改完數(shù)據(jù)后,要等待頁面更新,記得await nextTick()一下,否則斷言會失敗

$refs

類似于這樣的代碼:

close() { 
	// 清除校驗結(jié)果
	this.$refs.form.clearValidate();
	this.$emit('close');
},

this.$refs.form.clearValidate();會報錯,提示找不到clearValidate這個function
解決方法1: 模擬一個form塞在stubs里

// 這里要寫的是組件的名字,不是ref設(shè)置的名字
 const UniForms = {
   render: jest.fn(),
   methods: {
     validate: () => {},
     clearValidate:() => {}
   }
 }
wrapper = shallowMount(ForgetPassword, {
  localVue,
  stubs: {
    UniForms
  }
})

(模板上<uni-forms ref="form"></uni-forms>)
但我這個例子用這個方法不太行,會影響我別的測試(一些元素渲染失敗,wrapper.find時會找不到)
先記錄在這吧

解決方法2:
加一行??
wrapper.vm.$refs.form.clearValidate = jest.fn()

如果有要返回的數(shù)據(jù),可以在jest.fn()中直接模擬
比如說:
我們需要拿到返回的password、email,簡單的jest.fn()無法滿足需求

const { password, email } = await this.$refs.form.validate();

設(shè)定jest.fn()模擬的函數(shù),返回成功值

wrapper.vm.$refs.form.validate = jest.fn(() => Promise.resolve({ 
	password: 1, 
	email: 1
}))

后續(xù):
又有一處用到$refs:

mounted() {	
	this.$refs.form.setRules(this.formRules);
}

這次是在mounted()里使用,方法2就用不了了,因為需要先mount(wrapper),才能拿到wrapper.vm,但這里又是要在mounted中執(zhí)行的,假如我們使用wrapper.vm.$refs.form.setRules = jest.fn()其實就已經(jīng)晚了,mounted已經(jīng)執(zhí)行完了

這個時候就可以用方法1~

定時器

檢驗有關(guān)定時器的方法

setTime(number) {
	this.codeText = `倒計時${number}s`;
	if(!number) {
		this.codeText = '發(fā)送驗證碼';
		this.isSending = false;
		this.timer = null;
		return;
	} else {
		number--;
	}
	this.timer = setTimeout(() => {
		this.setTime(number);
	}, 1000);
},

使用jest.useFakeTimers()指定全局使用假的定時器api
jest.advanceTimersByTime(1000)模擬時間快進(jìn)1s

jest.useFakeTimers()
const sendCodeBtn = wrapper.findComponent('.send-code')
test('if setTime triggered 60, change btn content and start countdown', async () => {
    const setTimeSpy = jest.spyOn(wrapper.vm, 'setTime')
    await wrapper.vm.setTime(60)
    expect(sendCodeBtn.text()).toBe('倒計時60s')
    // 過一秒
    jest.advanceTimersByTime(1000)
    expect(setTimeSpy).toBeCalledWith(60 - 1)
  })

  test('if setTime triggered 0, change btn content and close timer', async () => {
    await wrapper.vm.setTime(0)
    expect(sendCodeBtn.text()).toBe('發(fā)送驗證碼')
    // 過一秒
    jest.advanceTimersByTime(1000)
    expect(wrapper.vm.timer).toBe(null)
  })

測試函數(shù)調(diào)用n次

本來想測
1.titleInput或contentInput無內(nèi)容時 => 提示’請輸入必要內(nèi)容’
2.titleInput和contentInput都有內(nèi)容時 => 不顯示提示
(錯誤寫法??)

test("", async () => {
    await form.trigger('submit')
    expect(localVue.prototype.$toast).toHaveBeenCalledWith('none', '請輸入必要內(nèi)容')
    setValue(titleInput, TEST_VALUE)
    await form.trigger('submit')
    expect(localVue.prototype.$toast).toHaveBeenCalledWith('none', '請輸入必要內(nèi)容')
    setValue(contentInput, TEST_VALUE)
    await form.trigger('submit')
    expect(localVue.prototype.$toast).not.toHaveBeenCalled()
});

但上面這種寫法是錯的,實際上localVue.prototype.$toast的調(diào)用是累積的,不是相互隔離的,第三次expect(localVue.prototype.$toast)的時候?qū)嶋H上已經(jīng)被調(diào)用三次了,那么not.toHaveBeenCalled()就不可能通過測試

這時候應(yīng)該使用toHaveBeenNthCalledWidth(),第一個參數(shù)寫n,表示第n次
第三次的時候不應(yīng)該被調(diào)用,就用toHaveBeenCalledTimes()判斷總調(diào)用次數(shù)

test("", async () => {
    await form.trigger('submit')
    expect(localVue.prototype.$toast).toHaveBeenNthCalledWith(1, 'none', '請輸入必要內(nèi)容')
    setValue(titleInput, TEST_VALUE)
    await form.trigger('submit')
    expect(localVue.prototype.$toast).toHaveBeenNthCalledWith(2, 'none', '請輸入必要內(nèi)容')
    setValue(contentInput, TEST_VALUE)
    await form.trigger('submit')
    expect(localVue.prototype.$toast).not.toHaveBeenCalledTimes(3);
});

手動調(diào)用生命周期

比如說
(onLoad是小程序里的生命周期)

onLoad({code}) {
	this.code = +code;
	// 每10min刷新一次
	if(!this.code) {
		this.getSignInCode();
		this.timer = setInterval(() => { this.getSignInCode() }, 600000);
	} 
}

這里想測試code為0的時候是否調(diào)用了函數(shù)getSignInCode,且過了10min是否再次調(diào)用

我想手動調(diào)用onLoad(),onLoad并不在wrapper.vm上,不能通過wrapper.vm.onLoad訪問
可以通過兩種方式找到:(這個組件名叫ShowQRcode

  1. ShowQRcode.onLoad({ code: 1 })
  2. wrapper.vm.$options.onLoad({ code: 1 })

但都會報錯:this.getSignInCode is not a function,因為getSignInCode是在wrapper.vm上的,所以這里要更改this指向
ShowQRcode.onLoad.call(wrapper.vm, {code: 0 })

 test('', () => {
   const signInSpy = jest.spyOn(wrapper.vm, 'getSignInCode')
   ShowQRcode.onLoad.call(wrapper.vm, { code: 0 })
   expect(signInSpy).toHaveBeenCalledTimes(1)
   jest.advanceTimersByTime(600000)
   expect(signInSpy).toHaveBeenCalledTimes(2)
 })

處理其他模塊導(dǎo)入的函數(shù)

場景:

import { uploadImg } from '@/util/uploadImg.js';

async selectImg(res) {
	// 上傳圖片
	const { url } = await uploadImg(res.tempFilePaths, 'files')
	this.imgPaths.push(url[0]);
}

如果要測試selectImg(),當(dāng)執(zhí)行到uploadImg()就會報錯

我們就可以利用jest.mock來模擬這個模塊
記錄一下jest.mock的簡單使用:
官網(wǎng)的例子:

// banana.js
export default () => 'banana';
// test.spec.js
// 后續(xù)的測試中,任何導(dǎo)入./banana模塊的代碼將會被自動模擬,而不是實際的banana.js模塊
jest.mock('./banana');
// 這個導(dǎo)入的bannana就被自動模擬了
const banana = require('./banana');
// 不會返回banana,因為被模擬了,默認(rèn)返回undefined
banana(); // will return 'undefined' 

還可以接收一個函數(shù),顯式指定模塊導(dǎo)出的內(nèi)容

// 相當(dāng)于 
// const mockFn = jest.fn(() => 'bannana'
// export default mockFn
jest.mock('./bannana', () => {
  return jest.fn(() => 'bannana');
});

const bannana = require('./bannana');
bannana(); // Will return 'bannana';

所以這里就這樣寫:

// 相當(dāng)于 
// export const uploadImg = jest.fn(() => Promse.resolve({ data: TEST_UPLOAD_RESPONSE}))
jest.mock('@/util/uploadImg.js', () => ({
  otherFunction: xxx,
  uploadImg: jest.fn(() => Promise.resolve({ data: TEST_UPLOAD_RESPONSE }))
}));

測試插槽

項目比較簡單,用插槽的地方很少,甚至沒用到作用域插槽
這里只記錄最簡單的方法
官網(wǎng)是有例子的:測試插槽

就是在shallowMount的時候配置slots

 beforeEach(() => {
    wrapper = shallowMount(Detail, {
      localVue,
      slots: {
        list: '<view>list</view>',
        operation: '<view>operation</view>'
      }
    })
  })

這里slots配置的就是模擬傳入插槽的內(nèi)容
比如list: '<view>list</view>',就是該組件內(nèi)有一個插槽出口<slot name="list"></slot>
然后我們模擬傳入這個插槽的內(nèi)容是<view>list</view>
之后打印wrapper.html()會發(fā)現(xiàn)插槽出口確實都被替換成了我們預(yù)設(shè)的內(nèi)容
只需要斷言expect(wrapper.html()).toContain('<view>list</view>')即可完成測試

這里還出現(xiàn)一個問題,我有一個插槽出口長這樣??

<slot name="top">
  <view class="top__button" 
		v-if="flag === 'xxx'">
    <text>{{ xxx }}</text>
  </view>
</slot>

在插槽中指定了默認(rèn)內(nèi)容,且默認(rèn)內(nèi)容要通過v-if控制顯示隱藏
并且這個地方我也寫了一個測試,是測試top__button的顯隱
如果我一開始預(yù)設(shè)的時候,預(yù)設(shè)了插槽top的內(nèi)容,就會導(dǎo)致這個測試失敗,因為找不到top__button了,直接被替換成了我預(yù)設(shè)的內(nèi)容
其實失敗的原因是我兩個測試共用了一個wrapper的配置(習(xí)慣寫在beforeEach里)

解決的方法就是在這個測試中,單獨的再重新創(chuàng)建一個wrapper,不要預(yù)設(shè)slots就好

補充:
測試作用域插槽

參考:
https://juejin.cn/post/7119314584371986468?searchId=2023092122585499D5137C15C4283D9452
https://blog.csdn.net/pk142536/article/details/122255192
https://zhuanlan.zhihu.com/p/457648810文章來源地址http://www.zghlxwxcb.cn/news/detail-742044.html

到了這里,關(guān)于記錄使用vue-test-utils + jest 在uniapp中進(jìn)行單元測試的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • vitest 單元測試配合@vue/test-utils 之 axios 篇

    vitest 是由 vite 提供支持的極速單元測試框架,VueTestUtils 是 Vue.js 的官方測試實用程序庫,Axios 是一個基于 promise 的網(wǎng)絡(luò)請求庫,以上均為各自官網(wǎng)對其的描述 項目中使用 axios 是非常常見的,所以我們可以對他做一個單元測試,在 test-utils 的文檔中提到除了 jest.mock()還可以使

    2024年02月19日
    瀏覽(23)
  • vitest單元測試配合@vue/test-utils之組件單元測試篇

    vitest 是由 vite 提供支持的極速單元測試框架,VueTestUtils 是 Vue.js 的官方測試實用程序庫,vitest 本身是不支持單元組件測試的,需要配合 test-utils 來完成組件單元測試,安裝與基本 API 就不再贅述,學(xué)會閱讀文檔與查找資料是一個程序員的基本功 demo 由一個組件和測試文件組成

    2024年03月16日
    瀏覽(26)
  • 如何使用Jest進(jìn)行單元測試

    Jest 是一種流行的 JavaScript 測試框架,它具有易用性和高效性。Jest 支持測試各種 JavaScript 應(yīng)用程序,包括 React、Vue、Node.js 等。在本文中,我們將介紹如何使用 Jest 進(jìn)行單元測試。 ## 1. 安裝 Jest 首先,我們需要在項目中安裝 Jest??梢允褂?npm 或 yarn 安裝 Jest: ``` npm install

    2024年02月10日
    瀏覽(26)
  • Testing Angular, VueJS, and React Components with Jest

    作者:禪與計算機程序設(shè)計藝術(shù) 在過去的幾年里,React、Angular和Vue等前端框架都獲得了越來越多開發(fā)者的青睞,并且取得了不俗的成績。這些前端框架的出現(xiàn)給前端開發(fā)領(lǐng)域帶來了許多新鮮的機會。特別是在面對復(fù)雜業(yè)務(wù)需求時,測試驅(qū)動開發(fā)(TDD)方法對于保證項目質(zhì)量至

    2024年02月06日
    瀏覽(18)
  • 使用 Jest 在 Visual Studio Code 中進(jìn)行更好的單元測試

    使用 Jest 在 Visual Studio Code 中進(jìn)行更好的單元測試

    目錄 前言: 使用 Jest 擴(kuò)展顯著改善測試流程 1.自動啟動 Jest 測試 2. 顯示單個失敗/通過的測試用例 允許調(diào)試單元測試 在文件中顯示代碼覆蓋率 結(jié)論 前言: Jest是一個流行的JavaScript測試框架,它提供了簡潔、靈活和強大的工具來編寫和運行單元測試。在Visual Studio Code(VS C

    2024年02月13日
    瀏覽(19)
  • uniapp Vue 使用 sip.js進(jìn)行語音通話視頻通話

    下載或者安裝 sip.js 到 uniapp 項目,APP 端在 menifest.json 中配置麥克風(fēng)權(quán)限 menifest.json 中 app 權(quán)限配置選中: android.permission.RECORD_AUDIO android.permission.MODIFY_AUDIO_SETTINGS sip.js 低版本 如 V0.13.0 版本的寫法 sip.js 高版本如 V0.21.2 用法 (參數(shù)同上,只列出 methods 里的部分) APP模式下檢測麥

    2024年02月13日
    瀏覽(104)
  • test ui-01-UI 頁面測試 Selenium/Appium/Cypress/TestCafe/Playwright/WebDriverIO/Nightwatch/Puppeteer/Jest

    UI測試(用戶界面測試)是軟件測試中的一個重要方面,其主要目的是確保用戶界面的正常運作,并驗證用戶可以按照設(shè)計的方式與應(yīng)用程序進(jìn)行交互。 UI測試通常涉及檢查圖形用戶界面(GUI)元素的正確性、響應(yīng)性和用戶體驗等方面。 在測試過程中,測試人員會模擬用戶與

    2024年01月17日
    瀏覽(34)
  • 使用Simulink Test進(jìn)行單元測試

    使用Simulink Test進(jìn)行單元測試

    本文摘要:主要介紹如何利用Simulink Test工具箱,對模型進(jìn)行單元測試。內(nèi)容包括,如何創(chuàng)建Test Harness模型,如何自動生成excel格式的測試用例模板來創(chuàng)建測試用例,如何手動填寫excel格式的測試用例模板來手動創(chuàng)建測試用例。 單元測試的目的 創(chuàng)建完模型后,我們需要驗證模型

    2024年02月16日
    瀏覽(23)
  • SpringBoot 如何使用 Spring Test 進(jìn)行集成測試

    SpringBoot 如何使用 Spring Test 進(jìn)行集成測試

    在開發(fā)過程中,單元測試是不可或缺的,它可以幫助我們及時發(fā)現(xiàn)代碼的問題并進(jìn)行修復(fù),從而提高代碼的質(zhì)量和可維護(hù)性。但是,單元測試只能測試單個方法或類的功能,無法測試多個模塊之間的交互和整個應(yīng)用程序的功能。因此,為了確保應(yīng)用程序的正確性和健壯性,我

    2024年02月10日
    瀏覽(21)
  • [C++] 基礎(chǔ)教程 - 如何使用google test進(jìn)行單元測試

    [C++] 基礎(chǔ)教程 - 如何使用google test進(jìn)行單元測試

    https://download.csdn.net/download/u011775793/88601877 單元測試是一種軟件測試方法,用于測試代碼中的最小可測試單元。在軟件開發(fā)中,我們通常將代碼分解為多個模塊或類,每個模塊或類都有自己的功能和行為。單元測試的目的是確保每個模塊或類都能正常工作,不會影響其他模塊或

    2024年02月04日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包