- the best place to look for newly introduced logic bugs is in the new or changed code;
- it’s best to test new/changed code by setting a breakpoint in the new/changed code and stepping into it with the debugger. This way you can be sure the new code is actually executed (not skipped by some weird business logic for example);
- every code path should be checked using the debugger and stepping into the code. Usually, the error handling cases have more bugs because that code path is rarely used;
- a fast way to force an error and test the error handling cases is to step into the code with the debugger and forcing/setting the desired value to some variable to make sure the code will follow the path you desire to test. Even though it’s common sense how to do it, most people don’t (unless they hunt a bug);
- danger zone: ||, &&, ??, ? operators. Why? Because the debugger will evaluate two conditions in a single step. Use debugger (immediate window) to analyze both conditions to check if they are as expected. Due to the short-circuit evaluation of the || operator for example, if the first condition is true, the second condition is not even evaluated. If in some cases, the code relies on the second condition to do something, and if the second condition was never tested, a bug might come up. So always check both code paths.