Starting a TDD project from scratch

我只是一个虾纸丫 提交于 2019-12-03 05:49:30

TDD is not about unit testing - TDD is about driving your development and architecture with tests - with any type of automated tests you need. Do you see the point?

You are starting a new project and you probably have a set of features. You should have some acceptance criteria for features you are going to implement. These criteria can define your top level tests. Let's start either with an end-to-end test (this can be quite hard sometimes because it involves UI which doesn't exist yet) or integration test for these acceptance criteria. Once you have test which is failing you will continue to implement features related to the large test but each this feature will be again driven either with an integration or an unit test. The feature is completed if all top level tests pass.

If you skip large tests (end-to-end, integration) you will develop set of well tested units which will either do not work when integrated together or your architecture will not be very good because of local scope defined by unit tests. Integration and end-to-end tests give you a global scope.

This is described with large example (Java) in the book Growing Object-Oriented Software Guided by Tests.

I typically start from top to bottom. In your case I would start by writing the controller logic of your new page. By controller i mean the code layer just below the UI, mocking everything below. Then write the service layer (if you have one), mocking the data layer. Finally test the data layer also with mocks of the underlying classes (could be ISession in your case). Finally I would write a single integration test of each of the data layer methods and build the page (html).

Since you're attempting to drive development based on the tests, the way to get started is to start with your first feature. For example, let's assume that you have a feature to upload documents. Your first test may be:

public class DocumentManagementTest {
  @Test public void allowsDocumentUploads() {
    DocumentManagement dm = new DocumentManagement();
    Reader mockReader = new MockDocumentReader();

    Document result = dm.createDocument("Document name", mockReader);

    assertEquals("Document name", result.getName());
    assertEquals(0, result.getTags().size());
    assertTrue(mockReader.fileWasRead);
  }
}

I would definitely mock out the database to start with, database setup and teardown is expensive and brittle. Remember though to make very small steps, the test I showed above would have probably evolved over a few iterations. Followup tests that drive out more of the design may be:

@Test public void allowsDocumentRenames() { ... }
@Test public void allowsAddingTagsToExistingDocuments() { ... }
@Test public void showsErrorWhenAddingDocumentThatAlreadyExists() { ... }

Once you've built out a feature such as createDocument you can create a controller around it.

public void doPost(HttpServletRequest req, HttpServletResponse resp) {
  String name = req.getParameter("doc_name");
  Document d = docMgmt.createDocument(name, req.getInputStream());
  // Hand the newly created document to the view engine.
}

I wouldn't worry too much about writing tests for the controller, as it fairly low risk from a complexity standpoint (if the controller gets too much code then it may be a smell that the controller code belongs in another class, possibly your DocumentManagement class).

By building out the functionality one feature at a time and adhering to the SOLID principles you'll slowly grow a system with great test coverage and pretty good OO properties.

Cheers!

Brandon

Start simple, you'll add features incrementally later on. Start from a quick design: which classes, which responsibilities, which relationships. You can use CRC cards. Don't spend too much time on that design as you'll be able to improve it later by Refactoring. Pick up the simplest class to start with to implement a simple capability of the system. For instance, you could first create an empty page.

Start with one class ? what shall its objects do ? How can you verify this is done correctly ? This is the first test.

You could also start without the database, and store your documents in a flat file. You'll refactor to a database later. Then you can start with the getAllDocuments() function.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!