There are a few techniques to make code more reliable:

Contracts

It is a set of pre and postconditions attached to functions or types, which can be functions themselves. They might be enforced both at compile and execution time, or by external tools against the code See: ADA 2012 implementation

Type system

The programming language forces the programmer to specify types. The compiler enforces the coherency of the types. Types are connected by inheritance and composition. Aspects can be specified via interfaces too.

Haskell excels at this. Type system

Tests

It is a set of functions that are executed independently of the execution. Dynamic languages such as python, ruby or JS are more focused on this approach. See TDD

Unit

Individual units, modules or functions of the program are tested. They are specially effective for side-effect free functions and well designed code.

    def mean(iterable):
        return sum(iterable)/len(iterable)
    
    class ModuleTestCase(unittest.TestCase)
        def test_for_mean():
            self.assertEqual(mean(range(3)), 1)
            self.assertRaises(ZeroDivisionError, mean, [])
    

Behavior/Case

Domain behaviors are tested. Behaviour driven development uses this as a premise as well. It uses a DSL specifically designed for the purpose of testing.

The idea is to test bigger sections of the code that follow certain behaviours associated with the Domain.

Formal proof

Proving correctness of the algorithm with some mathematical framework. It requires certain conditions specified in an abstract language. Formal proof is easier to do in functional languages due to their closeness to Algebra.

Abstraction

The quality of the code relies on the structure of it. A better structure implies less code or more robust on most scenarios

Domain

Making the code closer to the domain means that there is less chance for implicit concepts or unexpected behaviour. Domain Driven design is a set of techniques to achieve this purpose

Combination

DSL (Abstraction + Contract)

It involves the creation of new languages to deal with specific parts of the domain. It could be an internal or an external DSL. The parser of the language enforces the contract. The design of the language improves the quality through what it can describe