I'll add that, in my experience, in an untyped language, you don't need more or even different tests. Why? Because your in either world your boundaries are untrusted (and more than likely untyped) and then everything internal you can trust. User data, external systems, possibly internal systems, queues, storage..all that data is going to be varying degrees of unsafe and untyped. Those entry/exit points need to be fuzzed, unit and integration tested.
Again, I don't you're wrong, I just think you want/need the tests anyways (because typing isn't remotely enough).
I'd argue that what an expressive type system gives you is precisely this trust that internal data is passed around correctly.
In a dynamic langauge it's much easier to pass the wrong argument to a function, and I'd probably want to test for that...
You don't. Even 100% coverage isn't enough to map all the potential issues with incorrect types being passed around.
Types are a highly compact way of adding tests and documentation to your code that automatically integrates with everyone's IDEs and your CI pipeline. I don't know why you wouldn't use it if you think these things are useful.
"No thanks, I'd rather spend all my time writing these things I could write much faster using simple types."
To confirm this in a dynamic language, one would need to pass every possible permutation of every type available to the language to the function under test, to confirm that a function of, say, (string, int, boolean) would only ever work in the expected manner if the first argument was a string, the second was an int, and the third was a boolean.
Have you tried passing every possible permutation of typed arguments to your functions in test cases? If you haven't, then your program is less tested than a similar program written in a typed language. In a typed language you get all of that for free.