TDD strategy when implementing a multi-stage process? - tdd

At the moment I'm developing a piece of code which first gathers sentences from a set of documents, then tokenises these, then uses the results to analyse recurring frequencies of token sequences, including case variations (upper case/lower case/leading cap/other), then prints out the results.
Now I want to introduce two more stages before printing out the results:
1. firstly, removing "stop words" (i.e. words or short sequences the frequency of which can never be of interest, such as, in English, "the", "of the", "of which", etc.) - these stop words/"stop sequences" to be taken from a database table
2. secondly, bringing up a dialog enabling the user to identify sequences of new stop words, which would then remove the token sequences involved and also add the sequence in question to the database table.
The thing is, this is a multi-stage process, and I'm just wondering what TDD experts do faced with a situation like this: do I create a new test method for each individual stage...? The problem being that each individual stage requires the use of "live memory data" from the previous stage: another possibility could be to somehow serialise this data and then deserialise it when testing for the next stage... but then this would involve the app code doing things which were of benefit only for the testing code, i.e. it would mean tweaking ("distorting"?) the app code for the benefit of the testing code, which seems wrong in principle...
Also, if anyone can point me in the direction of a book or site which helps TDD newbs like myself go to "the next level" I would be very grateful.
later
To the person who marked this as "favorite": I've now got hold of a book called "Growing Object-Oriented Software, Guided by Tests", which is well-reviewed and appears to be for someone wanting to move from beginner to intermediate. First impressions good.
Any views on this book by experts also welcome, of course...

On the face of it, you seem to be building a pipeline. From what I can tell, you're currently implementing all of it within a single class, which stores both the data that's being worked on and implements the methods that do the processing. One approach that you could take would be to break down the problem into smaller chunks. Rather than having a single class, you have a class for each stage of the pipeline and another class for orchestrating the process which is responsible for plugging the stages together in the correct order.
So, scanning through what you've described, you appear to have the following processors:
DocumentReader (reads documents from somewhere into in memory document)
SentenceExtractor (document/list of documents in, list of sentences out)
1 or more SentenceAnalysers (sentences in, statistics out), you might want to break this down depending on the type of analysis and how complex it is.
StopWordExtractor (StopWordProvider and sentences in, sentences out)
There are additional supporting classes that would be needed, to support writing of new stopwords to the database and depending on how the stopwordprovider was implemented keeping it in sync as the user selects new ones.
Essentially, what I'm saying is that you appear to be doing too much in a single location. If you're really happy that the code as you've described it is a single unit, then there is nothing wrong with you testing it all in one place, but then your inputs will be your starting documents/sentences and your outputs will be the end of the process. If you agree with me that really, there are several distinct components involved in the process that could change independently, then I would suggest breaking the process down into smaller classes and testing that those perform as expected for given sets of inputs/outputs...

Related

