I am trying to grasp the entire TDD methodology and as such, I don’t really know how to present this as a nice concise question so here is the long drawn out version. I seem to be experiencing a gap between the bowling (Martin), money (Feathers), and other similar game/simple examples and a fully functioning Enterprise app.
I am trying to figure out if I'm missing something like the concept of feature which as I understand it is something that adds business value or how to properly separate concerns when doing TDD and how each will then apply to the other. If that definition of what a feature is is a hard rule then things like logging and error reporting are not features. Does that mean TDD does not provide a means for logging and notifying?
Not trying to start any wars, I am pretty sure that is not the case so I then tell myself that the 'business value' must switch mid app from the customers business value to the businesses(the creator of the app) business value.
So I then try to switch it up like this common example From: As a math idiot When I enter 2, press add, enter 2, then press = I want 4 returned.
To: As an systems analyst monitoring the system When a user enters a function that results in an unhandled error I want the current state of the application, the exception thrown and stack trace entered into the log and send an email to the systems analyst distribution list.
And then to: As a business analyst ensuring all customers orders get processed When a user submits an electronic order and routing or accounting information does not validate I want the invalid accounting and routing information entered into the log and emailed along with the order file attached to the business analyst user group. unless the issue is because the database could not be reached to lookup the customer info due to network issues enter "database could not be reached to lookup the customer info due to network issues" into the log and send an email with the error message to the systems analyst distribution list.
Then that starts getting expanded into something that I think would be totally unacceptable: As a electronic order completion check When an order is received I want to check the x12 file is translated into a flat file and if it fails validation or translation log and email the error the order information and status is extracted and loaded to the database the flat file is sent to the queue to the as400 and the status is updated to the database the as400 sends an acknowledgement that they received the order and the status is updated to the database the as400 sends a flatfile confirmation and the status is updated to the database the confirmation is translated to an x12 and the status is updated to the database the x12 confirmation is routed appropriately and the status is updated to the database the confirmation is sent to the customer and the status is updated to the database if the x12 contains invalid data log the error, send an email and if the flat file is not pulled of the queue in 2 minutes log the error, send an email etc with n to the x power of possible error scenarios.
Even if you broke each into its own 'feature' you still have issues of logging, notifying systems analyst that an application threw an exception or a network error occurred or database not found etc. or business group that an order with an unrecognized account number was encountered etc. Adding any one of these into the class, as a method, attribute etc seems to violate the Single Responsibility principle. About that time things start spinning, I get dizzy, shortness of breath and heart palpitations
So, since it is so confusing to me that I am at a loss as to how to even pose this as an articulate question, I will try to sum it up like this.
How do you determine when/where and how to break these things down and separate them? It's easy to say break them down into the smallest piece that offers business value but when you can't have one piece without a number of other pieces what is the 'real' answer? All of that doesn't fit on one sticky.
I am open to answers that include more books, tutorials, video but I think if there were perhaps some real world applications that account for these types of things that adhere to the agile & TDD principles that would probably provide the most value? Admittedly I am relatively new to this but I've gone through the Martin/Feathers/Osherove books, I've seen a number of katas on tic-tac-toe, bowling, prime numbers etc but there’s no logging, no error reporting none of that kind of 'real world' stuff.
Let me try something else.
I get a file from the mainframe via ftp listing the orders to be placed with our suppliers, this file is called the summary file. I check for this file every 5 minutes. When there is a file I parse it then check to ensure that we received every order listed in this summaryfile via MQ. As a double check I also check for the existence of orders because if a summary file fails to be received we cannot ensure we received all the orders. With that being said does the following seem like I'm headed in the right direction?
Feature: Check for the presence of a summary file
In order to verify all orders were sent through MQ from the mainframe
a summary file must be found to determine the expected orders.
Scenario: A summary file has not been sent
Given a summary file does not exist
When I check for the existence of a file
Then I should sleep for 5 minutes
Scenario: A summary file has been sent
Given a summary file does exist
When I check for the existence of a file
Then I should validate the summary file
Feature: Validate the summary file
In order to process a summary file
summary file must be valid
Scenario: A valid summary file exists
Given a valid summary file
When I validate the summary file
Then I should upload the order details to the order details DB.
Scenario: An invalid summary file exists
Given a invalid summary file
When I validate the summary file
Then I should log the errors encountered
And email the erroneous file to the analyst email group
Repeat that again replacing summary with order. That is what I came up with.
Story splitting is a skill. It takes practice and it can be a difficult to become good at. This page explains the concept and gives links to resources about story splitting.
Here's one of your ideas that you were having trouble breaking up:
As a business analyst ensuring all customers orders get processed When a user submits an electronic order and routing or accounting information does not validate I want the invalid accounting and routing information entered into the log and emailed along with the order file attached to the business analyst user group. unless the issue is because the database could not be reached to lookup the customer info due to network issues enter "database could not be reached to lookup the customer info due to network issues" into the log and send an email with the error message to the systems analyst distribution list.
I see at least 4 stories in that paragraph:
As a BA, during order entry failure due to invalid account and routing information, I want account and routing information to be emailed to the BA group with the order file so that someone knows to get correct information and re-enter the order.
As a BA, during order entry failure due to invalid account and routing information, I want account and routing information entered into the log so that e have a permanent record of invalid information.
As a BA, during order entry failure due to "can't reach database" , I want the error message "database could not be reached to lookup the customer info due to network issues" emailed to the SA list so that database/network issues can be analyzed and improved.
As a BA, during order entry failure due to "can't reach database" , I want the error message "database could not be reached to lookup the customer info due to network issues" written to the log so that we have a permanent record of database/network issues.
And if your team is doing TDD well, it shouldn't be too difficult to implement each of those stories separately. Your code will be guarded with tests so that if someone working on card 4 breaks card 1's functionality, hopefully a test will catch it.
You definitely can't jump straight to your most advanced story (x12 file translation, yikes) - when you're dealing with an immature system, you have to decompose huge complicated features into comprehensible stories that you can estimate and deliver within an iteration.
I'll start with your second user story, which I hope will be sufficient:
As an systems analyst monitoring the system When a user enters a function that results in an unhandled error I want the current state of the application, the exception thrown and stack trace entered into the log and send an email to the systems analyst distribution list.
I'd begin by breaking this down further into two user stories:
1) As an systems analyst monitoring the system, when a user enters a function that results in an unhandled error I want the current state of the application, the exception thrown and stack trace entered into a log so that I can diagnose what happened and get a head start of correcting the problem.
2) As a system analyst monitoring the system, whenever there is an unhandled error, I want to be notified by email so that I'm more likely to address issues in a timely fashion.
You may not even need to articulate the first one as a user story in its own right, since modern development platforms (and their open-source communities) make logging trivial.
Say you get the business to sign off on user story number two. If you're not using a library to handle the emailing for you, you can immediately start practicing test-driven development just by considering what you want to do in your global error handler (which is already logging unhandled exceptions). It needs to:
Start thinking about the classes that will do those things, stub out the interfaces, and write some tests.
Your further elaborations on the requirements are all additional features. Your next requirement will entail writing different kinds of information to the log. After that you need to be able to add attachments to the email. And on it goes. Each story may involve multiple classes, so the single responsibility principle shouldn't be an obstacle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With