📁 HLS(HTTP 라이브 스트리밍) 테스트 목록
- 재생을 누르면 노래가 시작된다
- 중지를 누르면 노래가 중지가된다
- 노래가 끝나면, 1.5초 이후 다시 처음부터 시작한다
위와같이 내용은 간단하다. 블로그 전용이므로 복잡한로직은 제거하고, 순수하게 재생/중지/노래가끝났을때의 처리 정도만 실시하였다.
아래는 원본코드이며, m3u8 url를 가진 주소를 이용하여 $VideoPlayer를 이용하여 노래를 재생/중지를 이용한다.
($VideoPlayer 안에는 hls.js에서 사용할수 있는 기능들을 객체로 만들어놓았고, $VideoPlayer 따로 만든 이유는 어느 화면에서든 공통에서 작성할 수 있도록 하기위해 globalProperties 이용하여 만들었다.)
$VideoPlayer는 아래와 같은 기능을 가지고 있다
- setVideo : 비디오 element를 설정하는 함수이며, setVideo(document.querySelector('#streaming')) 형태로 사용할 수 있고, 추가적으로 getVideo를 통해서 return된 video를 획득할수있다.
- registerEventListener : video의 이벤트 등록를 해주는 함수이다. $VideoPlayer.registerEventListener('pause', pauseEventListener) 처럼 사용하여, 두번째 인자에 함수를 넣어줄수 있다.
- playerMusic : m3u8확장자를 가진 url를 넣을수있으며, video src에 넣을수있다.
- startLoad : hls.js에서 autoStartLoad:false를 두는 경우 startLoad에 -1를 두고 play가 가능하다.
- onPlay : video의 play함수를 호출하며 return을 Promise형태로 return한다.
- onPause : vidoe pause 함수를 호출하며 video가 중지된다
<template>
<div>
<button id="playbtn" @click="clickPlay">재생</button>
<button id="pausebtn" @click="clickPause">중지</button>
<p>{{ currentTime }} / {{ durationTime }}</p>
</div>
</template>
<script setup>
import { getCurrentInstance, ref } from 'vue'
const app = getCurrentInstance()
const $VideoPlayer = app.appContext.config.globalProperties.$VideoPlayer
const m3u8Url = ref(
'm3u8확장자를 가진 URL'
)
const currentTime = ref(0)
const durationTime = ref(0)
const pauseEventListener = () => {
console.log('pause')
}
const playEventListener = () => {
console.log('play')
}
const timeUpdateEventListener = (event) => {
currentTime.value = event.target.currentTime
if (event.target.duration) {
durationTime.value = event.target.duration
}
}
const endedEventListener = () => {
setTimeout(() => {
$VideoPlayer.onPlay()
}, 1500)
}
$VideoPlayer.setVideo(document.querySelector('#streaming'))
$VideoPlayer.registerEventListener('pause', pauseEventListener)
$VideoPlayer.registerEventListener('play', playEventListener)
$VideoPlayer.registerEventListener('timeupdate', timeUpdateEventListener)
$VideoPlayer.registerEventListener('ended', endedEventListener)
const clickPlay = () => {
$VideoPlayer.playerMusic(m3u8Url.value)
$VideoPlayer.startLoad(-1)
$VideoPlayer.onPlay()
}
const clickPause = () => {
$VideoPlayer.onPause()
}
</script>
<style scoped src="@/assets/styles/hls/hlsview.css"></style>
🤪 재생을 누르면 노래가 시작된다
재생버튼을 누르면 노래가 시작된다. 순서는 id가 playBtn인 버튼을 찾는다 => playBtn인 버튼을 click시켜준다 => clickPlay함수안에 playerMusic, startLoad , onPlay 가 호출됐는지 확인한다. 식으로 작성한다
($VideoPlayer는 외부의존성이 있기 때문에 mocking 처리 하였다. 여기서는 $VideoPlayer의 내용물에대해 관심이 없다 전제하에 작성한다.)
추가적으로 playerMusic,startLoad같은 경우 인자와 함께 호출되었으므로 toBeCalledWith 함수를 사용하여 테스트한다.
import { shallowMount } from '@vue/test-utils'
import HlsView from '../../HlsView.vue'
const $VideoPlayer = {
setVideo: jest.fn(),
registerEventListener: jest.fn(),
playerMusic: jest.fn(),
startLoad: jest.fn(),
onPlay: jest.fn(),
onPause: jest.fn()
}
describe('hlsview unit test', () => {
let wrapper = null
jest.useFakeTimers()
beforeEach(() => {
wrapper = shallowMount(HlsView, {
global: {
config: {
globalProperties: {
$VideoPlayer
}
}
}
})
})
afterEach(() => {
$VideoPlayer.onPlay.mockClear()
jest.clearAllTimers()
})
test('재생을 누르면 노래가 시작된다', async () => {
//given(준비) : id가 playBtn인 버튼을 찾는다
const playBtn = wrapper.find('#playbtn')
//when(실행) : playBtn인 버튼을 click시켜준다
await playBtn.trigger('click')
//then(검증) : clickPlay함수안에 playerMusic, startLoad , onPlay 가 호출됐는지 확인한다
expect($VideoPlayer.playerMusic).toBeCalledWith(
'm3u8 확장자를 가진 URL'
)
expect($VideoPlayer.startLoad).toBeCalledWith(-1)
expect($VideoPlayer.onPlay).toBeCalled()
})
})
🥹 중지를 누르면 노래가 중지가된다
중지버튼을 누르면 노래가 중지가 된다. 마찬가지로 id가 pauseBtn인 버튼을 찾고 => pauseBtn인 버튼을 클릭한다 => onPause의 호출 여부를 확인한다.
import { shallowMount } from '@vue/test-utils'
import HlsView from '../../HlsView.vue'
const $VideoPlayer = {
setVideo: jest.fn(),
registerEventListener: jest.fn(),
playerMusic: jest.fn(),
startLoad: jest.fn(),
onPlay: jest.fn(),
onPause: jest.fn()
}
describe('hlsview unit test', () => {
let wrapper = null
jest.useFakeTimers()
beforeEach(() => {
wrapper = shallowMount(HlsView, {
global: {
config: {
globalProperties: {
$VideoPlayer
}
}
}
})
})
afterEach(() => {
$VideoPlayer.onPlay.mockClear()
jest.clearAllTimers()
})
test('중지를 누르면 노래가 중지가된다', async () => {
//given(준비) : id가 pauseBtn인 버튼을 찾는다
const pausebtn = wrapper.find('#pausebtn')
//when(실행) : id가 pauseBtn인 버튼을 클릭한다
await pausebtn.trigger('click')
//then(검증) : onPause함수 호출여부를 확인한다.
expect($VideoPlayer.onPause).toBeCalled()
})
})
🙃 노래가 끝나면, 1.5초 이후 다시 처음부터 시작한다
노래가 끝나고 1.5초가 지나면 노래가 다시 시작한다. 이미 endedEventListener 를 이벤트리스너로 등록하였고, 종료가 되면 endedEventListener 라는 함수가 발동이 될것이다.
import { shallowMount } from '@vue/test-utils'
import HlsView from '../../HlsView.vue'
const $VideoPlayer = {
setVideo: jest.fn(),
registerEventListener: jest.fn(),
playerMusic: jest.fn(),
startLoad: jest.fn(),
onPlay: jest.fn(),
onPause: jest.fn()
}
describe('hlsview unit test', () => {
let wrapper = null
// setTimeOut,setInterval를 사용할 수 있도록 useFakeTimers를 최상위에 호출한다
jest.useFakeTimers()
beforeEach(() => {
wrapper = shallowMount(HlsView, {
global: {
config: {
globalProperties: {
$VideoPlayer
}
}
}
})
})
afterEach(() => {
$VideoPlayer.onPlay.mockClear()
// 단위테스트가 끝날때마다 clearAllTimers를 시켜준다
jest.clearAllTimers()
})
test('노래가 끝나면, 1.5초 이후 다시 처음부터 시작한다', async () => {
//given : endedEventListener를 가진 vm을 호출한다
const instance = wrapper.vm
//when : endedEventListener를 호출한다 && 1.5초가 흐르도록 설정한다
instance.endedEventListener()
jest.advanceTimersByTime(1500)
//then : onPlay가 호출됐는지 확인한다.
expect($VideoPlayer.onPlay).toBeCalled()
})
})
'테스트코드' 카테고리의 다른 글
😙 스냅샷 테스트 (0) | 2024.12.03 |
---|---|
🐵 테스트코드 작성시 실제 vuex사용하기(mocking아님) (0) | 2024.08.23 |
🌊 vuex jest 테스트 코드 작성 (0) | 2024.06.17 |
🔗 vuex jest 사용 (1) | 2024.03.31 |
💿 부모컴퍼넌트에서 emit 테스트 (0) | 2024.03.18 |
댓글