Breaking a project's first User Story in to tasks [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I'm starting a new project from scratch and have written User Stores to describe how a given user will interact with the system. But, I'm having trouble understanding how to break the first user story in to tasks without the first one becoming an epic.
For example, if I were building a car and the first user story said something like "As a driver, I would like to be able to change the direction of motion so that I don't hit things.", that would imply a user interface (steering wheel), but also motion (wheels) and everything necessary to link those together (axle, frame, linkage, etc...). In the end, that first user story always seems to represent about 40% of the project because it implies so much about the underlying architecture.
How do you break user stories down for a new project such that the first one doesn't become an epic representing your entire underlying architecture?
You might want to think of your story as a vertical slice of the system. A story may (and often will) touch components in all of the architectural layers of the system. You might therefore want to think of your tasks as the work needed to be done on each of the components that your story touches.
For example, Let's say you have a story like In order to easily be able to follow my friends' tweets, as a registered user, I want to automatically follow all of my gmail contacts that have twitter accounts.
In order to accomplish this, you will have to pass through the UI layer, service layer, persist some data in the data layer, and make an API call to twitter and gmail.
Your tasks might be:
Add an option to the menu
Add a new gmail authentication screen
Add a twitter authentication screen
Add a contact selection screen
Add a controller that calls into your service layer
Write a new service that does the work
Save contacts to the database
Modify your existing gmail API calling service to get contacts
Add a twitter API calling service to follow selected contacts
There: That's 9 possible tasks right there. Now, as a rule, you want your tasks to take roughly 1/2 a day to 2 days, with a bias towards one day (best practice, for sizing). Depending on the difficulty, you might break down these tasks further, or combine some if they are two easy (perhaps the two API calling services are so simple, you'd just have a modify external API services).
At any rate, this is a raw sketch of how to break the stories down.
EDIT:
In response to more question that I got on the subject of breaking stories into tasks, I wrote a blog post about it, and would like to share it here. I've elaborated on the steps needed to break the story. The link is here.
When we started projects under a Scrum management style, the first set of tasks was always broad, or as you describe it: epic. That's inevitable, the framework of any project is usually the most important, largest, and time-consuming portion, but it supports the rest of the project. In order to pare down the scale on overwhelming-ness of how much there is to do see if you can list the MOST essential parts. Then work on defining those tasks as the starting points. Therefore you have a few tasks as starting points for a broad beginning. Hope that makes sense!
A user story describe the what while a task is more about the how.
There is no perfect formula, just add any task that describe how the user story is going to be implemented, documented or tested.
Keep in mind that a task should be estimated in hours, so try to scale and detail the tasks accordingly.
If you feel that you have too many tasks for a story (even if you have 1-8 hours long tasks), then maybe you should consider rewriting your user story in the first place because it's probably too complex.
Good luck
The story that you implement at the beginning can be refined over time. You dont need to think that every story has to be the final version that the user is going to use.
For example, in a recent project we had to develop an application which involved indexing various websites, and matching them against filters created by users, and finally alerting the user of matches (thing of it as google alert on steroids).
If you look at it from one perspective, there is only one story - "As a user I want to get alerts from matching pages". But look at it from another perspective of "what are the risks we want to mitigate". The first risk was that users wouldn't get relevant or better hits compared to google alerts. The second risk was in learning the technology to build this.
So our first user story was simply "As a user I want relevant hits", then we built just the hit matching algorithm on a hardcoded set of pages and hardcoded filters for some early users and got their feedback.
There might actually be a bit of back and forth here with multiple smaller stories to capture learning like "As a user I want more priority to be given to matches in the URL" etc.. these stories comes from the feedback as we iterate over what the early users consider "relevant hits".
Next, we broadened it to "As a user I want hits from specific websites" and we built the indexing architecture to crawl user specified sites and do hit matching on that.
The third story was "As a user I want to define my own filters", and we built this part of the system.
In this way we were able to build up the architecture piece by piece. Through most of the initial part, only early users could use the system, and many pieces of data were hardcoded etc.
After a point, early users could use the system completely. Then we added stories for allowing new users to register and opened it up to the public.
To cut a long story short, the story you implement first could implement only a small part of the final story, hardcoding and scaffolding everything else. And then you can iterate on it over time till you get the story that you might actually release to the public.
I've come to a crossroads with this issue in the past. User stories are supposed to be isolated so you can do them without any other stories, in whatever order, etc. But I found making that happen just made everything more complicated. To me this fell under the "Individuals and interactions over processes and tools" part of the agile manifesto - or at least my interpretation of it.
The ultimate goal is ship. And to ship you have to build, and to build you have to stop futzing with scrum and just get stuff done and make sure you track it.
So what we did was break a cardinal rule of stories and we made some tech stories like "create a preliminary schema". We also declared that some stories were dependent on others, and noted that on the back of the story card.
In the end I felt this type of story was few and far between, and the difficulty of the alternative justified the exception.

TDD is a top-bottom or bottom-top design?

In my memory, most people told me I should design from top to bottom. If I want to implement a web page, I should image or draw this page on paper and then divide it into some functionality. For each functionality, I try design the external API, and implement their inside respectively.
But in TDD, they say I should consider a very very small functionality(a method?) first, write its test, fail, implement it and pass test. Composing them is the last step. I can't image how it gets good API.
And most strangely, they say TDD is not only unit tests and also function tests. I think it means top-bottom. If there is a functionality A composed of methods B, C and D. Because of TDD I write the function test for A first. But... B, C, D are all unimplemented. Should I use three stubs? If B depends on other three methods?
I used TDD to write some small programs. But when I striked an application with GUI, I got stuck.
Since TDD starts with what you can see from the outside (of whatever item you are working on at the moment), I'm not sure how it could qualify as bottom-up.
Taking TDD to the extreme (e.g., as in XP, aka extreme programming), you would certainly start from the end-user perspective, and only ever write as much code as you need to pass the tests created so far. If you find yourself starting with the tests for some internal function before reaching the point where the higher-level tests (plus good design for the code you are writing to make those tests pass) require this routine, you are working on some other paradigm, not strict TDD – because there was no test telling you to write that method in the first place. Not that this is necessarily a bad thing, but any problems you have with that is not really one of the TDD methodology.
For GUI programming, of course, you have the standard problem of automating tests, even before you created code. I only know of good tools for web apps for that; if you have good pointers on this topic in the desktop case, I'd sure love to see them.
I've been heavily writing rspec tests for my rails projects keeping a ratio of about 1:1.6 between code/tests. I never really had an issue of what to write first or what it depends on. If the method A that i want to write consists of B and C, then i would first implement B and C, again using the proper testing. To me the sequence is not so important as long as the tests are good and precise.
So, I don't really use stubs the way you describe it, but only if the functionality is already there and i just want to bypass/circumvent it.
BTW, it is considered a top-down approach. This is an excerpt from Rspec Book :
If you ask experienced software
delivery folks why they run a project
like that, front-loading it with all
the planning and analysis, then getting into the detailed design and
programming, and only really integrating and testing it at the end, they
will gaze into the distance, looking
older than their years, and patiently
explain that this is to mitigate
against the exponential cost of
change—the principle that introducing
a change or discovering a defect
becomes exponentially more expensive
the later you discover it. The
top-down approach seems the only
sensible way to hedge against the
possibility of discovering a defect
late in the day.
I would say it's top down. Say I had a single PDF that had 4 distinct documents in it and I was writing software to split them into 4 individual documents instead of a single document, the first test I would probably write is:
// Note: Keeping this very abstract
#Test
public void splitsDocumentsAccordingToDocumentType() {
List docs = new DocumentProcessor().split(new SinglePdfWithFourDocs());
assertEquals(4, docs());
...
}
I would consider the DocumentProcessor.split() method to be similar to "A" in your example. I could now implement the entire algorithm within the single method split and make the tests pass. I don't even need "B" or "C" right? Knowing that you're a good developer and you cringe at the thought of that 1500 line method you would start to look for ways to restructure your code to a more suitable design. Maybe you see that two additional objects (responsibilities) could be split out of this code:
1) Parsing the contents of the file to find the individual documents and
2) Reading and writing of the document from the file system
Let's tackle #1 first. Use a couple of "Extract Method" refactorings to localize code related to the parsing of the contents then an "Extract Class" refactoring, pulling out those methods into a class named, say DocumentParser. This could be analagous to "B" in your example. If you'd like, you could move tests related to document parsing from your DocumentProcessorTest to a new DocumentParserTest and mock or stub the DocumentParser in the DocumentProcessorTest.
For #2 it's pretty much lather, rinse, repeat and you'll end up with something like a DocumentSerializer class, AKA "C". You can mock this as well in your DocumentProcessorTest and you now have no file I/O and have test driven a component that has two additional collaborators without having to design your entire class (with individual methods). Notice that we took an "outside in" approach, which really enables the refactoring.
Thanks

Designing a complex workflow diagram

We've got a surprisingly complex workflow that needs to be monitored by a quasi-technical employees with an in-house webapp. There's about 30 steps, some of which are manual (editing), some are semi-automated stop points (like "the files have been received" or customer approval of certain templates), and some are completely automated (file conversion, search indexing, etc). The flowchart for all of these steps is large and complicated, and three people might be working on three completely different steps at any one time.
How would you present this vast amount of information as usefully as possible to your users? Just showing the whole diagram seems like the brute force solution. But it's big, and it'll likely get bigger as we do more things. Not to mention the complexity necessary to encode this entire diagram in HTML.
I assume you don't want to show these just for entertainment or mockery, but help the users along the way, automating as much as possible, document the process etc. It would probably help if you clearly define the goals or purpose of your app.
I don't see a point in showing the entire workflow, except for "debugging the business rules" or maybe the clients want to see it.
If your goal is to help users do their job, I would present the state of the "project" (or whatever term fits better) is at, and possible transitions to other states.
The State might be multiple mostly independent variables, e.g. one might describe the progress of content - e.g. "incomplete" / "complete" / "reviewed by 2nd staffer" / "signed off by 2nd staffer", others might contain a schedule that is developed in parallel, e.g. "test print date = not scheduled", "print date = not scheduled", "final delivery = tomorrow, preferredly yesterday".
A transition might be "Seint to customer for review", "mark as content-complete", "content modified", etc.
Is this what you have in mind?
I propose to divide your workflow in modules and represent the active state for each module.
A module is a subset of your main workflow. For example it could be divided by tasks, person, roles, department, etc. This will greatly simplify the representation of the workflow. Let's says someone is responsible for data entry at many critical moments. We can group all his tasks in one module (or sub-workflow) containing the same activities, inputs, outputs and conditions. Modules could be inter-dependants and related.
A state is where we are located in a module. In simple workflows there is only one active task. In real life we are multi-threaded! So maybe in one module many states could be active at the same time. The state also includes active inputs, outputs and memory bits.
An input is something required to perform an activity for evaluation a boolean condition. It could be a document, a piece of data, a signal...
An output is something resulting from a task: an information, a document, a signal...
Enough definitions?
Then simply convert your workflow into a LADDER LOGIC and you have your states!
See Ladder Logic definition on Wikipedia
You display only active states:
Active task(s) for the module
Inputs required / inputs confirmed
Output required / output realized
Conditions to continue
Seems abstract?
Here is a small example...
Janet enters data in the system. She manages the green tasks of the diagram. We focus only on her work, not other tasks. She knows how to do 16 tasks in the workflow. We are waiting the following actions from her to continue, and her Intranet dashboard says:
Priority 1: You must send a PO to order enough pencils for the next month based on the sales report.
Task: Send a purchase order
Inputs: Forecast report from the marketing department
Outputs: PO, vendor, item, quantity
Condition for completion: PO sent and order confirmation received from supplier
Priority 2: You must enter into the financial system the number of erasers rejected by production
Task: Data entry
Inputs: Reject count from production
Outputs: Number of rejects
Condition for completion: data entered and confirmed
We do a lot of troubleshooting on automated production systems having hundreds of thousands ladder steps (the workflow is too complex to be represented in a whole). When the system is blocked we look at each module and determine what inputs are missing to activation task completion.
Good luck!
This sounds like the sort of application for which BPEL is suited.
Of course you don't want to re-architect your system right now. But there are a number of BPEL implmentations out there, some of which include graphical editing tools. One of these might help you in your current situation, because they are good at handling scope and hiding detail. So I think you might derive benefit from drawing your workflow as a BPEL diagram even if you don't do anything else with the language.
The Wikipedia page lists several of the available implementations. In addition, Oracle's JDeveloper IDE includes a BPEL Diagrammer as part of its SOA suite; unfortunately it is no longer part of the standard install but it is still available. Find out more.
Try doing it in layers. You have the most detailed layer done, now add additional docs with the details hidden, grouped into higher-level business processes. Users should be able to safely ignore some of those details, but it's good for them to have visibility of how their part fits in to the whole.
You may need more than one higher-level document.
You can use Prezi to present this information to users in a lucid manner.
Split and present the work flow into phases such that the end user is easily able to identify the phase he is currently in.
Display as many number of phases as the number of inputs. The workflow starts with 6 different inputs so display the six different buttons on screen enabling the user to select the input that he wants.
On selecting the button zoom into the workflow depicting the next steps. This would also help the user to verify the actions that he has done so far to reach the current states.
This would also help the user to verify the actions that he has done so far to reach the current states. But this way of presenting could become cumbersome for the users as the number of steps that he has completed goes up. Say the user has almost reached the end of the workflow. To check for the next step he should go through all the steps which might frustrate the user.
To avoid this you can split the complete work flow chronologically into 3-5 phases. The phases should be split logically. The ultimate aim would be not to overwhelm the users with the full work flow. Personally i would try to avoid the task involving this workflow if presented the way you have shown. No offense. I bet you also feel the same.
Could give you a better picture if you could re-post the image after replacing the state names with numbers.
I'd recommend having the whole flow documented somewhere, but in terms of what is distributed to users, how about focusing on task-oriented flows? No one user will be responsible for the entire process I would imagine.
For example, let's say I have 2 roles, A and B, and 6 tasks, 1 through 6, executed in order. Each task may have multiple steps but is self-contained (e.g. download the file, review, run process, review again, upload). A does the even tasks and B does the odd tasks.
A would need to know about those detailed steps that comprise tasks 2, 4, and 6 but not about what goes on in 1, 3, and 5. So hand A a detailed set of flows for the tasks he is responsible for, along with a diagram that treats each task as a black box.
If the flow can't be made modular in this way, you may want to review the process itself to see why it's so complex.
How about showing an example of a workflow scenario, that is, showing the transitions in one possible passing through the workflow? You could cater this to a specific user profile and highlight the pertinent states, dimming the others. This allows them to get a clear idea of the transitions by seeing a real-life example.

