Generate Test Cases

I know that when solving a problem, it’s useful to generate test cases, solve them, and try to find problems in the answer/method of each test case. However, I have several questions about these, as I’m often unable to come up with test cases on my own.

  • Where do I get numbers from (assuming they aren’t random)? Say I have a number a at a particular stage/index. Now for a previous index, I have to backtrack and work through some math (set vars and solve) to find possible ranges/values for the other numbers based on a. A similar idea can apply to tracking forward as well.

However, I have other constraints like

  • at any point, numbers cannot be negative
  • numbers must be less than N
  • (for a range) low must be at least a given min or high must be at least a given max
  • etc.

I have a tendency to not work through the algebra and imagine generic values instead of concrete examples. This wastes time and is never efficient. However, sometimes finding appropriate values isn’t obvious, especially with different cases and/or constraints. How do you find examples and get past this?

  • What if it’s a complete search problem? How do I scale the problem down so I’m instead searching a smaller solution space that I can think through? And how do I come up with examples of smaller input data to scale down the problem?

  • When some part of the solution goes wrong, it takes effort to realize what went wrong. Even after trying cases and gaining some understanding, how do I find concrete examples to help fix that problem? Often, we have points on a number line (or any sequence), and the input size N varies. We have to place the points in such a way that highlights the error.
    Do we first fix N and then generate those many numbers? Do we first think geometrically/sequentially and then decide what N will be?

Any tips on how to think differently when coming up with test cases than solving the problem? If I notice a case (say R>N) that does not work, how do I think of a suitable example that demonstrates where my logic goes wrong? And how do I change my point of view; ex. in my code, I thought of monotonic sequences of spaces between consecutive points. Now when coming up with new numbers, how do I prevent falling into the same thinking I used with that faulty code in the first place?

I really want to learn how to think about test cases and how to develop the right mindset for sample inputs/outputs/debugging. Any tips whatsoever about the above will be deeply appreciated.
Thank you.

You mean generating/solving test cases by hand? Idk …

Yes. I meant, “it’s useful to generate test cases, solve them, and try to find patterns in the reasoning behind each solution”.

I’ve always written down ideas and numbers on paper before touching the code. I usually start trying different diagrams/points on a line/sample inputs and try to reason my way to the answer in each one. I do this on notebook paper. Is this not recommended? How would you develop intuition or reasoning for the problem if not solve test cases by hand?

If there is another method you are suggesting, please let me know and elaborate on it. Thanks!

Can you give an example of a problem where you have to worry about constraints like these?