SuperAPI AI Directory

ohos-dev-graphics-pixel-tests-generator

Testing & quality

View repository

Updated 10-16 07:28

About this skill

OpenHarmony graphics pixel tests

Use this skill to generate repository-style C++ tests for the OpenHarmony Rosen graphics pixel comparison framework; the target directory is usually graphic_test/test。

Generating a test case is not just writing a test function. A good result requires choosing the right test directory and RSGraphicTestType, following the style of adjacent files, correctly using the framework lifecycle, registering all render nodes that need to stay alive, and when adding a new .cpp , updating graphic_test/test/BUILD.gn。

Key prohibitions

  • Do not, in GetRootNode()->AddChild(...)、AddChildToSubWindow(...) or after creating a custom surface, forget RegisterNode(...); the node may be released early, and the screenshot will be blank or unstable.
  • Do not mistakenly write an independent test as GRAPHIC_TESTS; use it only when multiple test surfaces of the same fixture clearly need to be aggregated into one grid screenshot.
  • Do not create a new ohos_unittest target for an ordinary graphic test; a newly added .cpp should be added to graphic_test/test/BUILD.gn the existing category sources array in
  • Do not invent Drawing helpers, test helpers, or RenderService APIs out of thin air; check adjacent files and framework headers first.
  • Do not blindly add FlushImplicitTransaction and sleep in automatic screenshot tests; add them only when manual screenshots, immediately querying render results, or adjacent tests require it.
  • Do not use image resource paths that cannot be guaranteed to exist; prefer reusing the existing /data/local/tmp/... path in the same directory, or generate a PixelMap in code.

Starting steps

  1. Locate the real graphic_test root directory in the workspace.
  2. First read graphic_test/graphic_test_framework/include/rs_graphic_test.h、rs_graphic_test_ext.h, then read the existing test file closest to the requirement.
  3. Before generating, answer these checkpoints:
    • Purpose: Which specific rendering behavior or screenshot difference am I verifying?
    • Existing: Should I extend an existing test file, or is creating a new one more appropriate?
    • Type: Which RSGraphicTestType and which test macro does this scenario correspond to?
    • Pixels: What colors, images, borders, grids, or boundary values in the screenshot make the difference visible and stable?
    • Build: If adding a new file, which sources array of test/BUILD.gn should it be added to?
  4. After confirming the scenario, read only the relevant reference files in this skill:
    • references/framework-lifecycle.md: framework lifecycle, macros, screenshots, node lifecycle.
    • references/test-taxonomy-build.md: test placement location and test/BUILD.gn update rules.
    • references/code-patterns.md: idiomatic ways to write nodes, images, Canvas, animations, manual screenshots, subwindows, and PixelMap.
    • references/templates.md: compact starting template.
  5. Prefer following the style of local adjacent files. Reference files explain patterns; existing code is the authority on includes, helper names, and API availability.
  6. At minimum, perform text-level checks: macro names, namespace, include,RegisterNode, source list entry, and whether fabricated APIs exist.

Generation process

1. Determine the test classification

Choose the directory and RSGraphicTestType:

Scenario Common directory Common type
Node appearance, background, foreground, geometry, content display rs_display_effect/property_display or rs_display_effect/content_display CONTENT_DISPLAY_TEST
animation protocols, curves, custom modifier animations rs_display_effect/animation ANIMATION_TEST
NG shader/filter/effect/mask/shape visual effects rs_effect_feature/... EFFECT_TEST
open capability APIs such as PixelMap, font, symbol open_capability/... usually CONTENT_DISPLAY_TEST, or reuse existing local types
dirty regions, HWC, GPU composer, hybrid render, performance-related rendering rs_perform_feature/... reuse existing local types, commonly CONTENT_DISPLAY_TEST、GPU_COMPOSER_TEST、HYBRID_RENDER_TEST
surface capture, screen capture, multi-screen, accessibility, watermark, render group rs_func_feature/... usually CONTENT_DISPLAY_TEST
framework surface behavior rs_framework/... usually CONTENT_DISPLAY_TEST
Effect Kit NDK filter effect_kit/... EFFECT_TEST

If a related file already exists, prefer extending that file; only add a new file when the new feature boundary is clear and appending would make the old file messy.

2. Choose the test macro

  • Ordinary automatic screenshot pixel tests use GRAPHIC_TEST(TestClass, TYPE, TestName)。
  • GRAPHIC_TEST(TYPE, TestName) is only suitable for very small default fixture tests; most real test files define derived fixtures.
  • Use GRAPHIC_TESTSwhen multiple test functions need to be assembled into the same grid screenshot. Keep sharing SetScreenSize, and remember that the output file name does not include an individual test name.
  • Only use TestCaseCapture, sleep after FlushImplicitTransaction , or need to avoid automatic screenshots, use GRAPHIC_N_TEST。
  • Unless the task explicitly involves recording/playback, do not use GRAPHIC_D_TEST. The current test corpus mainly uses automatic and manual tests.