RPG dialogue engine / structure [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I've always been interested in the data structures involved in an RPG (Role-Playing Game). In particular, I'm curious about dialogue and events based actions.
For example: If I approach an NPC at point x in the game, with items y and quests z, how would I work out what the NPC needs to say? Branching dialogue and responding to player input seems as trivial as having a defined script, and user input causes the script reader to jump to a particular line in the script, which has a corresponding set of response lines (much like a choose your own adventure)
However, tying in logic to work out if the player has certain items, and completed certain quests seems to really ruin this script based model.
I'm looking for ideas (not necessarily programming language examples) of how to approach all of this dialogue and logic, and separate it out so that it's very easy to add new branching content, without delving into too much code.
This is really an open question. I don't believe there's a single solution, but it'd be good to get the ball rolling with some ideas. As more of a designer than a programmer, I'm always interested in ways to separate content and code.
For example: If I approach an NPC at
point x in the game, with items y and
quests z, how would I work out what
the NPC needs to say? Branching
dialogue and responding to player
input seems as trivial as having a
defined script, and user input causes
the script reader to jump to a
particular line in the script, which
has a corresponding set of response
lines (much like a choose your own
adventure)
However, tying in logic to work out if
the player has certain items, and
completed certain quests seems to
really ruin this script based model.
Not at all. You simply factor the conditionals into the data.
Let's say you have your list of dialogues, numbered 1 to 400 or whatever like the Choose Your Own Adventure book examples. I assume each dialogue may consist of the text spoken by the NPC, followed by a list of responses available to the player.
So the next step is to add the conditionals in there, by simply attaching conditions to each response. The easiest way is to do this with a scripting language, so you have a short and simple piece of code that returns True if this response is available to the player and False if it is not.
eg. (XML format, but could be anything)
<dialogue id='1'>
<text>
Couldst thou venture forth and kill me 10 rats, perchance?
</text>
<response condition="True" nextDialogue='2'>
Verily! Naught could be better than slaying thy verminous foes. Ten ratty
carcasses shall I bring unto thee.
</text>
<response condition="rats_left_in_world() < 10" nextDialogue='3'>
Nay, brother! Had thou but ten rats remaining, my sword would be thine,
but tis not to be.
</response>
</dialogue>
In your scripting language, you'd need a 'rats_left_in_world' function that you can call to retrieve the value in question.
What if you have no scripting language? Well, you could have the programmer code an individual condition for each situation in your dialogue - a bit tedious, not all that difficult if your dialogue is written up-front. Then just refer to a condition by name in the conversation script.
A more advanced scheme, still not requiring a scripting language, might use a tag for each condition, like so:
<response>
<condition type='min_level' value='50'/>
Sadly squire, my time is too valuable for the likes of thee. Get thyself a
farm hand or stable boy to do thy bidding!
</response>
You can add as many conditions in there as you need, as long as they can be easily specified with one or two values. If all conditions are met, the response is available.
It's interesting, there's seems to be a core idea being missed here. We're having a discussion that relates to a programmer performing the task. Indeed, the code examples above are coupled to code, not content.
In game development, it's the content developers that we programmers want to empower. They will not (this is very important) look at code. Period. Now and again you get a technical artist or technical designer, and they're wonderful and don't mind it; but, the majority of content authors are not technically inclined.
I understand the question is for your own edification; but, it should be pointed out that, in industry, when we solve these types of problems our end users (the people utilizing the technology we're developing) are not engineers.
A system like this (branching dialogue) requires a representation in a tool that is relatively intuitive to use. For example, Unreal's Kismet visual scripting system could be utilized.
Essentially, the data structures (more than likely a branching tree as it's easy to represent/debug/etc.) would be crafted by a programmer, as would the nodes that represent the object in script. The system with its ability to link to world objects (more than likely also represented by nodes in visual scripting), etc. would then be crafted and the whole kitten caboodle linked together in some glorious bit of elegant code.
After all of that, a designer would actually be able to build a visual representation of the dialogue branching in the visual scripting language. This would be map-encounter specific, more than likely. Of course, you could procedurally generate these; but, that's more of a programmer desire than a designer's.
Just thought I'd add that bit of knowledge and insight.
EDIT: Noticed there's an XML example. I'm not sure what other designers/artists/etc. feel about it; but, the ones I've worked with cringe at the idea of touching a text file.
I'd venture to say that most modern games (be they RPGs, action games, anything above basic card/board games) generally consist of several components: The display engine, the core data structures, and typically a secondary scripting engine. One example which was popular for a time (and may still be; I haven't even spoken to a game developer in years) was Lua.
The decision-making you're talking about (events, conversation branches, etc) is typically handled by the secondary scripting engine, as the scripting languages are more flexible and typically easier to use for the game's designers. Again, most of the real story-driven or game-driving logic will actually happen here, where it can be swapped out and changed relatively easily. (At least, compared to running a full build of all the code!)
The primary game engine combines the data structures related to the world (geometry, etc), the data structures related to the player(s) and other actor(s) needed, and the scripts to drive the encounters, and uses all of that to display the final, integrated environment.
You can certainly use a scripting language to handle dialogue. Basically a script might look like this:
ShowMessage("Hello " + hero.name + ", how can I help you?")
choices = { "Open the door for me", "Tell me about yourself", "Nevermind" }
chosen = ShowChoices(choices)
if chosen == 0
if hero.inventory["gold key"] > 0
ShowMessage("You have the key! I'll open the door for you!")
isGateOpen = true
else
ShowMessage("I'm sorry, but you need the gold key")
end if
else if chosen == 1
if isGateOpen
ShowMessage("I'm the gate keeper, and the gate is open")
else
ShowMessage("I'm the gate keeper and you need gold key to pass")
end if
else
ShowMessage("Okay, tell me if you need anything")
end if
This is fine for most games. The scripting language can be simple and you can write more complicated logical branches. Your engine will have some representation of the world that is exposed to the scripting language. In this example, this means the name of the hero and the items in the inventory, but you could expose anything you like. You also define functions that could be called by scripts to do things like show a message or play some sound effect. You need to keep track of some global data that is shared between scripts, such as whether a door is open or a quest is done (perhaps as part of the map and quest classes).
In some games however, scripting could get tedious, especially if the dialogue is more dynamic and depends on many conditions (say, character mood and stats, npc knowledge, weather, items, etc.) Here it is possible to store your dialogue tree in some format that allows easily specifying preconditions and outcomes. I don't know if this is the way to do it, but I've once asked a question about storing game logic in XML files. I've found this approach to be effective for my game (in which dialogue is heavily dependent on many factors). In particular, in the future I could easily make a simple dialogue editor that doesn't require much scripting and allow you to simply define dialogue and branches with a graphical user interface.
I recently had to develop something for this, and opted for a very basic text file structure. You can see the resulting code and text format at:
https://github.com/scottbw/dialoguejs
There is a tradeoff between sophistication of scripting and ease of editing for non-programmers.
I've opted for a very simple solution for the dialogue, and handle triggering of related game events separately in a secondary scripting language.
Eventually I might add some way of adding "stage directions" to the text dialogue format that are used to trigger events in the secondary scripting engine, but again without needing to put anything that looks like code in the dialogue file itself.
That's an excellent questions. I had to solve that a few times for clients. We started with an XML structure quite similar to yours, and now we use JSON. You can see an example here: http://www.branchtrack.com/projects/on029pq6.json or https://dl.dropboxusercontent.com/u/11433463/branchtrack/on029pq6.json (prettify it for readability).
Full disclosure: the link above is generated in BranchTrack, an online editor for branching dialogues, and I am the CEO. Feel free to ask anything.
I recently tackled a problem like this while making Chat Mapper. What I do is graphically plot out the dialogues as nodes in a tree and then each node has a condition and a script associated with them. As you traverse through the tree and hit a node, you check the condition to see whether or not that node is valid, and if it is, you execute the script associated with that node. It's a fairly simple idea but seems to work well from our testing. We are using a .NET Lua interpreter for the scripts.
For my solution I developed a custom text file format consisting of seven lines of text per node. Each line can be a strided list or just a text line. Each node has a position number. The last digit of the number is a type, so there are 10 different types of nodes, such as fresh questions, confirmations, repeating actions based on prior results, etc.
Each dialog activation begins with a select query to the data store whose results can be compared against members of a strided list, to match up with the appropriate node. This is more brutal than an if/then but it makes the text config file smaller since you don't need any syntax besides the stride separator. I use a system of wildcards to allow for select query results to be able to be inserted into the speech of the NPC.
Lastly there are API hooks to allow custom scripts to interface in, in case the easy config file is not enough. I plan to make a web app gui in nodejs to allow people to visually script the config files :D

TDD: Where to start the first test [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
So I've done unit testing some, and have experience writing tests, but I have not fully embraced TDD as a design tool.
My current project is to re-work an existing system that generates serial numbers as part of the companies assembly process. I have an understanding of the current process and workflow due to looking at the existing system. I also have a list of new requirements and how they are going to modify the work flow.
I feel like I'm ready to start writing the program and I've decided to force myself to finally do TDD from the start to end.
But now I have no idea where to start. (I also wonder if I'm cheating the TDD process by already have an idea of the program flow for the user.)
The user flow is really serial and is just a series of steps. As an example, the first step would be:
user submits a manufacturing order number and receives a list of serializable part numbers of that orders bill of materials
The next step is started when the user selects one of the part numbers.
So I was thinking I can use this first step as a starting point. I know I want a piece of code that takes a manufacturing order number and returns a list of part numbers.
// This isn't what I'd want my code to end up looking like
// but it is the simplest statement of what I want
IList<string> partNumbers = GetPartNumbersForMfgOrder(string mfgOrder);
Reading Kent Becks example book he talks about picking small tests. This seems like a pretty big black box. Its going to require a mfg order repository and I have to crawl a product structure tree to find all applicable part numbers for this mfg order and I haven't even defined my domain model in code at all.
So on one hand that seems like a crappy start - a very general high level function. On the other hand, I feel like if I start at a lower level I'm really just guessing what I might need and that seems anti-TDD.
As a side note... is this how you'd use stories?
As an assembler
I want to get a list of part numbers on a mfg order
So that I can pick which one to serialize
To be truthful, an assembler would never say that. All an assembler wants is to finish the operation on mfg order:
As an assembler
I want to mark parts with a serial number
So that I can finish the operation on the mfg order
Here's how I would start. Lets suppose you have absolutely no code for this application.
Define the user story and the business value that it brings: "As a User I want to submit a manufacturing order number and a list of part numbers of that orders so that I can send the list to the inventory system"
start with the UI. Create a very simple page (lets suppose its a web app) with three fields: label, list and button. That's good enough, isn't it? The user could copy the list and send to the inv system.
Use a pattern to base your desig on, like MVC.
Define a test for your controller method that gets called from the UI. You're testing here that the controller works, not that the data is correct: Assert.AreSame(3, controller.RetrieveParts(mfgOrder).Count)
Write a simple implementation of the controller to make sure that something gets returned: return new List<MfgOrder>{new MfgOrder(), new MfgOrder(), new MfgOrder()}; You'll also need to implement classes for MfgOrder, for example.
Now your UI is working! Working incorrectly, but working. So lets expect the controller to get the data from a service or DAO. Create a Mock DAO object in the test case, and add an expectation that the method "partsDao.GetPartsInMfgOrder()" is called.
Create the DAO class with the method. Call the method from the controller. Your controller is now done.
Create a separate test to test the DAO, finally making sure it returns the proper data from the DB.
Keep iterating until you get it all done. After a little while, you'll get used to it.
The main point here is separating the application in very small parts, and testing those small parts individually.
This is perfectly okay as a starting test. With this you define expected behavior - how it should work. Now if you feel you've taken a much bigger bite than you'd have liked.. you can temporarily ignore this test and write a more granular test that takes out part or atleast mid-way. Then other tests that take you towards the goal of making the first big test pass. Red-Green-Refactor at each step.
Small tests, I think mean that you should not be testing a whole lot of stuff in one test. e.g. Are components D.A, B and C in state1, state2 and state3 after I've called Method1(), Method2() and Method3() with these parameters on D.
Each test should test just one thing. You can search SO for qualities of good tests. But I'd consider your test to be a small test because it is short and focussed on one task - 'Getting PartNumbers From Manufacturing Order'
Update: As a To-Try suggestion (AFAIR from Beck's book), you may wanna sit down and come up with a list of one-line tests for the SUT on a piece of paper. Now you can choose the easiest (tests that you're confident that you'll be able to get done.) in order to build some confidence. OR you could attempt one that you're 80% confident but has some gray areas (my choice too) because it'll help you learn something about the SUT along the way. Keep the ones that you've no idea of how to proceed for the end... hopefully it'll be clearer by the time the easier ones are done. Strike them off one by one as and when they turn green.
I think you have a good start but don't quite see it that way. The test that is supposed to spawn more tests makes total sense to me as if you think about it, do you know what a Manufacturing Order number or a Part Number is yet? You have to build those possibly which leads to other tests but eventually you'll get down to the itty bitty tests I believe.
Here's a story that may require a bit of breaking down:
As a User I want to submit a manufacturing order number and receive a list of serializable part numbers of that orders bill of materials
I think the key is to break things down over and over again into tiny pieces that make it is to build the whole thing. That "Divide and conquer" technique is handy at times. ;)
Well well, you've hit the exact same wall I did when I tried TDD for the first time :)
Since then, I gave up on it, simply because it makes refactoring too expensive - and I tend to refactor a lot during the initial stage of development.
With those grumpy words out of the way, I find that one of the most overseen and most important aspects of TDD is that it forces you to define your class-interfaces before actually implementing them. That's a very good thing when you need to assemble all your parts into one big product (well, into sub-products ;) ). What you need to do before writing your first tests, is to have your domain model, deployment model and preferably a good chunk of your class-diagrams ready before coding - simply because you need to identify your invariants, min- and max-values etc., before you can test for them. You should be able to identify these on a unit-testing level from your design.
Soo, in my experience (not in the experience of some author who enjoys mapping real world analogies to OO :P ), TDD should go like this:
Create your deployment diagram, from the requirement specification (ofc, nothing is set in stone - ever)
Pick a user story to implement
Create or modify your domain model to include this story
Create or modify your class-diagram to include this story (including various design classes)
Identify test-vectors.
Create the tests based on the interface you made in step 4
Test the tests(!). This is a very important step..
Implement the classes
Test the classes
Go have a beer with your co-workers :)

Resources