There are many reasons why we can’t say that we have awesome engineers getting out of college. Some reasons are simple, most obvious is: “we don’t teach them the right things”!
But there is also lack of real-life practice during studies, lack of teamwork and collaboration and of course setting wrong goals in front of students. It might sound depressing but we basically produce machines for code typing. If you don't agree, then put it this way, how many students you know that can think and act agile, understand importance and priorities, understand business at all?
First thing first, what essential thing we forgot to teach our students? We forgot to teach them things which last for long and not be obsolete as quick as many things in IT. You might be noticed that developers struggle to have knowledge in cool trendy topics, know latest releases of frameworks, experiment with new databases and languages but they are stuck if you ask them to list you 5 SOLID principles. Nowadays especially education institutions having a race to follow up with the latest technology, to offer courses in a latest cool languages, but at the same time make little effort to ensure that future engineers know about industry standards, discipline, and professional behavior.
Programming is not a military, but lack of discipline starts to cost way too much. Newcomers used to write a code without any tests, nobody ever asks them to do so. The only thing everybody asks them is to make the software work and do it fast! Discipline is considered as a second, third or fourth place in the desired skills list. Being able to: 1. code fast, 2. make things work and 3. working longer, is usually three things employer wants from developers, and education institutions are very successful in delivering this values.
How they enforce this values over students? Well, they first squeeze tons of things they think you have to learn on course. They ensure it is almost impossible to learn all this stuff with any quality. It is more look like you know a lot of things, there is a pile of terms which ring you a bell, but unfortunately, you have very little understanding of what is going on there. That’s why developers are fast, but they don’t follow any pattern, they don’t have any structure, just a pile of code.
There is also a problem with a higher or lower grade on college or course (A, B, C, D, E or 1 to 10 depending on school system). Just because you got the highest grade in the subject of some programming language does not mean that you are on top of the world for that language knowledge. Also, students have to keep in mind that without practice, their grade is worth zero in real life. You could ask why? Why then colleges have appraisals at all? Well, educational institutions use grade to compare your knowledge to some percentage or scale of teaching material they decide is good for you. I personally believe that grading students is harmful and produce unhealthy competing atmosphere instead of enforcing teamwork which is much closer to how real life will look like.
One interesting thing happening during the educational process and that’s evaluation period. Usually, there is time reserved for listening to what one teacher or group of teachers have to say. After you listen to all the material you have to go to the exam and prove that you did understand things and you can apply it to some examples. In most of the cases, students know what the teacher wants to see on the exam, so they can train themselves to pass the test. ! TRAP! If you didn’t notice so far, education institutions training people to pass the tests, they not give them the ability to apply new learnings it in the real world.
There is many students keep asking the same questions, is there a life after the test? The answer comes as a relief, usually right after successfully passing the test, students can even more successfully erase their short-term memory and free it for the next exam and repeat.
That leads to answer why TDD is so poorly applied in practice. Students were trained that they learn something, teacher tests them once and then they are free to forget. They are doing the same as a developer. They do a work, test it once, if it passes their observations they ship it to QA. QA usually find something, bug or unexpected behavior, not covered edge case etc, and return code back to the developer to redo it. Note the pattern you saw at college, students do something, pass it to the professor who then evaluates and return it back to the student if it’s not sufficient, or approves it. Basically, developers are not trained to take care of their testing and testing results.
When it comes to unit tests, there is also an interesting parallel with education. Developers like to “debug” a code, run it under different circumstances and observe the result of some variables in debug mode. Instead, they never actually wrote a test for something they expect and then run code against it. Why so? Because they don’t expect. Simple as that, they don’t know what to expect, because if you have to assume something you have to learn how it works. If you don’t understand how it works, then you will try it until it returns your desired outcome. Interesting enough, developers discovered that tactics from school. There, they had two variants of how to approach material, for example, math. They can learn meanings, deeply understand equations, and be able to apply them to any given problem. Or they could try numbers on the exam until it fits the desired outcome.
And this is still just brief overall why and where we failing to educate good IT engineers. It's also a depressing fact, that at the moment, that industry didn’t recognize urgency for change and didn’t create pressure on IT education institutions to change. Instead, it seems like they remain blind to this problems and keep going the way it looks easier for industry and commercial enough for education.