3. Build the fixture

Most files use this structure:

class ExampleTest : public RSGraphicTest {
public:
    void BeforeEach() override
    {
        SetScreenSize(screenWidth, screenHeight);
    }

private:
    const int screenWidth = 1200;
    const int screenHeight = 2000;
};

Only use SetSurfaceBoundswhen the test deliberately captures a sub-region or full-screen display behavior. For special display screenshots, sub-windows, and manual screenshots, refer to existing files in the same feature area.

4. Create visible and deterministic pixel output

Pixel comparison tests need clear, stable visuals:

  • Unless testing clipping or out-of-bounds behavior, place nodes within the configured screen range.
  • Use a grid layout for parameter matrices: based on screenWidth、screenHeight, rows and columns, calculate sizeX、sizeY、x、y。
  • Use highly contrasting backgrounds, borders, and image content so expected differences are visible.
  • When testing property clamping, cover boundary values: negative numbers, 0, intermediate values, 1, large values, invalid enum values, etc.
  • If each value should generate an independent image, use multiple GRAPHIC_TEST; if values should be compared in the same screenshot, use a grid within a single test.

5. Correctly add and keep nodes alive

Every node added to the scene and requiring rendering should be handled like this:

GetRootNode()->AddChild(testNode);
RegisterNode(testNode);

For parent-child node trees, if the local variables of the parent or child node may go out of scope, both parent and child must be registered. For sub-windows, add via GetRootNode()->AddChildToSubWindow(subId, node) , and still call RegisterNode(node)。

6. Only flush when necessary

Automatic tests usually rely on TearDown() for unified flush and screenshot. Add RSTransactionProxy::GetInstance()->FlushImplicitTransaction()。

When using FlushImplicitTransaction , you need to include transaction/rs_interfaces.h。

7. Update BUILD.gn when adding files

When adding .cpp , you must update graphic_test/test/BUILD.gn, inserting the relative path into the matching sources array, for example rs_display_effect_sources、rs_effect_feature_sources、open_capability_sources、rs_func_feature_sources、rs_perform_feature_sources、rs_framework_sources or effect_kit_sources。

Ordinary graphic tests should not create new ohos_unittest target. Existing RSGraphicTest target already aggregates the sources arrays of each category.

Necessary checks before completion

Before claiming completion, at minimum run a quick text check:

rg -n "GRAPHIC_(N_)?TESTS?|RegisterNode|FlushImplicitTransaction" path/to/new_or_changed.cpp
rg -n "relative/path/to/new_file.cpp" graphic_test/test/BUILD.gn

Then confirm:

  • The file has an Apache copyright header consistent with adjacent tests.
  • Includes match actual API usage, with no leftover template junk.
  • The code is located in namespace OHOS::Rosen。
  • Each test macro uses the correct fixture, type, and a unique test name.
  • Every scene node that needs rendering has been added to the root or sub-window, and RegisterNode。
  • Manual screenshot tests call the screenshot helper after flush/wait, and use GRAPHIC_N_TEST。
  • The new file has been added to the correct source array.
  • There are no leftover placeholder calls, such as DrawTextBlob(...)、paintSetColor or fabricated helper names.

Common failure modes

Failure symptom Cause Fix
Screenshot is blank Node not added, not registered, or has no visible properties Add the child, call RegisterNode, set visible bounds/color/image
Drawing code fails to compile Used a generalized Drawing API signature that does not match the local style Look at adjacent Drawing tests, use Brush/Pen and AttachBrush/DetachBrush
Test is not included in the build New .cpp not added to test/BUILD.gn category array Add the relative path to the correct sources list
Output grouping is wrong Standalone case mistakenly used GRAPHIC_TESTS Unless grid aggregation is explicitly needed, use GRAPHIC_TEST
Race condition in special queries before automatic screenshot Transaction not committed before querying render output Add FlushImplicitTransaction, and refer to the wait pattern of adjacent tests
Tests that depend on resources render empty Image path missing on device Reuse an existing /data/local/tmp/... path in the same directory, or generate PixelMap data in code

Characteristics of the current corpus

Currently graphic_test/test is mainly GRAPHIC_TEST automatic screenshots;GRAPHIC_N_TEST is heavily used for dirty regions, surface, screen, watermark, and manual screenshot flows.GRAPHIC_TESTS mainly appears in test_template style grid aggregation scenarios, and should be chosen carefully.

Most visual property tests do not assert pixel values in C++; instead they create deterministic rendering scenes, and the framework saves the PNG to /data/local/graphic_test/... before comparison.