The source of your confusion is probably thinking of "constexpr" as "evaluated at compile time". While there is truth to this idea, it is imprecise. I would invite you to drop your current understanding of "constexpr". Instead, start thinking of "constexpr" as "allowed in constant expressions". The language provides a precise definition for "constant expression"; for present purposes, it might be enough to consider a constant expression to be an expression whose value can be computed by the compiler. (If the compiler computes that value, it would need to evaluate something at compile time. This leads to that imprecise notion of constexpr.)
As you adjust your thinking to this new view, focus on the word "allowed". A person with a driver's license is allowed to drive a car but is not prohibited from riding a bicycle. A variable with the constexpr specifier is allowed in constant expressions but is not prohibited from other expressions.
Warning: When dealing specifically with integer variables, the constexpr specifier syntactically does not mean much more than const. If an integer variable is both declared const and initialized by a constant expression, then that variable is given the same privilege as a constexpr—it is allowed in constant expressions. This is a limited special case that supports pre-C++11 code. To clearly express intent (semantics) in new code, any variable used in a constant expression should be constexpr even if the language syntax allows it to be merely const.
During compile time, test doesn't exist yet, however, the above code compiles just fine.
Yes, code that has no syntax errors does tend to compile just fine. ;)
For variables, the only limitation imposed by constexpr that is not imposed by const is that the variable's initialization must be a constant expression (i.e. the value must be something the compiler can compute). You satisfied that by initializing id to 5 rather than to some value determined at run time. Your use of id after initialization is consistent with the use of a const int, so that use is valid for a constexpr int.
If test doesn't exist yet then how can getId exist during compile time?
I guess that depends on what you mean by "exist". In one sense, a function exists from the moment the compiler generates its object code. That code gets incorporated into the final executable. The object code does not need to be constructed during run time (only loaded from disk), so one could say the function started existing before the program was run. There are caveats, but the general idea is valid.
In a similar way, one could say that the class test exists during compilation, but I suspect you meant that instantiations (objects) of test don't exist yet.
If you had another meaning for "exist" in mind, then your claim that getId exists during compile time is possibly false. (In particular, getId is not executed during compilation.)
[From a comment:] What does it mean to say id is evaluated at compile time?
Correction: id can be evaluated at compile time. It can also be evaluated at run time. What actually happens depends on how id is used. If you do not give the compiler a reason to evaluate id, it does not have to.
[From a comment:] how can it evaluate id during compile time if getId (the parent) is only evaluated during run time.
The only place id is used in your code is in a return statement. The compiler is free to replace return id; with return 5; when it generates the object code for getId. (Not a particularly interesting example, but technically an evaluation of id at compile time. A more interesting example would use id in a context that requires a constant expression.)