"Genuine question. I've read so many times about why I should practice TDD that I believe it in theory. But I've never seen a beginner's example that has actually seemed like it would provide the claimed benefits."
You need to find ressources to show you. I think when you see a thousands lines long codebase (divided in modules, classes, files, ...) with a test suite which fail immediately when a feature - you are not even working on so you where not meant to test immediately - breaks because of your current refactoring you thought was cool... Voila!
"Why is writing a test that takes one single specified input and checks for one single specified output "better" than just writing my code and then trying to break it by [metaphorically] hitting the "Do Not Press!" button, by throwing as much incorrect, malformed or otherwise "wrong" data at it, as possible. "
Did you see the test to fail before you write your code ? Maybe you don't need to write it haha. Maybe your test don't fail for the good reason. If you don't write your test before to see it to fail for the good reason, how are you sure you write code to actually do what it is supposed to ?
To me learning TDD is like learning martial art (I talk about my own experience haha). You need to practice. Some say it need discipline to stick to it enough, sometimes you are not convinced but you just push the experiment a bit further and there you get it !
Maybe you like to read, to watch, to just listen, or you need a mentor, someone experienced ? Hopefully there is a lot on internet.
I have three main ressources to get into TDD :
1) The book "Test Driven Development by Exemple" by Kent Beck
3) To help to start with refactoring, the Book "Clean Code" by Uncle Bob Martin
You can learn from blogs how to use test frameworks, what is a unit test, what does it mean to test first. But TDD is more, than that.
The examples given to discover TDD are not complex. But it is enough to get the workflow and sometimes to feel the pros.
In TDD the order of your tests is relevant and it is to me the main point on which I have to improve, the way you refactor is relevant too. I mean, sometimes I don't end up with the same implementation after doing the same exercise twice or more.
Then you go on more and more and more complex, with practice. ;)
Going back on you example:
"I've got some 'multiplying' code that should return 4 when passed 2 and 2 so I'm advised to write an "assert" test that returns 4 when I send it 2 and 2."
This is the nominal behavior (happy path) of your program. But I would not make it my "First Test". I would start with giving 0 and 0 returning 0. Then 1 and 1 returning 1. Then 1 and 2, ect... Each time you try to code only what the currently red test case needs to pass. Don't try to cover all the possible cases to early, it is not a sprint, it is a marathon.
"But what happens if I send it just 2?... or 2 and 2 and 2?... xxxxxxx or 2 and W? None of the examples of why it's so vital to write tests ever seem to cover this kind of thing? They just seem to show a test which returns the correct answer when given the correct data. But aren't many of the problems with software caused when a piece of code receives the wrong data in the first place?"
These are the error path of your program if it is supposed to handle them. As you said it, you will have to write tests to write code to cover them. One at a time : lower number of arguments, wrong input type, ...