Danh mục

Growing Object-Oriented Software, Guided by Tests- P7

Số trang: 50      Loại file: pdf      Dung lượng: 0.00 B      Lượt xem: 12      Lượt tải: 0    
Thư viện của tui

Xem trước 5 trang đầu tiên của tài liệu này:

Thông tin tài liệu:

Growing Object-Oriented Software, Guided by Tests- P7: Test-Driven Development (TDD) hiện nay là một kỹ thuật được thành lập để cung cấp các phần mềm tốt hơn nhanh hơn. TDD là dựa trên một ý tưởng đơn giản: các bài kiểm tra Viết cho code của bạn trước khi bạn viết đoạn code riêng của mình. Tuy nhiên, điều này "đơn giản" ý tưởng có kỹ năng và bản án để làm tốt. Bây giờ có một tài liệu hướng dẫn thiết thực để TDD mà sẽ đưa bạn vượt ra ngoài những khái niệm cơ bản. Vẽ trên một...
Nội dung trích xuất từ tài liệu:
Growing Object-Oriented Software, Guided by Tests- P7276 Chapter 24 Test Flexibility complex. Different test scenarios may make the tested code return results that differ only in specific attributes, so comparing the entire result each time is misleading and introduces an implicit dependency on the behavior of the whole tested object. There are a couple of ways in which a result can be more complex. First, it can be defined as a structured value type. This is straightforward since we can just reference directly any attributes we want to assert. For example, if we take the financial instrument from “Use Structure to Explain” (page 253), we might need to assert only its strike price: assertEquals(strike price, 92, instrument.getStrikePrice()); without comparing the whole instrument. We can use Hamcrest matchers to make the assertions more expressive and more finely tuned. For example, if we want to assert that a transaction identifier is larger than its predecessor, we can write: assertThat(instrument.getTransactionId(), largerThan(PREVIOUS_TRANSACTION_ID)); This tells the programmer that the only thing we really care about is that the new identifier is larger than the previous one—its actual value is not important in this test. The assertion also generates a helpful message when it fails. The second source of complexity is implicit, but very common. We often have to make assertions about a text string. Sometimes we know exactly what the text should be, for example when we have the FakeAuctionServer look for specific messages in “Extending the Fake Auction” (page 107). Sometimes, however, all we need to check is that certain values are included in the text. A frequent example is when generating a failure message. We don’t want all our unit tests to be locked to its current formatting, so that they fail when we add whitespace, and we don’t want to have to do anything clever to cope with timestamps. We just want to know that the critical information is included, so we write: assertThat(failureMessage, allOf(containsString(strikePrice=92), containsString(id=FGD.430), containsString(is expired))); which asserts that all these strings occur somewhere in failureMessage. That’s enough reassurance for us, and we can write other tests to check that a message is formatted correctly if we think it’s significant. One interesting effect of trying to write precise assertions against text strings is that the effort often suggests that we’re missing an intermediate structure object—in this case perhaps an InstrumentFailure. Most of the code would be written in terms of an InstrumentFailure, a structured value that carries all the relevant fields. The failure would be converted to a string only at the last possible moment, and that string conversion can be tested in isolation. Precise Expectations 277Precise ExpectationsWe can extend the concept of being precise about assertions to being preciseabout expectations. Each mock object test should specify just the relevant detailsof the interactions between the object under test and its neighbors. The combinedunit tests for an object describe its protocol for communicating with the rest ofthe system. We’ve built a lot of support into jMock for specifying this communicationbetween objects as precisely as it should be. The API is designed to produce teststhat clearly express how objects relate to each other and that are flexible becausethey’re not too restrictive. This may require a little more test code than someof the alternatives, but we find that the extra rigor keeps the tests clear.Precise Parameter MatchingWe want to be as precise about the values passed in to a method as we are aboutthe value it returns. For example, in “Assertions and Expectations” (page 254)we showed an expectation where one of the accepted arguments was any typeof RuntimeException; the specific class doesn’t matter. Similarly, in “Extractingthe SnipersTableModel” (page 197), we have this expectation:oneOf(auction).addAuctionEventListener(with(sniperForItem(itemId)));The method sniperForItem() returns a Matcher that checks only the item identifierwhen given an AuctionSniper. This test doesn’t care about anything else in thesniper’s state, such as its current bid or last price, so we don’t make it morebrittle by checking those values. The same precision can be applied to expecting input strings. If, for example,we have an auditTrail object to accept the failure message we describedabove, we can write a precise expectation for that auditing:oneOf(auditTrail).recordFailu ...

Tài liệu được xem nhiều: