Exploring “Growing Object-Oriented Software, Guided By Tests” in context of web applications development with Rails and rich UI. I keen to build sample app but am I on the right track or missing the point?
Given a part of ordering system where, among other features, user can create an order and make a payment. And given basic rails setup with extra gems for enabling rich UI. I’d like to explore how would tests looks like.
Quick, high level, look into architecture reveals the following key layers:
- Rich UI (REST client?)
- CRUD (REST server?)
- Yet another domain (whatever…)
While not as RESTful as defined by Roy T. Fielding, Rails embraces resource as a central model and makes it universal communication entity which crosses all layers. It forces us to define resources sooner and maintaining low coupling to its structure in every layer including tests.
And as long as it makes sense, I imagine the tests would looks like this:
End-To-End
Covers observable application behavior and interaction with 3rd party services.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
order_record
- persisted active record modelorder_page
- manipulates and assert UI (capybara page wrapper)manufacturing_queue
- external service
Rich UI
This layer enables interaction with the system in a convenient for the humans way. Basically it consists of a set of UI components, translates user activities into requests to the next layer and interprets responses.
The test for this layer would share matchers with end-to-end scenarios:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
new_order_record
- non persisted active record modelnew_payment_record
- non persisted active record modelorder_record
- persisted active record modelorder_page
- manipulates and assert UI (capybara page wrapper)application
- rails application runner (or wrapper)have_received_request
- custom matcher which decodes request details from the type and active record objects (similar to respond_with from Responders gem)
CRUD
Provides resource manipulation interface.
Basically level two in Richardson’s maturity model and Rails fully covers this layer, i.e. form input to output, from handling request/response, to persisting resources in database of choice.
The test for this layer might look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
new_*
- not persisted active record modelorder
- persisted active record modelmake_request
- helper method, makes HTTP request based on the type and resources specified (similar to respond_with from Responders gem)user_request_listeners
- mock object
Yet another domain
This is where “interesting” things happens as a side effect of resource manipulation. For example: payment resource creation would trigger payment processing behavior or “return order” creation would trigger behavior responsible for adjusting stock levels, cost prices, etc.
Test for this layer usually dive into details of business domain, covering rules, validations, exceptions, etc.