Tests passing right from the start will typically occur when one implemented something in a more general way than actually needed for the tests at hand. This is quite normal: unit tests can only provide a small, finite number of input values for a given function, but most functions are written for a huge range of possible input values. Often an implementation specifically designed for the current test cases would be more complicated than a more general solution. If that is the case, it would be cumbersome and error prone to artificially design the code in a way to work only for the test cases and fail for everything else.
For example, lets say you need a function to return the minimum of some values from a given array. You made an implementation, driven by a test with an array containing only one or two values. But instead of implementing this in a convoluted way by doing the comparisons on different elements (maybe only the first two elements), you call a minimum-of-array function from the standard library of your language ecosystem and so make the implementation a one liner. When you now decide to add a test with a five element array, the test will probably pass right from the start.
But how do you know then the test is not "green" because of a bug in the test itself? A simple and straightforward way to approach this is by making a temporary modification to the subject under test to make the test fail. For example, you could intentionally add a line if (array.size()==5) return 123
to your function. Now your five-element test will fail, so you know
- the test is executed
- the Assert call in the test is executed
- the Assert call in the test validates the right thing
which should give you some confidence into the test. After you have seen the test fail, undo the modification, and the test should pass again.
Alternatively, you can modify the expected result of a test: lets say your passing test contains an assertion like
int result = Subject.UnderTest(...);
Assert.AreEqual(1,result);
then you can edit the test and replace the "1" by "2". When the test fails (as expected), you know it works as it should, and you can undo the replacement and see if the test now becomes green. The risk of introducing a bug into the test by such kind of replacement is very small, so this is probably acceptable for most real world cases.
A different, maybe debatable way, is to set a breakpoint into the test and use a debugger to step through it. That should also give you some confidence the test code is actually executed, and gives you the possibility to validate the path through the test by step-by-step inspection. However, one must be very careful not to overlook errors in a code path specificially for a failing test. For complex tests, you may consider to do both - making it artificially fail and use a debugger to inspect it.