本文へ移動
cccskills
無料GitHub で公開

qt-test-framework

Authors and runs Qt Test - the first-party C++ unit + GUI test framework that ships with Qt 6 (via the `QtTest` module header). Covers the `QTEST_MAIN` / `QTEST_APPLESS_MAIN` / `QTEST_GUILESS_MAIN` entry-point macros, the `QObject` private-slot test pattern, `QVERIFY` / `QCOMPARE` / `QFETCH` assertions, GUI event simulation (`QTest::mouseClick`, `QTest::keyClick`, `QTest::touchEvent`), `QSignalSpy` for signal introspection, `QBENCHMARK` for performance regression, and the `-o file,junitxml` CI output. Use for in-process testing of Qt widgets, QObject signal/slot chains, and Qt Quick / QML application logic; for out-of-process Qt-app driving, use an OS-native accessibility driver instead.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qaスター 13(GitHub 13 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(3)

  • SKILL.md11.6 KB
  • .tessl-plugin/plugin.json830 B
  • references/qt-gui-signal-benchmark.md2.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

qt-test-framework

Overview

Qt Test is a framework for unit testing Qt-based applications and libraries (qtover), providing standard unit-testing primitives plus Qt-specific extensions for GUI event simulation, data-driven tests, and benchmarking. The QTest namespace carries the verification macros (QVERIFY, QCOMPARE), data handling (QFETCH, QFETCH_GLOBAL), and entry points (QTEST_MAIN, QTEST_GUILESS_MAIN, QTEST_APPLESS_MAIN).

Qt Test is in-process - the test executable links the Qt application code and emits events directly into the QObject event queue. It does not go through the OS accessibility tree (per desktop-test-strategy-reference), so it cannot drive a Qt app from a separate process. For out-of-process Qt driving see winappdriver (Windows via UIA after QAccessible is enabled), qa-mobile's xcuitest-suite with its references/macos.md (macOS), and the AT-SPI sections of desktop-test-strategy-reference (Linux).

When to use

  • Pure-logic unit testing of QObject-based classes - view models, data models, signal/slot graphs.
  • GUI tests of QWidget or Qt Quick views where the test executable can link the app code (in-process), avoiding the brittleness of out-of-process accessibility-tree drivers.
  • Benchmark + performance-regression checks via QBENCHMARK (qtns).
  • QSignalSpy-based assertions on signal emission order / arguments (qtidx).

Step 1 - Add Qt Test to the build

CMake (Qt 6, the canonical Qt build system per Qt 6 docs):

find_package(Qt6 6.5 REQUIRED COMPONENTS Test Widgets)

qt_add_executable(test_calculator tst_calculator.cpp Calculator.cpp)
target_link_libraries(test_calculator PRIVATE Qt6::Test Qt6::Widgets)
add_test(NAME test_calculator COMMAND test_calculator)

qt_add_executable runs moc automatically, which Qt Test slot discovery depends on.

Step 2 - Author a test class

The canonical shape per qtover - a QObject subclass with private slots as test functions:

#include <QtTest/QtTest>
#include "Calculator.h"

class TestCalculator : public QObject {
    Q_OBJECT

private slots:
    // initTestCase() / cleanupTestCase() run once per class
    void initTestCase();
    void cleanupTestCase();
    // init() / cleanup() run around each test function
    void init();
    void cleanup();

    void addsTwoIntegers();
    void emitsResultChangedSignal();
    void rejectsDivisionByZero();
};

void TestCalculator::initTestCase() {
    qDebug() << "Starting test suite";
}

void TestCalculator::addsTwoIntegers() {
    Calculator c;
    QCOMPARE(c.add(2, 3), 5);     // strict equality assertion
    QVERIFY(c.lastError().isEmpty());
}

QTEST_MAIN(TestCalculator)        // generates main() + QApplication
#include "tst_calculator.moc"     // include moc output

The four lifecycle slots are recognised by name (qtover): initTestCase (once before any test), cleanupTestCase (once after), init (per test), cleanup (per test).

Verify: build the target and run ./test_calculator -functions; confirm it lists your private-slot test functions before authoring data-driven or GUI cases. If none appear, the slots are not under private slots: or the #include "tst_*.moc" line is missing - fix and rebuild.

Step 3 - Pick the right entry-point macro

Per qtns, three entry-point macros choose what application class the harness instantiates:

MacroInstantiatesUse for
QTEST_MAINQApplicationWidget GUI tests
QTEST_GUILESS_MAINQCoreApplicationConsole / non-GUI logic tests
QTEST_APPLESS_MAINnoneTests of code that itself instantiates its own application object

Per qtover, if the test class defines a static public void initMain() method, "it is called by the QTEST_MAIN macros before the QApplication object is instantiated" - that's the hook for setting platform-specific environment variables before Qt's event loop starts.

Step 4 - Data-driven tests

Per qtns, QFETCH retrieves test data values; data is declared in a sibling _data() slot:

private slots:
    void addsTwoIntegers_data();
    void addsTwoIntegers();

void TestCalculator::addsTwoIntegers_data() {
    QTest::addColumn<int>("a");
    QTest::addColumn<int>("b");
    QTest::addColumn<int>("expected");

    QTest::newRow("zeros")       << 0 << 0  << 0;
    QTest::newRow("positives")   << 2 << 3  << 5;
    QTest::newRow("negatives")   << -2 << -3 << -5;
    QTest::newRow("overflow")    << INT_MAX << 1 << INT_MAX + 1;  // documents UB
}

void TestCalculator::addsTwoIntegers() {
    QFETCH(int, a);
    QFETCH(int, b);
    QFETCH(int, expected);
    Calculator c;
    QCOMPARE(c.add(a, b), expected);
}

Per qtover: "A test can be executed multiple times with different test data." Each newRow runs the test function once.

Step 5 - GUI event simulation

The QTest namespace provides keyboard (keyClick / keyClicks), mouse (mouseClick / mousePress), touch (touchEvent), and wheel event helpers (qtns); the full function-family table is in references/qt-gui-signal-benchmark.md.

void TestLoginWidget::successfulLogin() {
    LoginWidget w;
    w.show();
    QVERIFY(QTest::qWaitForWindowExposed(&w));

    QTest::keyClicks(w.usernameField(), "alice");
    QTest::keyClicks(w.passwordField(), "s3cret");
    QTest::mouseClick(w.submitButton(), Qt::LeftButton);

    QTRY_VERIFY(w.isLoggedIn());   // polls until true or times out
    QCOMPARE(w.currentUser(), QStringLiteral("alice"));
}

QTRY_VERIFY / QTRY_COMPARE (qtns) poll the predicate with a default 5-second timeout - the right primitive for waiting on async signal/slot completion without ad-hoc QTest::qWait sleeps.

Step 6 - Signal introspection with QSignalSpy

Per qtidx, QSignalSpy enables "easy introspection for Qt's signals and slots":

void TestCalculator::emitsResultChangedSignal() {
    Calculator c;
    QSignalSpy spy(&c, &Calculator::resultChanged);

    c.add(2, 3);

    QCOMPARE(spy.count(), 1);
    const QList<QVariant> args = spy.takeFirst();
    QCOMPARE(args.at(0).toInt(), 5);
}

This is the canonical pattern for asserting on signal emission order, count, and argument values - far more robust than connecting test-internal slots and counting invocations by hand.

Step 7 - Benchmarks

QBENCHMARK executes a block repeatedly to measure performance, reporting CPU time, walltime, or instructions-retired per the active back-end; use QBENCHMARK_ONCE for a single run (qtns, qtover). Example slot: references/qt-gui-signal-benchmark.md.

Step 8 - Run

Per qtover, a Qt Test executable accepts the following command-line options:

# List all test functions
./test_calculator -functions

# Extended verbose - shows each QCOMPARE / QVERIFY
./test_calculator -v2

# Run a specific test function
./test_calculator addsTwoIntegers

# Run a specific data row
./test_calculator addsTwoIntegers:negatives

# Write JUnit XML for CI ingestion
./test_calculator -o results.xml,junitxml

The -o filename,format flag per qtover supports formats: "txt, csv, junitxml, xml, lightxml, teamcity, or tap".

For multi-binary suites, ctest (driven by add_test from Step 1) runs the per-test executables and aggregates outcomes.

Step 9 - Parsing results

./test_calculator -o results-junit.xml,junitxml

The JUnit XML output feeds junit-xml-analysis for cross-platform aggregation alongside other JUnit-emitting test runners.

Step 10 - CI integration

Run the ctest suite across an Ubuntu / Windows / macOS matrix; Linux needs QT_QPA_PLATFORM=offscreen (the headless Qt platform plugin) for GUI-touching executables with no X / Wayland session. Full workflow: references/qt-gui-signal-benchmark.md.

Anti-patterns

Anti-patternWhy it failsFix
Public slots as test functionsmoc treats them as Qt signals/slots; harness ignores themPrivate slots (qtover)
Forgetting #include "tst_xxx.moc" for single-file testsLinker error - moc output not bundledInclude the generated moc file at the bottom of the .cpp (Step 2)
QTest::qWait(2000) between actionsFlaky; slow on fast machines, racy on slowQTRY_VERIFY / QTRY_COMPARE with predicate polling (qtns)
One mega-test slot exercising many flowsFirst failure stops the chain; coverage attribution lostOne slot per behaviour; share setup via init() (qtover)
Test depends on QTimer::singleShot(0, …) cascadeEvent-loop ordering variesDrive the event loop with QCoreApplication::processEvents() or QTRY_* predicates
Using QTEST_MAIN for headless CITries to instantiate QApplication without a displayQTEST_GUILESS_MAIN for non-widget tests; QT_QPA_PLATFORM=offscreen for widget tests (Step 10)
QSignalSpy connected after the actionMisses emissions; count is wrongConstruct QSignalSpy before the action that triggers the signal (Step 6)
Benchmarks mixed with correctness tests in the same slotIteration count masks regressionsSeparate _benchmark() slots; gate on regression in CI

Limitations

  • In-process only. Qt Test links the application code into the test binary; it cannot drive a separately-packaged Qt app - for that, use an OS-native accessibility driver.
  • No binary compatibility guarantee. Per qtidx, "no binary compatibility guarantee" is offered for Qt Test; recompile when the Qt version changes.
  • QApplication singleton constraint. Multiple QTEST_MAIN test binaries cannot share a process - each test binary runs as its own executable (which is why ctest exists).
  • GUI tests need a display platform. Headless Linux runners require QT_QPA_PLATFORM=offscreen or xvfb-run for widget- level tests.
  • No async-await ergonomics. Qt Test predates coroutines; async flows use QSignalSpy + QTRY_VERIFY or explicit event-loop driving - clunkier than Playwright's await-everywhere model.
  • Localised string assertions in QCOMPARE are brittle - prefer asserting on QString identifiers (object names) or enum values rather than displayed text.

References

  • Qt Test overview - qtover.
  • QTest namespace reference - qtns.
  • Qt Test module index - qtidx.
  • Sibling out-of-process Qt drivers: winappdriver (Windows), qa-mobile's xcuitest-suite (macOS), AT-SPI per desktop-test-strategy-reference (Linux).
  • Strategic frame: desktop-test-strategy-reference.
  • Downstream: junit-xml-analysis.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

testland のスキルをすべて見る

このスキルの問題を報告する