[Flutter] SQLite Test

Comely·2024년 11월 18일

Flutter

목록 보기
17/26

Dart 언어와 SQLite를 활용하여 데이터베이스를 먼저 만들었습니다.

w3shools.com/sql/default.asp
해당 사이트에서 SQL 학습을 추천드립니다.

SQLite의 데이터 타입

스토리지 클래스(storage class)라는 5개의 기본 그룹으로 나뉩니다.
아래는 SQLite의 주요 데이터 타입과 그 특징입니다.

TEXT----- 문자열로 저장 : TEXT, CHAR, CLOB
INTEGER- 정수로 저장 : INT, INTEGER, TINYINT
REAL----- 실수로 저장 : REAL, DOUBLE, FLOAT
BLOB----- 변환 없이 저장 : 명시적 BLOB 타입
NONE---- 특정 타입 없음 : 명시적 타입 없음

sqflite 코드

  • Table: 'note'
import 'package:sqflite/sqflite.dart';

class NoteDbHelper {
  Database db;

  NoteDbHelper(this.db);

  Future<Note?> getNoteById(int id) async {
    // SELECT * FROM note WHERE id = 1
    final List<Map<String, dynamic>> maps = await db.query(
      'note',
      where: 'id = ?',
      whereArgs: [id],
    );

    if (maps.isNotEmpty) {
      return Note.fromJson(maps.first);
    }

    return null;
  }

  Future<List<Note>> getNotes() async {
    final maps = await db.query('note');
    return maps.map((e) => Note.fromJson(e)).toList();
  }

  Future<void> insertNote(Note note) async {
    await db.insert('note', note.toJson());
  }

  Future<void> updateNote(Note note) async {
    await db.update(
      'note',
      note.toJson(),
      where: 'id = ?',
      whereArgs: [note.id],
    );
  }

  Future<void> deleteNote(Note note) async {
    await db.delete('note',
      where: 'id = ?',
      whereArgs: [note.id],
    );
  }
}

Sqflite Test

SQLite를 활용하여 데이터베이스 관련 코드를 테스트하는 예제입니다.
여기서 사용하는 데이터베이스는 메모리에만 존재하는 임시 데이터베이스로,
앱이 종료되면 저장된 데이터도 사라집니다.
테스트를 진행할 때마다 db를 생성하게 되고 close를 통해 db를 종료합니다.

테스트 코드를 통해 데이터베이스의 CRUD 작업(생성, 읽기, 수정, 삭제)을 검증할 수 있습니다.

라이브러리

sqflite_common_ffi

윈도우 사용시 오류가 있을 때 추가 라이브러리

sqlite3_flutter_libs

테스트는 다음을 검증합니다.
1. 데이터베이스에 테이블을 정상적으로 만들 수 있는지.
2. 데이터를 입력, 조회, 수정, 삭제하는 작업이 제대로 동작하는지.
3. 각각의 작업이 기대한 대로 수행되는지.

1. test 함수

이 코드는 Flutter의 테스트 라이브러리를 사용하여 작성된 단위 테스트입니다. test 함수는 특정 코드가 의도한 대로 작동하는지 확인하기 위해 사용됩니다.

test('db test', () async { ... });

'db test'는 테스트의 이름입니다.
async는 비동기 작업(예: 데이터베이스 작업)을 수행하기 위해 필요합니다.

2. 데이터베이스 생성

final db = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);

databaseFactoryFfi.openDatabase는 SQLite 데이터베이스를 생성합니다.
inMemoryDatabasePath를 사용하면 메모리에서만 동작하는 임시 데이터베이스가 생성됩니다.

3. 테이블 생성

await db.execute(
    'CREATE TABLE note (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, color INTEGER, timestamp INTEGER)');

execute로 note라는 테이블을 생성합니다.

테이블의 각 Colume은 다음과 같이 정의됩니다

  • id: 기본 키로, 자동 증가(AUTOINCREMENT).
  • title: 메모 제목.
  • content: 메모 내용.
  • color: 메모 색상(정수로 표현).
  • timestamp: 메모가 작성된 시간.

4. 도우미 클래스 활용

final noteDbHelper = NoteDbHelper(db);

NoteDbHelper는 데이터베이스 작업을 편리하게 하기 위한 헬퍼 클래스입니다.
데이터 삽입, 조회, 업데이트, 삭제 등의 작업을 이 클래스를 통해 수행합니다.

5. 노트 삽입

await noteDbHelper.insertNote(Note(
  title: 'test',
  content: 'test',
  color: 1,
  timestamp: 1,
));

새 노트를 데이터베이스에 삽입합니다.
title, content, color, timestamp 필드를 포함하는 Note 객체를 생성하여 전달합니다.

6. 노트 개수 확인

expect((await noteDbHelper.getNotes()).length, 1);

데이터베이스에 저장된 노트의 개수를 확인합니다.
expect 함수는 실제 결과와 기대한 결과가 같은지 비교합니다.
노트가 하나 저장되었는지 확인합니다.

7. 노트 조회

Note note = (await noteDbHelper.getNoteById(1))!;
expect(note.id, 1);

ID가 1인 노트를 데이터베이스에서 조회합니다.
조회된 노트의 ID가 1인지 확인합니다.

8. 노트 수정

await noteDbHelper.updateNote(note.copyWith(
  title: 'change'
));

기존 노트의 제목(title)을 'change'로 변경합니다.
copyWith는 기존 노트를 복사하면서 일부 필드만 변경하는 메서드입니다.

note = (await noteDbHelper.getNoteById(1))!;
expect(note.title, 'change');

수정된 노트를 다시 조회하고, 제목이 변경되었는지 확인합니다.

9. 노트 삭제

await noteDbHelper.deleteNote(note);
expect((await noteDbHelper.getNotes()).length, 0);

데이터베이스에서 해당 노트를 삭제합니다.
삭제 후 데이터베이스에 저장된 노트의 개수가 0인지 확인합니다.

10. 데이터베이스 닫기

await db.close();

데이터베이스 작업이 끝난 후 연결을 닫아줍니다.

전체코드 package: sqflite_common_ffi

import 'package:sqflite_common_ffi/sqflite_ffi.dart';

void main() {
  test('db test', () async {
    final db = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);

    await db.execute(
        'CREATE TABLE note (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, color INTEGER, timestamp INTEGER)');

    final noteDbHelper = NoteDbHelper(db);

    await noteDbHelper.insertNote(Note(
      title: 'test',
      content: 'test',
      color: 1,
      timestamp: 1,
    ));

    expect((await noteDbHelper.getNotes()).length, 1);

    Note note = (await noteDbHelper.getNoteById(1))!;
    expect(note.id, 1);

    await noteDbHelper.updateNote(note.copyWith(
      title: 'change'
    ));

    note = (await noteDbHelper.getNoteById(1))!;
    expect(note.title, 'change');

    await noteDbHelper.deleteNote(note);
    expect((await noteDbHelper.getNotes()).length, 0);

    await db.close();
  });
}
profile
App, Web Developer

0개의 댓글