It is not completely true that all code that runs without error on R2012a (or b) will run with the same effect on R2018a (or b).
The release notes are a good place to start, but you will need to verify this for every function you want to use.
The way I do this is by creating a tester function. I run that on all releases/OSes I want to confirm compatibility with. If you have a look at my File Exchange submissions you will find examples. There may be some exceptions of the oldest submissions, but at least all newer ones are tested to work on everything since R13 (v6.5, june 2002), as well as GNU Octave.