This question already has an answer here:
Testing code for correctness is important. Whether you do strict TDD or not, tests are really the only way a project can scale in size beyond a point where every team member can reasonably keep all the code knowledge loaded in their brains at once. After that point, tests are imperative in order to ensure future modifications don't break old logic (that or you're burning lots of resources doing the same thing manually).
The majority of people understand what I've stated above -- not much to argue with there. However, without much of a CS background, there is a lot open to interpretation. Naively, tests are likely to simply mean code that runs other code. While this is true, it doesn't paint the entire picture. Without much concern for proper testing, in my experience, people will tend to generate a bunch of integration or functional tests when asked to write unit tests.
Whether you aren't privy to testing nuances, or whether you simply choose to ignore them (in the interest of time or because you don't like testing), the result is the same. You get a project with a bunch of "confused tests", or tests that don't really respect the line between unit, functional, and integration styles of testing. In other words, you get tests that don't have a clear purpose other than to exercise as much code as possible. This is frustrating because it becomes increasingly cumbersome to parse the result of those tests for meaningful information.
- Did the tests fail because my remote server is down, or is my logic incorrect?
- Why is this "unit" test failing when I swap [un]related system component
And so on. How can you illustrate this distinction in a way that someone with a more engineering/get-it-done mindset can identify with? In essence, how do you make people care about the distinction?
Indeed, at a recent Android testing meetup at Twitter, the team asserted that full blown testing of software is a project in-and-of itself. And projects require resources. You can't just slip testing in on the side and not think much about it. Resources must be allocated and developers must take it seriously.
That's a good start, but we can't just throw retrospective resources and attention at code that's already been written. I'm curious, what approaches work to remedy a confused test landscape, and how you can prevent confused tests from happening in the first place?