Software systems are notoriously difficult to get right, and most often contain bugs. Some bugs are obvious and elicited simply by using the software. Some other bugs are less so and require expert knowledge of the inner working of the software to elicit them, by exploring less common unintended code paths, but still account for most of the dangerous and costly bugs, like e.g., memory bugs.
The cost of finding these bugs is usually high due to the level of expertise required, but automated testing methodologies like fuzzing and symbolic execution can help lower these costs.