---
title: "PlayWright E2E에서 오디오(녹음) 사용하기"
description: "녹음 시나리오는 어떻게 테스트할까요?"
date: 2023-09-18
tags: [javascript, testing]
sections: [technical]
draft: false
---

E2E 테스트에서 **마이크 입력**을 다루는 경우 실제 사용자의 음성 입력을 자동화하기란 쉽지 않습니다. 특히 `MediaStream`을 사용하는 기능(예: 녹음, 음성 인식 등)을 테스트하려면 별도의 설정이 필요하죠.


이 글에서는 **Playwright**를 이용해 **녹음 기능을 자동화**하고, **가짜 오디오 파일로 입력을 시뮬레이션하는 방법**을 정리해보았습니다. 영어 동화책 섀도잉 프로그램인 [ RockieTalkie ] 서비스에서 사용한 E2E 코드를 각색해 소개합니다!


# 시나리오 요약

> 사용자가 버튼을 눌러 녹음을 시작하고, 일정 시간 후 다시 버튼을 눌러 녹음을 종료합니다. 그 뒤 음성 인식 결과를 확인하고, 결과에 따라 다시 녹음하거나 다음 단계로 넘어가는 시나리오입니다.

이러한 테스트를 위해 Playwright에서 다음과 같은 기능이 필요했습니다.

- **가짜 UI 팝업 자동 허용** (`--use-fake-ui-for-media-stream`)
- **가짜 디바이스 입력 사용** (`--use-fake-device-for-media-stream`)
- **미리 녹음된 오디오 파일 사용** (`--use-file-for-fake-audio-capture`)


# 테스트 코드 살펴보기

```javascript
import { chromium } from '@playwright/test';
import { test, expect } from '../fixtures/account';

test.describe('T_017', () => {
 test('evaluate', async () => {
 const browser = await chromium.launch({
 args: [
 "--use-fake-ui-for-media-stream",
 "--use-fake-device-for-media-stream",
 "--use-file-for-fake-audio-capture=../../data/98_01_001_a.wav",
 ],
 });
 const context = await browser.newContext({
 permissions: ["microphone"],
 });
 const page = await context.newPage();

		...

 let count = 0;
 while(count++ < 2) {
 await page.locator('button.button-main').click();
 	// wait for fake audio capture
 await page.waitForTimeout(1500);
 await page.locator('button.button-main').click();
 await page.waitForLoadState('networkidle');

 await expect(page.locator('button.button-retry')).toBeVisible();
 await expect(page.getByRole('button', { name: 'Retalk' })).toBeVisible();
 const numResultTags = await page.locator('div.screen:visible > span').count();
 await expect(numResultTags).toBeGreaterThanOrEqual(1);
 await page.getByRole('button', { name: 'Retalk' }).click();
 }

 // display Next
 await page.locator('button.button-main').click();
 await page.waitForTimeout(1500); // wait for fake audio capture
 await page.locator('button.button-main').click();
 await page.waitForLoadState('networkidle');
 await page.getByRole('button', { name: 'Charging' }).click();
 await page.waitForLoadState('networkidle');
 await expect(page.locator('button.button-main').first()).toBeVisible();
 });
})
```

1. `Playwright`에서 브라우저를 실행할 때 `--use-fake-ui-for-media-stream`, `--use-fake-device-for-media-stream`, `--use-file-for-fake-audio-capture` 옵션을 통해 가짜 마이크와 오디오 파일을 지정했습니다. 여기서는 `../../data/98_01_001_a.wav` 라는 파일을 마이크 입력으로 사용했습니다. 

2. 다만 (1) 오디오 파일이 지나치게 짧거나, (2) 버튼 클릭 후 오디오 파일 실행이 즉시 이루어지는 경우에는 테스트가 정상적으로 진행되지 않는 문제가 있었습니다. 파일 실행에 의도적인 지연을 주어 우회할 수 있었습니다.

3. 브라우저 컨텍스트를 만들 때 `permissions: ['microphone']`을 추가해줘야 마이크 권한을 허용받은 상태로 테스트가 진행될 수 있었습니다. 


# 정리하며
`Playwright`는 강력한 브라우저 자동화 도구이지만 마이크 입력처럼 실제 하드웨어에 의존하는 기능은 다소 까다로울 수 있습니다. 다행히 Playwright는 Chromium의 실험 옵션을 그대로 사용할 수 있어 비교적 쉽게 테스트를 자동화할 수 있었습니다.

물론 이 테스트는 실제 사용자 음성을 인식하는 것과는 차이가 있습니다. 정확한 음성 인식 결과를 검증한다기보다는 기능 흐름이 잘 동작하는지, 녹음 버튼을 눌렀을 때 정상적으로 음성이 처리되고 UI가 업데이트되는지 등을 확인하는 용도로 적합합니다.
