Ian raises some concerns about testing interfaces in Python...
Unit tests aren't going to test across the boundaries where people are
proposing interfaces -- between loosely coupled components.
I am not sure I understand this point. Say I give you version 1 of a
component and the tests deemed "sufficient" for that component. Then I
give you version 2 of the component and the tests. If you are able to
run version 1 of the tests against version 2 of the component, that
should be a reasonable indicator that your own use of version 1 will
be compatible with version 2 of the component.
As the provider of the component, I need to know nothing about your
own use of that component, for reasonable definitions of "sufficient
tests".
Note also that interfaces are more explicit about contracts between
components than tests will be. For instance, an interface might demand
a method which is not yet being used in your code or your usage; the
interface makes it explicit that this method should still be defined,
and so predicts future developments, not just current developments
(half-implemented dictionary interfaces are a common example in
Python, where interfaces would motivate people to finish the work).
The original scenario was an upgrade to a component breaking backward
compatibility. If an upgrade provides a new feature then your old code
has not used that feature yet. I would not expect that to break
backward compatibility.
If an upgrade requires an old feature to require a new method of its
old consumers, then that *would* break backward compatibility. However
I would expect a reasonable set of tests from the component provider
to demonstrate this failure on their part to keep their old customers
happy.
Or two interfaces can match methods and signatures, but include extra
information about the semantic differences between those interfaces;
because it doesn't use duck typing, you won't accidentally mix
semantics (you have to explicitly say which, if any, of those
interfaces you support). This is particularly a problem with
interfaces that define only a small number of methods, or use common
methods like __call__. The only way to test these is with system
tests, and system tests are always incomplete, there's always some
code path or combination you haven't tested.
I guess I would need a specific example that cannot be tested by a
unit test. Certainly there are "big" tests that require a lot of
"units" to execute. But if each of those units were developed and
updated by a series of "unit" tests then I would expect those tests to
represent the "differences between those interfaces" as they exist
within each unit.
I am having trouble addressing this issue in the abstract. If it is a
frequent problem, I would look for ways to avoid it or break it into
smaller problems. Maybe this is a scenario where changing the language
would solve the problem. I just don't know, but I suspect there are
simpler ways to solve the problem on the basis that I have used Python
and several languages like Python and I have not run into this
scenario. That doesn't mean it isn't real, just that I have not
recognized it.