Agent Skillstekartik/sqflite › sqflite-common-test-suite

sqflite-common-test-suite

GitHub

sqflite通用测试套件,用于验证各种DatabaseFactory实现的兼容性。提供标准化测试用例覆盖SQL操作、事务及特性标志,确保不同平台实现的一致性。

sqflite_common_test/skills/sqflite-common-test-suite/SKILL.md tekartik/sqflite

Trigger Scenarios

运行sqflite数据库实现兼容性测试 验证自定义或官方sqflite工厂的合规性

Install

npx skills add tekartik/sqflite --skill sqflite-common-test-suite -g -y
More Options

Non-standard path

npx skills add https://github.com/tekartik/sqflite/tree/master/sqflite_common_test/skills/sqflite-common-test-suite -g -y

Use without installing

npx skills use tekartik/sqflite@sqflite-common-test-suite

指定 Agent (Claude Code)

npx skills add tekartik/sqflite --skill sqflite-common-test-suite -a claude-code -g -y

安装 repo 全部 skill

npx skills add tekartik/sqflite --all -g -y

预览 repo 内 skill

npx skills add tekartik/sqflite --list

SKILL.md

Frontmatter
{
    "name": "sqflite-common-test-suite",
    "description": "Use when running the shared sqflite conformance test suite against a DatabaseFactory implementation (ffi, ffi async, web, the native plugin or a custom one) with sqflite_common_test: SqfliteTestContext, SqfliteLocalTestContext, SqfliteTestContextMixin, SqfliteLocalTestContextMixin, all_test.dart run\/sqfliteTestGroup, the individual suites (raw_test, batch_test, open_test, transaction_test, type_test, exception_test, doc_test, wal_test walTests, sqflite_protocol_test), the capability flags supportsUri, supportsDeadLock, supportsWithoutRowId, supportsConcurrentRead, supportsMultipleInstances, strict, isPlugin, and databaseFactoryMock."
}

Shared sqflite test suite (sqflite_common_test)

sqflite_common_test is the conformance suite every sqflite implementation is validated with: give it a SqfliteTestContext wrapping a DatabaseFactory and it defines hundreds of test()s (open/upgrade, raw SQL, batch, transactions, types, exceptions, WAL, protocol) in the calling test file.

Guidelines

  • Dependency (not on pub.dev, publish_to: none), in dev_dependencies:
    dev_dependencies:
      sqflite_common_test:
        git:
          url: https://github.com/tekartik/sqflite
          path: sqflite_common_test
        version: '>=0.3.0'
    
    It pulls sqflite_common, sqflite_common_ffi, test, path and synchronized.
  • Two imports are enough for the common case: package:sqflite_common_test/sqflite_test.dart (the context types) and package:sqflite_common_test/all_test.dart (the whole suite). Import all_test.dart with a prefix (as all): every suite library exports a top-level run.
  • Entry points of all_test.dart: run(SqfliteTestContext context) and sqfliteTestGroup(SqfliteTestContext context) are the same thing; call it from main(), optionally inside your own group('ffi', ...).
  • Build the context with SqfliteLocalTestContext(databaseFactory: ...) — a file-based context (dart:io) that creates/deletes directories under the factory's databases path. Subclass it to flip the capability flags of the implementation under test.
  • Capability flags (all default to the conservative value in SqfliteTestContextMixin, override only what the implementation supports):
    • supportsUri (false): file: uri paths, true for ffi.
    • supportsWithoutRowId (false): CREATE TABLE ... WITHOUT ROWID.
    • supportsDeadLock (false): enables the multi-instance dead lock tests.
    • supportsConcurrentRead (false): only sqflite_common_ffi_async sets it.
    • supportsMultipleInstances (!isWeb): singleInstance: false.
    • supportsRecoveredInTransaction (false): native android/ios/macos only.
    • strict (true): the implementation rejects loosely typed queries.
    • isPlugin (false): true only for the native sqflite plugin factory. isWeb, isAndroid, isIOS, isMacOS, isLinux, isWindows come from the mixins; do not override them.
  • Always call the implementation initializer before run() (for ffi: sqfliteFfiInit() from package:sqflite_common_ffi/sqflite_ffi.dart).
  • Two test files running the suite in the same package run in parallel and share the databases path. Give each one its own directory with await factory.setDatabasesPath('${await factory.getDatabasesPath()}_suffix') in an async main() before run().
  • Add @TestOn('vm') (before library;) to a suite file using a VM-only factory, @TestOn('browser') for a web factory, in a package that also runs tests on the other platform.
  • Individual suites, when the whole suite is too much or one area fails: import package:sqflite_common_test/<name>.dart and call its run(context)raw_test, batch_test (run(context, noManualTransactionTest: true)), open_test, open_flutter_test, transaction_test, type_test, exception_test, exp_test (noMultipleStatement: true), doc_test (noLoggerTest: true), iterate_test, slow_test, statement_test, sql_command_test, database_factory_test, service_impl_test, issue_test. wal_test.dart exports walTests(context) (not run) and sqflite_protocol_test.dart exports run(SqfliteTestContext?), which accepts null and then checks the invoke-method protocol against an internal mock factory, no real database needed.
  • Context helpers usable in your own tests: await context.initDeleteDb('x.db') returns a deleted absolute path ready to open, createDirectory(null) gives the databases path, deleteDirectory(path), writeFile(path, bytes), isInMemoryPath(path), pathContext (a package:path Context).
  • package:sqflite_common_test/database_factory_mock.dart gives DatabaseFactoryMock / databaseFactoryMock: every method throws UnimplementedError. Use it to satisfy a DatabaseFactory parameter that the code under test must not call, never to fake results.
  • Anti-patterns: calling run(context) inside test() or setUp() (it declares tests, so it must run at main() level); sharing one databases path between suite runs; overriding a supports* flag to true to make a failing test disappear — it hides a real implementation gap.

