Eiffel contracts are relatively primitive compared to the more modern Racket and Pyret contracts. Eiffel contracts are basically limited to assertions and don't support contracts on higher order function arguments, refinements, etc.
There is also the whole dynamic typing thing. Eiffel is still fully statically typed.
In terms of my opinion of Racket/Pyret, though, there's been a number of Ruby projects to do similar stuff to this over the years, since it's trivial to add (just add a class method that redefines a method and wraps it in code to execute the contracts), and a lot of Ruby newbies try to find ways of adding back the restrictions they've lost when moving from statically typed languages.
Invariably they've ended up dying or not getting much interest, largely because a large part of the appeal of dynamic languages for a lot of people is that the code reads simple. In the Ruby world at least, aesthetics is a big deal. And putting the tests inline destroys that aesthetic and makes it harder to read the code.
Especially because tests tends to be trite and repetitive and contain a lot of stuff that is obvious to a human when you have the code right in front of you.
Especially when they go beyond documenting contracts that are intended to bind subclasses to an interface.
That code readability is important.
I have a prototype for my own Eiffel inspired language with DbC support, and my own experience with it was that as much as I love the idea, even Eiffel level contracts are bordering on being too verbose, for these reasons.
Pull them out into separate files, and they're a lot more acceptable, but then what is the difference from any other unit testing framework?
This "static" vs "dynamic" distinction is largely artificial. Every program has parts that make sense to think of as "static" and parts that will be very "dynamic", and the ratio of these two differs from program to program (and even within a program, from day to day).
The same goes for making statements about programs.
Therefore, in Pyret, we recognize that there are lots of different levels at which we make statements about our programs: from tests through types to specifications, spanning both static and dynamic aspects. They not only aren't in conflict, they're even related. Most languages include only a subset of them or make them appear to be disjoint. In contrast, in Pyret, we're already working on linking these to one another, and are going to keep pushing in this direction.
Languages that leave out one or more of these end up forcing users to reinvent these wheels for themselves (because they're each good ideas that people inevitably want). But by forcing people to reinvent a wheel, they end up giving users ad hoc versions of these tools, and also introduce friction between these parts. (E.g., as Robby Findler found several years ago, just about every single bolted-on DBC system had significant limitations or errors.)
There is also the whole dynamic typing thing. Eiffel is still fully statically typed.