The BIST is not enough
It's late, and the bottle is dangerously close to half-empty so let's rant.
You *can* get software with "built-in self tests", if you lay down the dollars but what do these do? I have never done hardware design but I do think that hardware has the advantages over software of far smaller state space and far higher locality (I'm not talking about fine-tuning impedances and propagation delays here). So you can probably test the various hardware subelements in the same way that you would run the test cases on a library of mostly side-effect free functions. But no BIST procedure is going to give you any assurance about a program that interacts with the user, slurps in third-party classes, runs on a flaky OS, talks over the network, gets stuff from a potentially bad database etc. What might save your program, apart from clean interfaces and clean code, is: well-though out exception handling, software rejuvenation (throwing away you run-time datastructures and starting from scratch if an error occurs), lots of runtime precondition and postcondition checking (through 'assert' for those who don't write in Eiffel). This will keep you on a meaningful trajectory through those parts of the state space where users are not being surprised.
Regarding software testing I never could make friends with "writing tests before the actual function". I have noticed that I you write the test code _alongside_ (not before, not after) your actual code, you really think differently about the interfaces your classes present to the outer world. You try to keep them neat and clean so that you understand them yourself. You leave out any unneeded complexity and generality because you _will_ have to test it, which is a pain. You write in fine-grained modular fashion as otherwise there is no way your code and your tests can properly interact. And last but not least, you put yourself into the place of the caller of your code, which quickly shows where confusions, unstated assumptions and ambiguous requirements lurk. Which makes you add more asserts.