본문으로 바로가기
제품데스크톱 도구TASTECAD도면 확인TASTEFILES파일 관리TASTEFTP파일 전송TASTESSH원격 작업공간TASTEZIP압축과 해제개발 도구TASTECODERust 통합 개발 환경TASTESTUDIO통합 개발·테스트 환경TASTEETL데이터 통합(ETL)서버TASTEREMOTE원격 데스크톱 서버TASTEGEO공간정보 서버TASTEMAIL메일 작업공간시작하기다운로드문서구매모든 제품
마켓플레이스
소식
개발소식오늘의 개발 소식개발 문서프로그래밍 언어RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron알고리즘알고리즘 기초알고리즘 핵심알고리즘 심화실무 알고리즘
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스커뮤니티 안내
협업기술 전수홈페이지 구축데스크톱 앱 구축릴리스·결제 파이프라인판매 파트너문의
서비스원격 데스크톱설치 패키지 커스텀
TASTEDEV
제품

데스크톱 도구

TASTECAD복잡한 도면을 가볍게 열다TASTEFILES필요한 파일만, 가장 빠르게TASTEFTP파일이 오가는 가장 단정한 길TASTESSH서버와 나 사이, 더 단단한 연결TASTEZIP더 빠르게 묶고, 더 안전하게 풀다

개발 도구

TASTECODERust 앱을 편집 · 빌드 · 디버깅 · 테스트까지 한 창에서TASTESTUDIO편집부터 원격 테스트와 승인 기반 AI 수정까지TASTEETL값을 보며 데이터를 옮깁니다

서버

TASTEREMOTE우리 회사 서버로 운영하는 원격 데스크톱TASTEGEOGeoServer 호환 공간정보 서버를 Rust로 다시 세웁니다TASTEMAIL메일의 주도권을 다시 내 손에

시작하기

다운로드모든 제품 최신 판문서제품 사용법구매구독 · 영구 라이선스모든 제품모든 제품 한눈에
모든 제품
마켓플레이스소식
개발

소식

오늘의 개발 소식언어 · 프레임워크 · GitHub · AI 공식 발표개발 문서언어 · 프레임워크 · 알고리즘 안내서

프로그래밍 언어

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

프레임워크

프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular
서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express
앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron

알고리즘

알고리즘 기초복잡도 분석 · 정렬 · 탐색 · 기본 자료구조 · 트리와 힙알고리즘 핵심그래프 탐색 · 최단 경로와 최소 신장 트리 · 동적 계획법 · 탐욕 알고리즘 · 분할 정복 · 백트래킹알고리즘 심화문자열 알고리즘 · 수학과 정수론 · 비트 연산 · 구간 트리 · 유니온 파인드실무 알고리즘코딩 면접 풀이 전략 · LRU 캐시 · 레이트 리미터 · 일관된 해시
개발 문서 전체 보기
커뮤니티
프로젝트빌더와 작업 발견개발 로그결정과 시행착오프롬프트재사용 가능한 지시AI 도구 이슈Claude · Codex · Gemini 문제와 우회법쇼케이스완성된 결과커뮤니티 안내공개하고 함께 만드는 방식
협업
기술 전수Rust·egui 네이티브 앱 만들기홈페이지 구축10개 언어, 계정, 문서·다운로드데스크톱 앱 구축Rust·egui, WebView 없이릴리스·결제 파이프라인서명 · MSI·deb·rpm·AppImage · 해시판매 파트너소개하고 결제액의 30% 받기문의구축 · 제휴 · 투자 문의
서비스
원격 데스크톱브라우저로 내 컴퓨터에 접속설치 패키지 커스텀필요한 기능만, 설정은 미리
구매
KO
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
로그인
로그인
TASTEDEV

작은 도구부터, 더 좋은 개발까지.

