이 글에서는 디스코드 봇을 개발할 때 흔히 마주치는 테스트 관련 증상과 원인, 그리고 로컬에서부터 디스호스트에 배포하여 검증하는 구체적 절차를 다룬다. 디스코드 봇을 안정적으로 운영하려면 테스트 과정과 환경 차이를 명확히 이해하고 대응하는 것이 중요하다.
증상
- 로컬에서는 정상 동작하지만 디스호스트에 배포하면 명령에 응답하지 않음.
- 특정 이벤트(메시지, 반응 등)가 수신되지 않음.
- 배포 후 프로세스가 즉시 종료되거나 예기치 않게 재시작됨.
- 테스트 자동화(유닛/통합)가 실패하거나 인증 관련 에러 발생.
원인
- 환경 변수 미설정:
BOT_TOKEN,GUILD_ID,NODE_ENV등이 누락됨. - 잘못된 Gateway Intents: 필요한 인텐트를 등록하지 않아 이벤트가 수신되지 않음.
- Node 버전/의존성 차이: 로컬과 호스트의 Node 버전 불일치 또는 빌드 스텝 누락.
- 포트/프로세스 관리 문제: 웹훅/헬스체크 포트 충돌 또는 프로세스 관리(예: PM2 설정 누락).
- 테스트 환경 분리 미흡: 프로덕션 토큰을 테스트에서 그대로 사용하거나 동일 길드에서 충돌 발생.
해결 방법
1단계: 로컬에서 기본 기능 검증
로컬에서 먼저 최소한의 코드로 연결과 명령 처리를 확인한다. 아래 예시는 discord.js v14 기준 접속 및 메시지 응답 예제이다.
// index.js
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });
client.once('ready', () => console.log(`Ready: ${client.user.tag}`));
client.on('messageCreate', msg => {
if (msg.content === '!ping') msg.reply('pong');
});
client.login(process.env.BOT_TOKEN);
- 환경 변수는
.env파일과dotenv로 관리하여BOT_TOKEN을 로컬에서 주입한다. - 테스트용 **테스트 길드(Test Guild)**를 만들어 봇을 초대하고 명령을 실행해 확인한다.
2단계: 자동화된 유닛/통합 테스트 추가
jest를 사용해 핵심 로직(명령 파서, 핸들러)만 단위 테스트로 분리한다.- 디스코드 API 호출은 목(Mock)으로 대체하여 네트워크 의존성을 제거한다.
package.json 스크립트 예:
{
"scripts": {
"start": "node index.js",
"test": "jest --runInBand"
}
}
단위 테스트 예:
// __tests__/command.test.js
const handleCommand = require('../commands/handleCommand');
test('ping returns pong', () => {
const res = handleCommand('!ping');
expect(res).toBe('pong');
});
3단계: 디스호스트에 배포 및 환경 구성
- 디스호스트 환경 변수 설정에
BOT_TOKEN,GUILD_ID,NODE_ENV등을 등록한다. - 프로세스 관리는 PM2 또는 Docker 사용을 권장한다.
PM2 예시:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'discord-bot',
script: './index.js',
env: { NODE_ENV: 'production' }
}]
};
간단한 Dockerfile:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "index.js"]
- 배포 후 로그(
console.log,process.on('unhandledRejection'))를 확인하여 초기화 문제나 인증 오류를 즉시 파악한다.
4단계: 런타임 문제 디버깅 및 운영 팁
- Intents 확인:
MessageContent,GuildMessages등 이벤트에 필요한 인텐트를 코드와 디스코드 개발자 포털 양쪽에서 활성화한다. - 디버그 로깅 활성화:
DEBUG=discord.js:*또는 어플리케이션 내 상세 로그를 통해 연결/이벤트 흐름을 추적한다. - 테스트/프로덕션 분리: 테스트용 토큰과 프로덕션 토큰을 분리하고 테스트는 별도 길드에서 실행한다.
- 재시작 정책: 디스호스트에서 자동 재시작/헬스체크 설정을 통해 다운타임을 최소화한다.
마무리
디스코드 봇 테스트는 로컬 검증, 자동화 테스트, 그리고 디스호스트와 같은 호스팅 환경에서의 환경 변수·인텐트·프로세스 관리를 순차적으로 점검하면 대부분 해결된다. 핵심은 환경 차이를 작게 유지하고 로그와 테스트로 동작을 빠르게 검증하는 것이다.