Тесты при разработке, физика и биология

В 72-м выпуске подкаста «Стек-оверфлоу» Джоел Сполский рассказывает об области применимости тестов при разработке и об особенностях современного прикладного программирования. Задолбался набирать, но всё интересно так (пропуски никак не обозначены):
If you say physics or chemistry, things that you say are going to happen, happen exactly the way you say they are going to happen. So, if you study Newtonian mechanics and you say that I wanna slide this thing along the table here and it’s gonna hit that thing at some speed. And absent any error or anything like that, that’s what’s gonna happen. And that’s what C programming was like. And that is the world for which test-driven development is perfect.

Now what happened is, we started building larger and more and more complicated things that have lots of those little mechanical things, that they are hard. And we’ve created so many levels of abstractions that what we are dealing with now, is if you plant a seed in a ground, it will grow into a tree. It works 98% of the time. And you can try to get 10 identical seeds somehow that you’ve cloned in seed-cloning device (don’t know what that would be) and plant them at exactly the same soil, give them all exactly the same conditions and you would get statistically normal variation in a tree height. And that’s what programming is like these days. So it is a lot more like biology than it is like physics or chemistry. There are so many levels in which it can go wrong.

So there’s a way to get a Google map in a native app on iPhone. And there is probably about 18 lines of code involved, I don’t know how many lines there are, but not a lot. You get this enormously complicated functionality that’s got extreme personality using very very few lines of code, and so the surface are to test is a lot of complicated functionality that all kinda has to work right, whereas the amount of code you actually wrote is 18 lines and you can almost inspect them faster than you can test that service or that complicated functionality you’re providing, which is going to be fine. Once you get it working, it’s gonna be ok. And where it’s gonna fail is in ways that you would never even dream of writing a test to test for.

I was doing some of that the other day, it’s a little project our listeners can take home. You are on an Apple Macintosh and you have a Quicktime movie of a video and an aiff file. And what you have to do... The Quicktime movie is the movie we gonna play at the beginning of Stack Overflow DevDays tomorrow morning, and the aiff audio is the voice of Daniel saying “Now welcome the host of Stack Overflow DevDays, Joel Spolsky” which has to play at the end of the first video. But not right at the end, you know, like 15 seconds before the end, so it’s like over the captions. Right? So anyway. Easiest way to throw this together is you make some AppleScript, it’s about 14 lines of applescript: start playing the movie, and than it’s got to maximize the player and all kinds of stuff, cause you don’t wanna see the player chrome on the screen. And you want to make sure that when that other audio plays, it stays in the background...

Let me give you an example of what kind of bugs I had while developing this little thing. There is a bug that by default QuickTime on Macintosh will only allow the frontmost QuickTime window to generate audio, the other one will be muted. You can turn this off. You would never know this in advance, until you try to write this app. And the minute you try writing this app, you say: why isn’t the audio playing from that background sound. And then you discover that there is an option in QuickTime and you have to figure out what is the Apple Event that I send to QuickTime to tell it to change it’s parameter so that the background apps can make music too. Because you wouldn’t know this in advance, you would not possibly have written a test for this. That’s what it is like to work at the very top level of the abstraction tree. I just want to play video, and then I want to play an audio behind it and I don’t want to see any chrome on the screen and want the movie to start exactly at the beginning, and you can’t even predict, no matter how hard you read the QuickTime Apple Events documentation, you will not be able to tell me whether or not the movie will start playing when you open it.
 5   2009   цитаты
2 комментария
Алисей Лебедев
Ох как лихо замутил ни о чем. Я могу ещё привести примеры, где автоматизированные тесты не дают должного эффекта. Чистка окон, игра в монополию, приготовление яичницы, уборка снега. Взять вот так неподходящий пример, и на нем показать что в нашем сложном современном мире старые методы не годятся. (Задумчиво) Нет, не годятся.
Алисей, в том-то и дело, что сегодня слишком часто автоматизированные тесты преподносятся как наиболее совершенное и, главное, универсальное средство. В итоге неопытные разработчики слишком полагаются на них, игнорируя всё остальное. Пример Спольского вполне подходящий и иллюстрирует главную идею: если программист не предусмотрел некую ситуацию при написании кода, то он не предусмотрит ее и при написании теста. При этом многие ситуации в принципе непредсказуемы, и выявить их можно только при тестировании программы в реальной среде.