support@tastedev.netTASTEDEV 후원하기
제품제품군구매문서다운로드마켓플레이스고객 지원
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스
정책개인정보처리방침이용약관구독 약관환불 정책커뮤니티 운영 정책
계정로그인가입하기
방문자
오늘
012345678901234567890123456789012345678901234567890123456789
어제
012345678901234567890123456789012345678901234567890123456789
누적 조회
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
상호
지엑스소프트
대표자
최영구
사업자등록번호
853-44-00368
주소
인천광역시 미추홀구 경인로 351 9층 V24
전화
+82-10-4404-1523
이메일
whitecalvin@tastedev.net
개인정보 보호책임자
최영구

© 2026 TASTEDEV제품 정보는 현재 검증된 개발 소스를 기준으로 합니다.출시·고도화 중

Dart 문서
Dart
Dart 시작하기기본 문법타입과 데이터라이브러리와 패키지오류 처리와 테스트핵심 개념
토론

Dart 안내서 · 5/6

오류 처리와 테스트

Dart는 예외(exception)로 오류를 알리고, try/catch로 처리합니다. Java와 달리 함수가 던질 수 있는 예외를 선언하지 않으며(검사 예외가 없음), 어떤 예외든 잡지 않으면 위로 전파됩니다. 이 장에서는 예외를 던지고 잡는 방법, assert, 그리고 package:test와 dart test로 테스트를 쓰고 실행하는 방법을 살펴봅니다.

Exception과 Error

Dart의 핵심 라이브러리는 문제를 두 종류로 나눕니다.

종류뜻예
Exception예상할 수 있고 처리해야 하는 실패FormatException, IOException, TimeoutException
Error프로그램의 버그, 보통 잡지 않고 고칩니다RangeError, TypeError, StateError, ArgumentError

입력 형식이 틀렸거나 네트워크가 끊긴 상황은 Exception으로 표현하고 호출한 쪽에서 처리합니다. 리스트 범위를 벗어난 접근처럼 코드가 잘못된 경우는 Error이며, 잡아서 숨기기보다 원인을 고쳐야 합니다. throw는 어떤 객체든 던질 수 있지만, 실제 코드에서는 Exception이나 Error를 구현한 타입만 던지는 것이 관례입니다.

class InsufficientFundsException implements Exception {
  InsufficientFundsException(this.balance, this.amount);
  final int balance;
  final int amount;

  @override
  String toString() => '잔액 부족: 잔액 $balance, 요청 $amount';
}

class Account {
  int _balance = 0;
  int get balance => _balance;

  void deposit(int amount) {
    if (amount <= 0) {
      throw ArgumentError.value(amount, 'amount', '0보다 커야 합니다');
    }
    _balance += amount;
  }

  void withdraw(int amount) {
    if (amount > _balance) {
      throw InsufficientFundsException(_balance, amount);
    }
    _balance -= amount;
  }
}

try, on, catch, finally, rethrow

on 타입으로 특정 예외만 잡고, catch (e, s)로 예외 객체와 스택 추적을 받습니다. finally 블록은 예외가 났든 안 났든 항상 실행되므로 자원 정리에 씁니다. 잡은 예외를 기록만 하고 다시 위로 던지려면 rethrow를 씁니다. rethrow는 원래 스택 추적을 보존합니다.

int parseAge(String input) {
  try {
    final age = int.parse(input);
    if (age < 0) throw FormatException('음수 나이', input);
    return age;
  } on FormatException catch (e) {
    print('형식 오류: ${e.message}');
    return 0;
  } catch (e, stackTrace) {
    print('예상하지 못한 오류: $e');
    print(stackTrace);
    rethrow;
  } finally {
    print('parseAge 끝');
  }
}

void main() {
  print(parseAge('42'));   // 42
  print(parseAge('abc'));  // 형식 오류 출력 후 0

  final account = Account()..deposit(100);
  try {
    account.withdraw(500);
  } on InsufficientFundsException catch (e) {
    print(e); // 잔액 부족: 잔액 100, 요청 500
  }
}

async 함수에서도 같은 문법을 씁니다. await한 Future가 오류로 끝나면 그 자리에서 예외가 던져지므로 try/catch로 감싸면 됩니다.

