Testing
Easy3D / Reference / Testing
Easy3D keeps a small test suite registered with CTest (EASY3D_BUILD_TESTS=ON by default). The interesting part is its two-tier design: CNA-free tests always build and run, while CNA-dependent tests run when CNA is linked — and are still compile-checked when it is not.
The test suite
| CTest name | Covers | Runs in default build? |
|---|---|---|
basics | Version info and other CNA-free helpers | Yes — CNA-free |
texture_atlas | TextureAtlas: named rects, AddGrid, UV math, throwing/non-throwing lookups | Yes — CNA-free |
camera | Camera3D, OrbitCamera, FollowCamera — executes real CNA matrix/vector math | No — needs CNA linked |
batches | BillboardBatch, CubeBatch, DebugDraw item storage | No — needs CNA linked |
cube_mesh | AppendCubeMesh/BuildCubeMesh — vertex counts, index validity, face positions, UV corners, winding | No — needs CNA linked |
Running the tests
Default build — 2 tests
cmake -S . -B build
cmake --build build
ctest --test-dir build # basics, texture_atlas
CNA-linked build — full suite
cmake -S . -B build -DEASY3D_LINK_CNA=ON
cmake --build build
ctest --test-dir build # basics, texture_atlas, camera, batches, cube_mesh
Why some tests need CNA linked
The camera, batch, and cube-mesh tests exercise CNA math at runtime — even just constructing Vector3/Vector2 values calls CNA's compiled constructors. So running them requires linking CNA. Compiling them does not: CNA's math types are declared in headers and only defined in CNA's .cpp files, so translating the test sources to object code needs only the headers.
The compile-check trick
In the default (no-CNA-link) build, the CNA-dependent test sources are still built as OBJECT libraries — compiled but never linked into an executable, so there are no undefined-symbol errors:
add_library(easy3d_test_camera_compilecheck OBJECT test_camera.cpp)
add_library(easy3d_test_batches_compilecheck OBJECT test_batches.cpp)
add_library(easy3d_test_cube_mesh_compilecheck OBJECT test_cube_mesh.cpp)
This is a cheap compile-only check that catches CNA header/API drift even in the light default build: if CNA renames a method or changes a signature, the default build breaks immediately instead of waiting for someone to run a CNA-linked build.
Test style
The tests are plain C++ programs with a tiny local CHECK macro — no test framework dependency. They print failures with file/line and return a non-zero exit code, which is all CTest needs:
#define CHECK(cond) \
do { \
if (!(cond)) { \
std::printf("FAIL: %s (line %d)\n", #cond, __LINE__); \
++g_failures; \
} \
} while (0)
This matches the project's "small, boring, testable" principle: when you add behavior that can be tested without linking all of CNA, you add or update a small test alongside it.