Handling TDD Interface Changes

I started using TDD. As mentioned in an earlier question , the biggest difficulty is handling changes to the interface. How do you reduce the impact on your test cases as requirements change?

+4
source share
9 answers

Changing the interface requires updating the code that uses this interface. In this regard, the test code is no different from code other than it. Inevitably, the tests for this interface will need to change.

Often, when the interface changes, you find that "too many" tests are interrupted, i.e. tests for a significant part of unrelated functions turn out to be dependent on this interface. This may be a sign that your tests are too wide and need to be refactored. There are many possible ways that can happen, but here is an example that, I hope, shows a general idea, as well as a specific case.

For example, if the method of creating an Account object has been changed, and this requires updating all or most of your tests for your Order class, something is wrong. Most of your test order blocks probably don't care about how the account is made, so refactoring checks the following:

def test_add_item_to_order(self): acct = Account('Joe', 'Bloggs') shipping_addr = Address('123 Elm St', 'etc' 'etc') order = Order(acct, shipping_addr) item = OrderItem('Purple Widget') order.addItem(item) self.assertEquals([item], order.items) 

:

 def make_order(self): acct = Account('Joe', 'Bloggs') shipping_addr = Address('123 Elm St', 'etc' 'etc') return Order(acct, shipping_addr) def make_order_item(self): return OrderItem('Purple Widget') def test_add_item_to_order(self): order = self.make_order() item = self.make_order_item() order.addItem(item) self.assertEquals([item], order.items) 

This particular template is a Creation Method .

The advantage is that your test methods for ordering are isolated from how accounts and addresses are created; if these interfaces change, you have only one place to change, and not every test that is used to use accounts and addresses.

In short: tests are also code, and like all code, sometimes they need refactoring.

+6
source

I think this is one of the reasons for the fashionable argument that interfaces are used too much.

However, I do not agree.

When requirements change, so are your tests. Right? I mean, if the criteria for which you wrote a test are no longer valid, you should rewrite or exclude this test.

Hope this helps, but I think I may have misunderstood your question.

+6
source

There will be a blow. You just need to admit that it will take time to change the interface in order to change related tests first. There is no way around this.

However, then you think that the time you save without trying to find an elusive error in this interface later, and without fixing this error during the week of release, is completely worth it.

+4
source

β€œWhat should we do to prevent our code and tests from being dependent on requirements? It seems like nothing. Every time the requirements change, we need to change our code and tests. But maybe we can simplify our work? Yes, we can. The key principle is: encapsulating code that can be modified. "

http://dmitry-nikolaev.blogspot.com/2009/05/atch-your-changes.html

+1
source

You write tests before writing code for a new interface.

0
source

If you adhere to the Test First approach, theoretically there should be no effect of interface changes on your test code. In the end, when you need to change the interface, first change the test case (s) to meet the requirements, and then continue to work and change your interfaces / implementation until the tests pass.

0
source

In TDD, your tests are not tests. They are executable specifications. IOW: This is the executable encoding of your requirements. Always keep that in mind.

Now, it suddenly becomes apparent: if your requirements change, the tests must change! What is the whole point of TDD!

If you are making a waterfall, you will have to change your specification document. In TDD, you must do the same, except that your specification is not written in Word, it is written in xUnit.

0
source

When the interfaces change, you should expect the tests to break. If too many tests fail, it means that your system is too closely connected, and too many things depend on this interface. You should expect some tests to break, but not many.

Breakthrough tests is good, any changes in your code should violate tests.

0
source

If requirements change, your tests should be the first thing to change, not the interface.

I would start by modifying the interface design in the first relevant test, updating the interface to pass a new test. After updating the interface to pass the test, you should see that other tests are interrupted (because they will use the outdated interface).

You need to update the remaining failed tests with the new interface design so that they pass again.

Updating the interface in a test-driven manner ensures that changes are truly necessary and can be verified.

0
source

Source: https://habr.com/ru/post/1277216/


All Articles