Future<String> loadConfig() async {
  try {
    return await readRemoteConfig();
  } on TimeoutException {
    return '{}'; // 시간 초과면 기본 설정 사용
  }
}

위 코드에서 TimeoutException은 dart:async에 있고, readRemoteConfig는 설정을 읽어 오는 임의의 비동기 함수입니다.

assert

assert(조건, 메시지)는 조건이 거짓이면 AssertionError를 던집니다. 개발 중에만 확인하는 가정을 적을 때 씁니다. assert는 기본적으로 꺼져 있고, dart run --enable-asserts로 실행하거나 dart test로 테스트를 돌릴 때, Flutter 디버그 모드에서 켜집니다. 프로덕션 빌드에서는 평가조차 되지 않으므로, 사용자 입력 검증처럼 항상 필요한 검사에는 쓰면 안 됩니다.

class Percent {
  Percent(this.value) : assert(value >= 0 && value <= 100, '0~100 사이여야 합니다');
  final int value;
}

package:test로 테스트 쓰기

Dart의 표준 테스트 도구는 package:test입니다. dart create로 만든 프로젝트에는 이미 들어 있고, 없다면 dart pub add --dev test로 추가합니다. 테스트 파일은 test/ 디렉터리에 두고 이름을 _test.dart로 끝냅니다.

// test/account_test.dart
import 'package:test/test.dart';
import 'package:bank/account.dart';

void main() {
  group('Account', () {
    late Account account;

    setUp(() {
      account = Account()..deposit(100);
    });

    test('입금하면 잔액이 늘어난다', () {
      account.deposit(50);
      expect(account.balance, equals(150));
    });

    test('잔액보다 많이 출금하면 예외', () {
      expect(
        () => account.withdraw(500),
        throwsA(isA<InsufficientFundsException>()),
      );
    });

    test('0 이하 입금은 ArgumentError', () {
      expect(() => account.deposit(0), throwsArgumentError);
    });
  });
}

expect(실제값, 매처)가 기본 형태이고, 매처 자리에 값을 그대로 쓰면 equals로 비교합니다. 자주 쓰는 매처는 equals, isTrue, isNull, contains, hasLength, greaterThan, isA<T>(), throwsA, 그리고 throwsArgumentError나 throwsStateError 같은 이미 만들어진 예외 매처입니다. setUp과 tearDown은 각 테스트 앞뒤에, setUpAll과 tearDownAll은 그룹 전체 앞뒤에 한 번 실행됩니다. 테스트 함수를 async로 쓰면 테스트 실행기가 그 Future가 끝날 때까지 기다립니다.

dart test 실행하기

dart test                               # test/ 아래 모든 테스트
dart test test/account_test.dart        # 파일 하나
dart test --name "입금"                  # 이름에 맞는 테스트만
dart test --reporter expanded           # 테스트마다 한 줄씩 출력
dart test --coverage=coverage           # 커버리지 데이터 수집

실패한 테스트는 기대값과 실제값, 실패한 위치를 함께 보여 줍니다. CI에서는 dart analyze, dart format --set-exit-if-changed ., dart test를 차례로 돌리면 기본적인 품질 검사가 됩니다. Flutter 프로젝트는 같은 package:test API를 바탕으로 한 flutter test를 씁니다.

정리

Dart는 예상 가능한 실패를 Exception, 버그를 Error로 구분합니다. on으로 특정 예외를 잡고, catch (e, s)로 스택 추적을 받으며, finally로 정리하고, rethrow로 다시 던집니다. assert는 개발 중에만 확인하는 가정에 쓰고, 테스트는 package:test의 test, group, expect로 쓴 뒤 dart test로 실행합니다.

이 장에 대해 질문이 있나요?
이전 장라이브러리와 패키지다음 장핵심 개념

댓글 0개

인기 댓글순최신순

로그인 · 로그인하면 댓글을 남길 수 있습니다.