Examples

Whole suite against the ffi factory

@TestOn('vm')
library;

import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_test/all_test.dart' as all;
import 'package:sqflite_common_test/sqflite_test.dart';
import 'package:test/test.dart';

class FfiTestContext extends SqfliteLocalTestContext {
  FfiTestContext() : super(databaseFactory: databaseFactoryFfi);

  @override
  bool get supportsUri => true;
}

void main() {
  sqfliteFfiInit();
  all.run(FfiTestContext());
}

Isolated databases path, so two suite files can run in parallel

@TestOn('vm')
library;

import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_test/all_test.dart' as all;
import 'package:sqflite_common_test/sqflite_test.dart';
import 'package:test/test.dart';

final _factory = createDatabaseFactoryFfi(noIsolate: true);

Future<void> main() async {
  sqfliteFfiInit();
  var dbsPath = await _factory.getDatabasesPath();
  await _factory.setDatabasesPath('${dbsPath}_no_isolate');

  group('ffi_no_isolate', () {
    all.run(SqfliteLocalTestContext(databaseFactory: _factory));
  });
}

Only a few suites, plus the protocol suite with no factory

@TestOn('vm')
library;

import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_test/batch_test.dart' as batch_test;
import 'package:sqflite_common_test/raw_test.dart' as raw_test;
import 'package:sqflite_common_test/sqflite_protocol_test.dart' as protocol_test;
import 'package:sqflite_common_test/sqflite_test.dart';
import 'package:sqflite_common_test/transaction_test.dart' as transaction_test;
import 'package:sqflite_common_test/wal_test.dart';
import 'package:test/test.dart';

void main() {
  sqfliteFfiInit();
  var context = SqfliteLocalTestContext(databaseFactory: databaseFactoryFfi);
  raw_test.run(context);
  batch_test.run(context, noManualTransactionTest: true);
  transaction_test.run(context);
  walTests(context);
  protocol_test.run(null); // mock based, no real database
}

Own tests reusing the context helpers

@TestOn('vm')
library;

import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_test/sqflite_test.dart';
import 'package:test/test.dart';

void main() {
  sqfliteFfiInit();
  var context = SqfliteLocalTestContext(databaseFactory: databaseFactoryFfi);

  test('my schema survives a reopen', () async {
    var path = await context.initDeleteDb('my_schema.db');
    var db = await context.databaseFactory.openDatabase(
      path,
      options: OpenDatabaseOptions(
        version: 1,
        onCreate: (db, _) =>
            db.execute('CREATE TABLE Item (id INTEGER PRIMARY KEY)'),
      ),
    );
    await db.close();

    db = await context.databaseFactory.openDatabase(path);
    expect(await db.query('Item'), isEmpty);
    await db.close();
  });
}

A DatabaseFactory the code under test must not touch

import 'package:sqflite_common/sqlite_api.dart';
import 'package:sqflite_common_test/database_factory_mock.dart';
import 'package:test/test.dart';

class Repository {
  Repository(this.factory);
  final DatabaseFactory factory;
  bool get isConfigured => true; // never opens the database
}

void main() {
  test('no database access on construction', () {
    var repository = Repository(databaseFactoryMock);
    expect(repository.isConfigured, isTrue);
  });
}

Version History

  • aaabf90 Current 2026-09-22 03:38

Same Skill Collection

packages/sqflite_common_ffi_async_test/skills/sqflite-common-ffi-async-test-suite/SKILL.md
packages/sqflite_common_ffi_async/skills/sqflite-common-ffi-async-factory/SKILL.md
sqflite_android/skills/sqflite-android-setup/SKILL.md
sqflite_common_ffi/skills/sqflite-common-ffi-testing/SKILL.md
packages_flutter/sqflite_ffi/skills/sqflite-ffi-flutter/SKILL.md
packages_web/sqflite_common_ffi_web_test/skills/sqflite-common-ffi-web-test-suite/SKILL.md
packages_web/sqflite_common_ffi_web/skills/sqflite-common-ffi-web-options/SKILL.md
packages_web/sqflite_common_ffi_web/skills/sqflite-common-ffi-web-setup/SKILL.md
sqflite_common_ffi/skills/sqflite-common-ffi-desktop/SKILL.md
sqflite_common/skills/sqflite-common-api/SKILL.md
sqflite_darwin/skills/sqflite-darwin-setup/SKILL.md
sqflite_platform_interface/skills/sqflite-platform-interface-implementers/SKILL.md
sqflite/skills/sqflite-crud-and-transactions/SKILL.md
sqflite/skills/sqflite-open-database/SKILL.md
sqflite/skills/sqflite-testing-and-platforms/SKILL.md

Metadata

Files
0
Version
aaabf90
Hash
93bfe524
Indexed
2026-09-22 03:38

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-22 09:59
浙ICP备14020137号-1