a simple CMake project compiles sources only when out-of-date, target are linked only when dependers are out-of-date. IIRC unit tests and integration tests are always run, which makes sense to me because a test may not directly depend on a target.
External projects are different, because they are treated as a self-contained unit. A common use is to drive the external project’s pipeline only once. Another option is to always build the project to bring it up-to-date. The test phase is always driven.
In the second scenario it would be beneficial to drive the test phase only when the external project is brought up-to-date, I think.