<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36533086</id><updated>2012-01-27T23:12:23.710+01:00</updated><category term='LINQ'/><category term='Visual Studio'/><category term='ÖreDev'/><category term='Salvation Army'/><category term='TFS'/><category term='SpecFlow'/><category term='VB.NET'/><category term='Life of a consultant'/><category term='MSBuild'/><category term='Fun'/><category term='SOA'/><category term='ASP.NET MVC'/><category term='C#'/><category term='BrassBand'/><category term='Sprint Planner Helper'/><category term='Web Design'/><category term='TDD'/><category term='CQRS'/><category term='Agile'/><category term='WCF'/><category term='Euphonium'/><category term='BDD'/><category term='Kanban'/><category term='Scrum'/><category term='Tools'/><category term='NHibernate'/><category term='KanbanBoards'/><category term='Marcus private'/><category term='SpecificationByExample'/><category term='DDD'/><category term='.NET'/><title type='text'>marcusoft.net</title><subtitle type='html'>I learned a long time ago that Sharing is knowing. Here I'm sharing my thoughts on .NET development, agile/lean software engineering, bdd, tdd, the Salvation Army and life in general.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.marcusoft.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default?start-index=101&amp;max-results=100'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>754</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36533086.post-5823647146010711072</id><published>2012-01-23T08:00:00.000+01:00</published><updated>2012-01-23T08:00:09.381+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Some common Kanban questions–my suggestions</title><content type='html'>&lt;p&gt;I have been talking about &lt;a href="http://www.kanban101.com" target="_blank"&gt;Kanban&lt;/a&gt; a lot the last couple of years. Sometimes to the point where I think that I must have talked a hole in the head of the those closest to me. But from time to time you get great response, for example; &lt;/p&gt; &lt;p&gt;Anna (an &lt;a href="http://www.avegagroup.se" target="_blank"&gt;Avega Group&lt;/a&gt; colleague) attended one of my Kanban introductions and became inspired. She started to implement parts of the practices I’ve suggested at her client and soon ran into some questions. She sent me an email and asked for my suggestions on how to act in certain situations. &lt;/p&gt; &lt;p&gt;I of course answered but also felt the questions was not only good, they were also common. So I thought that I’ll share my suggestions here. Bear in mind, as I also told Anna, that Kanban is really just a couple of simple rules – how you apply them in your context is very much up to you. This has led to a plethora of practices and ways to solve problems. These are the ones I have picked up in the great network I have surrounded myself with. &lt;/p&gt; &lt;p&gt;So important to note is that Kanban as methodology doesn’t answer any of these questions. It’s up to you. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;blockquote&gt;&lt;/blockquote&gt; &lt;h3&gt;How do you highlight new activities on the board?&lt;/h3&gt; &lt;p&gt;Anna also said; we don’t want them to get mixed up with the ones we already have there. I suspect that she was talking about the work items that might get prioritized over already committed work.&lt;/p&gt; &lt;p&gt;Actually this is one of the benefits of using a flow approach such as Kanban. It’s gives you control and power to say Yes! Yes to change prioritization in the middle of the flow. Yes to add new stuff in your queue of items. I know that &lt;a href="http://agilemanagement.net/" target="_blank"&gt;David J Andersson&lt;/a&gt; consider that as title for his &lt;a href="http://agilemanagement.net/index.php/kanbanbook/" target="_blank"&gt;Kanban book&lt;/a&gt;; Kanban – how to become a Yes man!&lt;/p&gt; &lt;p&gt;When you have control over a visualized flow it’s easy to see what can be added and what then need to be removed.&lt;/p&gt; &lt;p&gt;One way to handle that is to let the stakeholder have complete control over the Inbox. In my current assignment our project manager is allowed 6 items in our To-do-column. How he prioritizes them is up to him. We simply know that the top one is the first we should work on. &lt;/p&gt; &lt;p&gt;If you feel that, that would make your flow too unpredictable you could allow for a fixed number of items that they cannot change the order on. But what they do before your inbox is completely up to them. &lt;/p&gt; &lt;h3&gt;Is it ok to add work items whenever – or only during daily standup?&lt;/h3&gt; &lt;blockquote&gt;&lt;/blockquote&gt; &lt;p&gt;In my opinion you should at least talk to some other person in the team when adding or changing the order your work items. It doesn’t have to be a formal meeting but could. I’ve experienced anything from big prioritization meetings with several participants (see below) to just letting the stakeholder add notes when the feel like. &lt;/p&gt; &lt;p&gt;One thing I’ve tried that force a communication to take place is that a note must be estimated in size before added to the board. That make the stakeholder talk and describe the item before adding it to the board. &lt;/p&gt; &lt;p&gt;When it comes to moving the board I encourage moving of the items when the state of the work changes. Not just at daily standups. There’s some people, mainly in the &lt;a href="http://en.wikipedia.org/wiki/Scrum_(development)" target="_blank"&gt;Scrum&lt;/a&gt; community,&amp;nbsp; advocating moving of the work items only at the daily standup. I was one of them. But then I realized that the board should convey the status of the work – and it should be up to date all the time. So I suggest you move the sticky when the state of the work has changed. That’s also much easier to remember and gives instant feedback of the progress made on the item.&lt;/p&gt; &lt;h3&gt;Do you have any suggestion for a simple, powerful agenda on a daily standup?&lt;/h3&gt; &lt;p&gt;This one was actually easy. You simply “walk the board”, enumerating work from the right to the left. This will emphasize the pull-principle so that we see work have been pulled into new states, closer to the goal.&lt;/p&gt; &lt;p&gt;Instead of asking all members of the team what their status is we concentrate on the work being done. &lt;/p&gt; &lt;p&gt;If you are in a hurry or have a large team you can simply stop with any deviations from normal. Anything blocked? Anyone not respecting WIP-limits? Work items without attention? Missuse of the board? People sitting on more than one notes? Items having stayed for a long time in the same place?&lt;/p&gt; &lt;p&gt;Stuff that just flow as normal doesn’t need our attention right now. Keeping to just the deviations has led to really big team (40+ people) having daily standups in under 5 minutes. &lt;/p&gt; &lt;p&gt;Keep the meeting short (10 min max) and focus. Put off any discussion to after the daily standup. What I’ve found is that pretty soon will small groups gather after the daily standup and talk about the work. Or better – the process and how to improve it.&lt;/p&gt; &lt;h3&gt;What’s a suitable range in size for work items?&lt;/h3&gt; &lt;p&gt;It depends, said the consultant and sent his check… This is very hard to give a general answer to, of course. &lt;/p&gt; &lt;p&gt;For small tasks I would say that if it takes longer time to manage the sticky (creating it, adding it to the board and move it) than the work itself – don’t add it to the board. But make a note of work being accomplished. My good friend &lt;a href="http://joakimsunden.com" target="_blank"&gt;Joakim Sunden&lt;/a&gt; as written an &lt;a href="http://joakimsunden.com/2011/06/one-way-of-handling-small-tasks-on-a-kanban-board/" target="_blank"&gt;excellent blog post&lt;/a&gt; on this matter. I suggest you check it out.&lt;/p&gt; &lt;p&gt;In the other end you have to consider what value you want from the board. A board &lt;strike&gt;is&lt;/strike&gt; should be an information radiator. If you have work items sitting in the same state for several weeks it will not give you any value. I usually have 1-2 week as maximum, estimated time through the board. &lt;/p&gt; &lt;p&gt;Of course sometimes you have waiting stages (such as “Waiting for deployment”) and then you can batch up many items there. &lt;/p&gt; &lt;p&gt;Even though I suggest that you try to slice up big work in to smaller end-to-end slices of functionality and manage each separately, you could also: split them into tasks and move the task. Here I’ve read about people keeping a number series to keep track of when the main item can be moved. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Say you have a big work item entering development. &lt;/li&gt; &lt;li&gt;You give it a number (5 – Allow for credit card payment). &lt;/li&gt; &lt;li&gt;You then add tasks for that item; &lt;/li&gt; &lt;ul&gt; &lt;li&gt;5.1. Update database, &lt;/li&gt; &lt;li&gt;5.2 Create GUI &lt;/li&gt; &lt;li&gt;5.3 Create business layer, &lt;/li&gt; &lt;li&gt;5.4 Integration with PayPal.&lt;/li&gt; &lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;As the team start work on the sub items they move them over to Development done. &lt;/li&gt; &lt;li&gt;When the last item has move the whole work item can be moved (#5 that is)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This pattern will help you to keep track of the status of the work even for big items. Also by divide the work item into smaller tasks you have to think hard about what is needed to complete the task. That is a exercise well worth the time in itself. Hence I never allow for task bigger than 8 h (1 day).&lt;/p&gt; &lt;h3&gt;How do you handle recurring activities, such as weekly meetings etc?&lt;/h3&gt; &lt;p&gt;I usually don’t add these to the board. It’s not stuff that “make our customer happy”. But of course if you want to track the how much time is spent on meetings… then by all means add them. &lt;/p&gt; &lt;p&gt;In one team I’ve been in we had recurring activities (generating customer invoices) that needed to be done by certain dates in the month. So they created stickies that they reused for those activities and kept them in a corner of the board. With the next due date written above them. When that date approached we simply move the item to the top of the Inbox.&amp;nbsp; &lt;/p&gt; &lt;h3&gt;We have several stakeholders that supply us with work – how do you make them prioritize among themselves? &lt;/h3&gt;  &lt;p&gt;This sounds exactly like the situation where the first Kanban system was ever created in software development. It’s described in great detail in &lt;a href="http://agilemanagement.net/index.php/kanbanbook/" target="_blank"&gt;David J Anderssons Kanban book&lt;/a&gt;. Simplified they had a maintenance team (in India) that got their work from 4 different managers. Of course all of these wanted “their” items to be prioritized over the other work. &lt;/p&gt; &lt;p&gt;The manager of the team solved this by send them an email when the team had room for 3 new items. They then decided among each other what to prioritize now. Pretty soon the mail was automated. And also the stakeholders started to deal among each other (if I vote for your item this now can I count on your support later?). &lt;/p&gt; &lt;p&gt;The reason, I think, that this worked has to visibility and building trust by delivering value often. The stakeholders knew, roughly, how long it would take until the opportunity to add item. So if they missed out this time it wouldn’t be long until the next occasion. The didn’t have to wait so long until the next train, if you like. &lt;/p&gt; &lt;p&gt;It’s of course better to meet in person if you can. But invite all your stakeholders. Describe how your process works and how they can see work flow through the process. Show them how you will deliver faster (maybe even promise a max time?) if you can work with fewer items running at the same time. &lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;I hope you could make sense of this even though the questions were out of context. I would love some comments on other ways to handle these situations. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-5823647146010711072?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/5823647146010711072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=5823647146010711072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5823647146010711072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5823647146010711072'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2012/01/some-common-kanban-questionsmy.html' title='Some common Kanban questions–my suggestions'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-2071797570192050990</id><published>2012-01-01T21:54:00.001+01:00</published><updated>2012-01-09T08:56:41.695+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='Salvation Army'/><title type='text'>“If you quit today”–make someone happy</title><content type='html'>I have been working as a contractor for the better part of my career. Due to the nature of consultancy and the IT-business in general I’ve seen a lot of colleagues come and go. Brilliant people in many cases, people that you miss so bad when they have quit. &lt;br /&gt;So when the ubiquitous “Thank you for the time here”-mail comes I always try to write them a short sentence saying that I’ve really appreciated their company, competence and just being around them. &lt;br /&gt;And it hits me every time; why didn’t I say anything of this while we were colleagues?&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;It’s so stupid. It’s so simple. And it takes about 5 minutes to write. I always find the time when they send the notice that they will quite.&lt;br /&gt;So I will try this out – send people a “If you quit today … I would love to have said this first”-note before they go. Yeah, yeah I know it sounds like a New years resolution but I actually decided to do this in November. &lt;br /&gt;I found a great spot for doing it also. On the LinkedIn recommendation page. Then it will be available for others to see as well. It might have a twofold effect for the person in question. &lt;br /&gt;Speaking of twofold this reminds me about a chours we sang in the Salvation Army when I was small (my translation):&lt;br /&gt;&lt;blockquote&gt;Make someone happy&lt;br /&gt;Try to do it today&lt;br /&gt;There’s so many way you can try out&lt;br /&gt;And if you do it you will see&lt;br /&gt;That you’ll get happiness in giving&lt;br /&gt;So try today to make someone happy&lt;/blockquote&gt;I’ll give this a try. &lt;strike&gt;Follow my tweets with the tag “#IfYouQuitToday”.&lt;/strike&gt;&lt;br /&gt;After a great suggestion from&amp;nbsp;&lt;a href="https://twitter.com/#!/chibbeu" target="_blank"&gt;Christer Unestrand&lt;/a&gt;&amp;nbsp;I have now changed the twitter tag to &lt;a href="https://twitter.com/#!/search?q=%23HaveIToldYouLately" target="_blank"&gt;"#HaveIToldYouLately"&lt;/a&gt; since that's a more positive take on it. Thanks Chibbe!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-2071797570192050990?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/2071797570192050990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=2071797570192050990' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2071797570192050990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2071797570192050990'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2012/01/if-you-quitted-todaymake-someone-happy.html' title='“If you quit today”–make someone happy'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-3944511374658002557</id><published>2011-12-29T11:08:00.001+01:00</published><updated>2012-01-01T21:40:46.550+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>What is agile?</title><content type='html'>&lt;p&gt;About a year ago I got asked by my project manager to “just give a quick intro and overview; What is agile? 20 minutes or so…” That didn’t feel to bad – but when I got home and started to prepare it struck me; it’s really hard to sum up agile!&lt;/p&gt; &lt;p&gt;For me agile has been become more a less a lifestyle and much of the things I argue for or fight against is about agile or being agile. And also, now that &lt;a href="http://10yearsagile.org/" target="_blank"&gt;agile is 10 years old&lt;/a&gt;, the buzzword has gone into the next phase and almost anything good or cool that people does, related to software is branded with agile ™. &lt;/p&gt; &lt;p&gt;Is TDD agile? If your not doing TDD are you not agile? Standups? Boards? The list goes on and on and I couldn’t come up with an intelligent answer. Either everything had to be included to be agile or nothing was left. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;Like the story of the old women who collects wood: &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;She went out and started to pick up sticks from the ground: &lt;br&gt;“I’ll manage that one”, &lt;br&gt;“And if I managed that one I sure manage that one”, &lt;br&gt;“And if I managed that last one I will manage this one to” &lt;br&gt;…&lt;/p&gt; &lt;p&gt;After awhile she had way to much to carry. So she started to take sticks away again; &lt;br&gt;“If I cannot manage that one, I’ll take it away”, &lt;br&gt;“And if I couldn’t manage that one, I will have to take this one away too” &lt;br&gt;…&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So I dodge that presentation. &lt;/p&gt; &lt;p&gt;But the question stayed with me and itched me like your knitted Christmas stockings from grandma. Later during the autumn (or rather the winter) I got another opportunity and this time I took the chance to sort my thinking on the matter. In this post I’ll share my thinking on the subject. And yes, sorry for the long post – it’s a 45 minutes presentation. But now on paper.&lt;/p&gt; &lt;h3&gt;Shu Ha Ri&lt;/h3&gt; &lt;p&gt;I read an excellent book called &lt;a href="http://www.coachingagileteams.com/" target="_blank"&gt;Coaching Agile Teams by Lyssa Adkins&lt;/a&gt; and that introduced the martial arts thinking of &lt;a href="http://en.wikipedia.org/wiki/Shuhari" target="_blank"&gt;Shu Ha and Ri&lt;/a&gt;. That is different phases that you go through when learning new skills. From the &lt;a href="http://en.wikipedia.org/wiki/Shuhari" target="_blank"&gt;Wikipedia page&lt;/a&gt; about it we have a wonderful translation that sums it up, short and sweet:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“first learn, then detach, and finally transcend.”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Here’s a quick intro to the three levels:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;On the &lt;strong&gt;Shu&lt;/strong&gt; level you learn fundamentals and techniques. My mind often wander to Karate Kid and the famous wax-on, wax-off scene,&amp;nbsp; when I think of this level.  &lt;li&gt;On the &lt;strong&gt;Ha&lt;/strong&gt; level you have reached a level of understanding of the fundamentals that you can start to challenge the rules a bit. “What if I turn my hand like this?”, “Yes, but in this situation I might try to go this way instead”&lt;br&gt;The thing here is that you are using your knowledge you picked up on the Shu level and break the rules based upon that knowledge.  &lt;li&gt;&lt;strong&gt;Ri&lt;/strong&gt; level means that you are leaving the rules, improvising and creating new ones as needed. But coming from, or being in the culture of the rules that you learned and challenged on the first two levels. &lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Wasn’t this about agile now again?&lt;/h3&gt; &lt;p&gt;Ok, ok .. I’m getting lost here. But I think that the Shu Ha Ri model says something about how and why many agile adoptions might fail; we break the rules before we know them. Or rather we break rules without really knowing the reason of the rules. WHY is it like that?&lt;/p&gt; &lt;h3&gt;We love our tools – and a word on diets&lt;/h3&gt; &lt;p&gt;Moreover our industry loves and craves tools, guidelines and best practices. We are still longing for a short and sweet description that says; “do this and your software development project will be a success”. A &lt;a href="http://en.wikipedia.org/wiki/Silver_bullet" target="_blank"&gt;silver bullet&lt;/a&gt; if you like, when I learned &lt;a href="http://en.wikipedia.org/wiki/No_Silver_Bullet" target="_blank"&gt;1986 from mr Brooks that no such thing exists&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;And really … we know this, don’t we? We’re just hoping… Oh we hope sooo much. Like people still searching for a diet (only bananas, low carb high fat, pills, TV-shop) when we in reality knows; eat less, work out more. Bam – works every time. &lt;br&gt;But we’re still hoping – maybe this blue pill will do the trick. Or this bicycle thingy that folds and plays my favorite music at the same time – it will make me slimmer. I know it…&lt;/p&gt; &lt;p&gt;And that’s the reason for failure of many other software methodologies and processes; &lt;a href="http://en.wikipedia.org/wiki/IBM_Rational_Unified_Process" target="_blank"&gt;RUP&lt;/a&gt;, for example, wasn’t intended to be used the way many people used it. Nothing in RUP saying that you should have year long iterations for example. And it even says explicitly that the documentation templates was just templates, to be modified - it still we use all of them, and all of the headings as well. Just to be sure. &lt;/p&gt; &lt;p&gt;In fact the dreaded &lt;a href="http://en.wikipedia.org/wiki/Waterfall_model" target="_blank"&gt;Waterfall method&lt;/a&gt; is in itself a misconception and erroneously applied model. The man that “coined” the phrase used it as a reference to a &lt;strong&gt;flawed &lt;/strong&gt;model, but still our industry took to it as a fish to water. Why? Because it was something to hold on to. &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“The waterfall method you say…? I’ll take it”&lt;/p&gt; &lt;p&gt;“But it’s &lt;strong&gt;flawed!! &lt;/strong&gt;It was meant as a joke…"&lt;/p&gt; &lt;p&gt;“Don’t care! It’s at least something”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;a href="http://dannorth.net/" target="_blank"&gt;Dan North&lt;/a&gt; did an excellent &lt;a href="http://oredev.org/2011/sessions/embracing-uncertainty--the-hardest-pattern-of-all" target="_blank"&gt;keynote on this at OreDev 2011&lt;/a&gt; – we he said; &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“We rather be wrong than uncertain”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Scary but true.&lt;/p&gt; &lt;h3&gt;Applies to agile processes&lt;/h3&gt; &lt;p&gt;So when agile came along, starting with Scrum (at least in Sweden), we all went; &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“Yes! That’s right! And with some rules along with it. Lets go”&lt;/p&gt;&lt;/blockquote&gt; &lt;p align="left"&gt;So everybody started apply Scrum. Or at least tried. Or at least where it didn’t hurt to much. I have actually &lt;a href="http://www.marcusoft.net/2011/10/is-scrum-dead-is-scrum-aism.html" target="_blank"&gt;never seen a Scrum implementation&lt;/a&gt; as it was meant to be; it’s always some part missing;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Yeah, we do Scrum, but we don’t do standups/have a board/sit together  &lt;li&gt;It was too hard to find a good Scrum-master so we have our own &lt;em&gt;applied &lt;/em&gt;version of it.  &lt;li&gt;It’s Scrum-ish; we don’t meat our customer that often, and we have skipped iterations.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This have to do with not embracing the fundamentals that agile is based upon. Or if you like (and to finally get back to the martial arts mumbo-jumbo about ShuHaRi); we’re breaking the rules of agile without knowing why?&lt;/p&gt; &lt;h3&gt;What is agile?&lt;/h3&gt; &lt;p&gt;So, with that in mind, answering the question “What is agile” is not that hard:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“An approach to software development based on the values and principles expressed in the &lt;a href="http://www.agilemanifesto.org/" target="_blank"&gt;Agile Manifesto&lt;/a&gt;”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And the agile manifesto talks about, as you already know:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Individuals and interactions over processes and tools  &lt;li&gt;Working software over comprehensive documentation  &lt;li&gt;Customer collaboration over contract negotiation  &lt;li&gt;Responding to change over following a plan&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;But what do they mean in the Agile manifesto then?&lt;/h3&gt; &lt;p&gt;Well, I will not be so presumptuous as to say that I know what they were thinking. But if we try to think about WHY they have written as they have… Maybe we’ll learn something:&lt;/p&gt; &lt;h4&gt;We are uncovering better ways of developing software by doing it and helping others do it&lt;/h4&gt; &lt;p&gt;What’s the thought behind this statement? &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Firstly “uncovering” means that they (and we) are still learning. This is not the truth once and for all.  &lt;li&gt;Secondly “developing software by doing it” – all the signees of the agile manifesto were developers, to my knowledge (!). They still had their hands in the dough. If that’s good or bad is another question…  &lt;li&gt;Thirdly – “helping others” – they haven’t been sitting alone and dreamt this up. It’s based on experiences from a lot of projects where they together have been involved in.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Individuals and interactions over processes and tools&lt;/h4&gt; &lt;p&gt;Why do they write this?&lt;/p&gt; &lt;p&gt;Software is a &lt;strong&gt;knowledge&lt;/strong&gt; &lt;strong&gt;creating &lt;/strong&gt;process – nobody knows the finished product before it’s done. Not even the customer. In order to succeed we need to communicate. A lot and often.&lt;/p&gt; &lt;p&gt;So … therefore it’s more important to focus on the individuals in the project and their communication, than to focus on following a certain process, or use a certain tool. If you communicate well within the group – the process and tool becomes secondary by itself. &lt;/p&gt; &lt;p&gt;What do you do when a project is in danger of being late? You put all the smart people you need to create the product in one room. Leave them alone and let them work. There you have it; Scrum in a nutshell.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;What would change if you could talk to your end-customer/stakeholder each day?  &lt;li&gt;What is the number one thing hindering you from doing so? How can you change that?&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Working software over comprehensive documentation&lt;/h4&gt; &lt;p&gt;Oh man – this one has been abused so much it isn’t fun anymore. It DOESN’T say “No documentation” – it says; “Working software &lt;strong&gt;over&lt;/strong&gt; comprehensive documentation”. Of course documentation is needed.&lt;/p&gt; &lt;p&gt;Why do they write this?&lt;/p&gt; &lt;p&gt;Working software is actually the only real metric that you could use for progress. How much software that works (that the end user can take advantage of and be more productive with for example) are you putting into production each week?&lt;/p&gt; &lt;p&gt;That’s why we are here; to help and delight the customer with &lt;strong&gt;working&lt;/strong&gt; software. Think for yourself how happy your customer would be for a great requirements specification. … Exactly – not that much. Still, that is what is being DONE after several months in some projects.&lt;/p&gt; &lt;p&gt;And why is it important to put it out there often? To get feedback. Feedback is the creator of knowledge. Without it you can do changes but you don’t know if it’s the right change, or how much you should do. &lt;/p&gt; &lt;p&gt;I love a &lt;a href="https://twitter.com/#!/mfeathers" target="_blank"&gt;Michael Feathers tweet&lt;/a&gt; about this (couldn’t find a link to it now sadly):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“This definition of done this scares me. Code is in production or not!”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;When we take software into production we know that it’s there. Ready to be used. And we’re run through our process (analysis, design, development, testing, building, deploying). All of this will give us valuable feedback to improve upon.&lt;/p&gt; &lt;p&gt;This is also a foundation of &lt;a href="http://en.wikipedia.org/wiki/Lean_manufacturing" target="_blank"&gt;Lean&lt;/a&gt;, to move &lt;strong&gt;small&lt;/strong&gt; bodies of work through the &lt;strong&gt;whole&lt;/strong&gt; production chain &lt;strong&gt;often and swiftly&lt;/strong&gt;. &lt;br&gt;But, very important - WHY? To learn and improve your process! &lt;/p&gt; &lt;p&gt;That’s why even well working units at Lean plants will continue to put more pressure on themselves (decreasing WIP-limits for example) when they already work well. To further improve.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How can you measure how efficient you are creating working software?  &lt;li&gt;What is the need of documentation from a end-customer perspective?&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Customer collaboration over contract negotiation&lt;/h4&gt; &lt;p&gt;So what is the reasoning behind this then?&lt;/p&gt; &lt;p&gt;Well as with the first point this honors the fact that nobody actually knows what the finished product will look like. Not even the customer. Not even in “re-writes” (trust me – I’ve been doing my share of those).&lt;/p&gt; &lt;p&gt;But why writing this “contract negotiation” in here? Well that the common way of “protecting” yourself against uncertainty in the software industry. Write a contract or an SLA. And really what – is bad about that? Here’s a story that I’ve took part in:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;After a project at one of my client we sat down in one of the rare opportunities we had to meet the customer.&amp;nbsp; They were happy – because we had delivered before the estimated time. But we started to talk about how we worked on “each side” customer vs. IT-department (yes, sadly the same company).&lt;/p&gt; &lt;p&gt;“So how did you do estimates? You were about 20% under budget. How can you guess so badly” – the customers project manager asked&lt;/p&gt; &lt;p&gt;“Well – first we make a guess and then we always add 30% just to be sure” said the IT project manager&lt;/p&gt; &lt;p&gt;That made the customer side burst into laugh in unison. When they had calmed down they said:&lt;/p&gt; &lt;p&gt;“That’s exactly the same thing we do with all your numbers. We add 30%, because otherwise we just get disappointed”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I wish I was making it up but I was in the meeting. So both sides added extra time and resources to the estimates to protect themselves. But here’s the most stupid thing about this – all that time they could have been cranking out “working software” instead. Now we were writing contracts, budgets and estimates. &lt;/p&gt; &lt;p&gt;Really this whole business of having a IT-department that the business side “buys” services from is wasteful in itself. It doesn’t promote a collaborative culture. It’s writing contract instead of collaborating.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;What could you stop doing if you sat next to your customers?&lt;sup&gt;&lt;/sup&gt; &lt;li&gt;What would you change to improve collaboration among different departments in your project?&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Responding to change over following a plan&lt;/h4&gt; &lt;p&gt;And the final one – which I have found to make the most profound change in my thinking. Why have they written this? This is at the heart of the philosophy behind agile; what kind of person/project/ company are you? &lt;/p&gt; &lt;p&gt;If problem arises with a plan you made – what are your first measures? Some people would make even more plans, stricter budgets and less maneuverability for the next project. Others would say; well that was to strict let’s give ourselves more flexibility for the next time and not plan so much in advance. &lt;/p&gt; &lt;p&gt;I’ve heard of companies who’s CFO’s war cry is; “no exceptions” (everybody goes through the same exact process and is treated in the same way). &lt;br&gt;And on that same company there were team leaders that said: I only do exceptions all day long – that the way we roll.&lt;/p&gt; &lt;p&gt;So again, there’s is nothing wrong with planning. In fact, I think I have planned more when I started with agile than I did before. &lt;strong&gt;But &lt;/strong&gt;I have completely shifted the horizon. I make detailed plans for the next few days or weeks and very rough ones for anything bigger than that – because I know it will change. That’s the only thing I do know about the things down the project road, in fact. Look up &lt;a href="http://www.ayeconference.com/starting-with-rolling-wave-planning/" target="_blank"&gt;Rolling wave planning&lt;/a&gt; for more on this. &lt;/p&gt; &lt;p&gt;And this also comes back to feedback, which I think sums up agile in a word. To align your process in such a way that you get feedback and change your behavior to adapt to the new situation. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you knew that everything you have decided upon so far could change – how would you set up your project differently?&lt;!--EndFragment--&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;So – really what is agile?&lt;/h3&gt; &lt;p&gt;Agile is a philosophy, a way to approach how you do stuff (system development mostly). There are not steadfast rules on how you should or shouldn’t do things. &lt;/p&gt; &lt;p&gt;So to “become agile” you and your team must apply this thinking and then start adjusting yourself, your process and the people around you in small steps towards that thinking. &lt;/p&gt; &lt;p&gt;I have found simple goal-statements, rephrased into questions, to be to great use to guide me and teams I have coached. For example this statements:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“Will this (meeting, feature, schedule, prioritization) make our customer more happy?”&lt;/p&gt; &lt;p&gt;“If you were forced into delivering new functionality into production every month/week/ day – what would change first to get there?”&lt;/p&gt; &lt;p&gt;“How could we solve the number one hindrance you see to deliver every other week”&lt;/p&gt;&lt;/blockquote&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;This is how I see the question and it’s answer today. I’m sure I will change. Often and a lot. But that’s just part of the whole being agile thing.&lt;/p&gt; &lt;p&gt;I hope you got something out of this. I sure did just by forcing myself to write it down.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-3944511374658002557?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/3944511374658002557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=3944511374658002557' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3944511374658002557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3944511374658002557'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/12/what-is-agile.html' title='What is agile?'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-1877650632727020736</id><published>2011-12-22T12:54:00.001+01:00</published><updated>2011-12-22T14:11:02.033+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='TFS'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Applying the Switch framework to broken builds</title><content type='html'>&lt;p&gt;I’m rereading a great book – &lt;a href="http://www.heathbrothers.com/switch/" target="_blank"&gt;Switch by the Heath Brothers&lt;/a&gt; and it inspires me. The last time I read this book it inspired me &lt;a href="http://www.marcusoft.net/2010/10/no-more-bugs-thought-experiment.html" target="_blank"&gt;to write a post&lt;/a&gt; and it’s happening again. &lt;/p&gt; &lt;p&gt;The book is about change, how to accomplish change and especially in situations where you are not in power or control. In short – how to talk to and influence others to understand the need for change and follow through on it. &lt;/p&gt; &lt;p&gt;One very smart thing is that you can download a cheat sheet that contains the ideas in a nutshell – &lt;a href="http://www.heathbrothers.com/resources/download/switch-framework.pdf" target="_blank"&gt;the Switch Framework&lt;/a&gt; – for free. Of course it’s not much use if you haven’t read the book, so you better do that first. Could very well be the best book you read. &lt;/p&gt; &lt;p&gt;I thought I would apply the reasoning in the framework to a real life situation and see if I get any ideas on how to get forward. I haven’t implemented this yet but I’ve been reasoning about it with myself and other for quite some time now. &lt;/p&gt; &lt;p&gt;So this is, like many post on this blog, a learning experience for me and I’m sharing it with you. Please supply any feedback to me. I would love to hear your thoughts on the matter.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h3&gt;The Problem – Broken build indifference&lt;/h3&gt; &lt;p&gt;To have &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration" target="_blank"&gt;continuous integration (CI)&lt;/a&gt; for your source control nowadays is almost mandatory. But if I think back it was a very novel thing for many developers just a few years back. &lt;/p&gt; &lt;h4&gt;CI&lt;/h4&gt; &lt;p&gt;In short CI means that you have an automated way to get the latest source code, compile it, run unit test and integration tests (if present) and then deploy it to an environment for testing. You should run this as often you can, at least daily but it’s not uncommon to do a full build on each check-in. &lt;/p&gt; &lt;p&gt;In my experience it’s one of biggest quality improvers you can add to development process or team. It give you a base line for the current quality of the system and a pulse and a sense of going forward, each check-in makes the system just a little better than before. It’s quality guarantor of the source code checked in. You know that it’s good enough to pass the compile and tests in the build script. &lt;/p&gt; &lt;p&gt;An automated build is a guarantor that the build is done in the same way each time. If you get it to work once it will follow the same procedure each time, which gives you much reliable deployments to all environments (to production for example).&lt;/p&gt; &lt;p&gt;Also it give stakeholders around you a way to get hold of the “latest and greatest” whenever they want.&lt;/p&gt; &lt;h4&gt;The catch&lt;/h4&gt; &lt;p&gt;There’s only one catch… you need to fix broken builds. In fact you should make that the top priority for the team. Always fix broken builds as soon as they happen. But that is of course boring… and irritating … and sometimes even makes you angry as you might not have been the person that was responsible for the check-in that broke the build.&lt;/p&gt; &lt;p&gt;This is the root to a lot of argumentation and inventions; a blame hat, red blinking lights, monitors that shows you when the build broke and who was responsible etc. etc. &lt;/p&gt; &lt;p&gt;In some teams I’ve been in, people after awhile give up. “This build broke… So what – he has broken the build six times in a row”, “Who cares? Broken build, I’ll fix it with my next check-in next Friday”. And if someone in the team starts reasoning like that it doesn’t take long before others tag along. Before long the build process is often side-stepped and stuff is thrown together and into production in an ad-hoc fashion. It all resembles the &lt;a href="http://en.wikipedia.org/wiki/Broken_windows_theory" target="_blank"&gt;broken window syndrome&lt;/a&gt;, actually &lt;/p&gt; &lt;p&gt;So, back to the topic of the post, how do you CHANGE this behavior? Well – let’s try out the Switch Framework.&lt;/p&gt; &lt;h3&gt;The Switch framework – a short introduction&lt;/h3&gt; &lt;p&gt;Hey, I cannot start applying the framework without giving a short introduction. In order to understand it you should know this at least;&lt;/p&gt; &lt;p&gt;The authors have a image of the human psyche that they build a lot of their reasoning on; the image of a Rider on an Elephant (borrowed from Jonathan Haidt). The elephant is our emotion and the rider is our rational side. The rider controls the elephant with some reins from his topside position. The only problem is that if the six-ton elephant wants to go into the bushes to have something to eat … those reins will not help much. &lt;/p&gt; &lt;p&gt;In order to accomplish change you will have to address both the rider and the elephant part of people. The rider need clear instructions while the elephant need motivation and some reasons for why this should be done. Finally you need to shape the path on which they are going to be traveling. The Switch framework gives you some guidelines on how to accomplish that.&amp;nbsp; &lt;/p&gt; &lt;p&gt;And there… I have now summed up about 4 pages in the book. Read the rest to get the full picture. &lt;/p&gt; &lt;h3&gt;Applying Switch to the Broken build indifference problem&lt;/h3&gt; &lt;p&gt;So here is my thinking on what you can do to help a team that’s experiencing the problem I described above. &lt;/p&gt; &lt;h4&gt;Direct the rider&lt;/h4&gt; &lt;p&gt;The rider probably knows that a solid CI is a good thing, most of the developers do. The problem here though is more that we need to put the attention on the broken builds and fix them, which probably is mostly an elephant-problem (of lazyness). So to the “rider” we need to supply information and arguments on why this is good. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Follow the bright spots.&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;In the book the authors talk about finding situations where the wanted behavior has been a success. People who already are doing this and succeeds with it. &lt;/p&gt; &lt;p&gt;We might find other teams that can talk to our team about the benefits of fixing a broken build right away. Or find situations when that have helped us find stuff that would have ended up being a problem later on.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Script the critical moves&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is putting emphasis on concrete measures that one can take to make it crystal clear and easy to follow.&amp;nbsp; &lt;/p&gt; &lt;p&gt;In our case that might be a technical solution; for example some tools don’t accept commits or check-ins when the build fails. In Team Foundation Server this is called gated check-ins and simply hinders bad code from entering the system. Mind you that the build we still break… but you will have to fix it before you can continue. &lt;/p&gt; &lt;p&gt;We also need to make sure that everyone understands and can follow the actual build process. With great logging (not too much though) and simplified build scripts that doesn’t tries to do everything. In my experience the build script is often done by one person (and he/she sweats and swears over it). And when it works you “just leave it”. &lt;br&gt;Maybe we should go through it together and make sure everybody understands what is going on. And even simplify it and the stuff it does. “Does everybody get what happens when we’re running our integration tests”?&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Point to the destination&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I love this part – it’s like sending a postcard from the future when this have been applied. Look who wonderful stuff is over here. All our problems is just gone. Nice, huh?&lt;/p&gt; &lt;p&gt;Here we can talk about how we can be more responsive and faster in our process. “Due to our rock solid build and deployment process we can now deploy a new version into production, safely, in under 8 minutes. Look ma’. No hands!”&lt;/p&gt; &lt;h4&gt;Motivate the elephant&lt;/h4&gt; &lt;p&gt;The elephant is all about feeling and getting the emotions on our side. Here are the steps for that.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Find the feeling&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This part is about getting a sense of urgency, or feeling that this needs to be fixed. There’s a great example in the book where somebody shows an inventory problem by pouring out all the different gloves that the company is buying on a table. 424 different kinds. That made a feeling of “WOW! How can we go on doing this? This must be fixed!” stick with people seeing the pile of gloves.&lt;/p&gt; &lt;p&gt;For the broken build we could start tracking data on how much time people are spending on untangling bad source code they got when doing a Get. Or how many times outside stakeholders are using a faulty version of our system, or even waiting for us to put another one together. &lt;/p&gt; &lt;p&gt;Make people feel the pain they are inflicting on each other. But here we have to tread carefully and not fall into the blame game, which I think is bad. Jellying and hitting people with treats or humiliations cannot be the answer. But helping them to see that their behavior is hurting others might. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Shrink the change&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In this part Switch is asking us to make the first steps easier. Giving us ahead start and a sense of that we’re already are on our way. &lt;/p&gt; &lt;p&gt;In the broken build problem this should not be too hard. We have the process in place. “Some (3/5) builds are working – we just have to try a little harder and we’re almost there”&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Grow the people&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here you’re trying to create a team-feel, to get a feeling of belonging and some small peer pressure into the game.&lt;/p&gt; &lt;p&gt;I’ll leave this one with a (tweaked) quote;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“I dream of the day when a broken build is a major thing and a release to production is not”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;could be&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“On this team a broken build is a major thing and a release to production is not”&lt;/p&gt;&lt;/blockquote&gt; &lt;h4&gt;Shape the path&lt;/h4&gt; &lt;p&gt;Often we think that change is hard because of people, but in reality it’s often the situation and the environment the people are in that is the problem. This part is all about changing the environment to help and support the change.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tweak the environment&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Maybe some simple change in the way we work or the environment we’re acting in can be change to facilitate the change in a big way. A great example of this is the Amazon 1-Click-buy. They simplified their checkout process to be one simple click, which of course resulted in an increase in sales. &lt;/p&gt; &lt;p&gt;I often find that build scripts and the stuff they are doing is very complicated. Maybe we should split the CI build into just doing a compile and running the unit tests. That will leave us in a pretty good state for ensuring that the code quality is good enough to commit into the source repository. We can then have separate build running a couple of times a day, that runs the Integration level test and (if they pass) deploy to a test environment. &lt;/p&gt; &lt;p&gt;This will be much easier to understand and we will get faster builds. The testing environment will still be stable and updated a couple of times a day is still very good.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Build habits&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is about moving your action into the muscle memory, and thereby making them “free”. We do it without thinking about it – reducing the workload of the rider. &lt;/p&gt; &lt;p&gt;A checklist is a very good idea of this. Here you could think of introducing separate steps or checklist on a board that make you go through this. I suggest you read &lt;a href="http://hakanforss.wordpress.com/2011/09/05/standard-work-in-software-developmentpart-2/" target="_blank"&gt;Håkan Forss blog on this matter&lt;/a&gt;. It’s a great way to make stuff standard and hence a baseline for quality. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Rally the herd&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here we want to make the behavior contagious so that it’s automatically inflicted on new team members and teams around us. This will help us to grow as well. &lt;/p&gt; &lt;p&gt;I suggest that you make team talk with each other and exchange ideas. Maybe a show-and-tell-session on build automation at the Friday afternoon coffee?&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;Well – that was a great way of generating ideas and sorting out my tangled mind on the matter. &lt;/p&gt; &lt;p&gt;There are a number of actions that you can take to fight indifference on broken builds. Some are technical and some are just behavioral, just as expected. I haven’t implemented all of these in my current team, but will sure try to start to.&lt;/p&gt; &lt;p&gt;If you read this and think that I have forgotten something or got something wrong – please comment below.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-1877650632727020736?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/1877650632727020736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=1877650632727020736' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/1877650632727020736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/1877650632727020736'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/12/applying-switch-framework-to-broken.html' title='Applying the Switch framework to broken builds'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-3333381899174569140</id><published>2011-12-13T13:29:00.001+01:00</published><updated>2011-12-13T13:29:42.279+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><title type='text'>Log4Net, RollingFile named by Date and the staticLogFileName setting</title><content type='html'>&lt;p&gt;We have been chasing some strange logging bugs for a while in my current project. We are using &lt;a href="http://logging.apache.org/log4net/" target="_blank"&gt;log4net&lt;/a&gt; to do our logging and it works fine ... until a couple of weeks ago. Some logging didn't occur, in another case we didn't get new files...&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt; &lt;p&gt;The fix is, very simple, but quite surprising and I thought I'll share something on what we did to fix it. &lt;p&gt;We are using a &lt;a href="http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.html" target="_blank"&gt;RollingFileAppender&lt;/a&gt; and common strategy for how to handle the log files; we're creating a new file for each new date. In order to achieve this we have set the following configuration:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appender&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="RollingLogFileAppender"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="log4net.Appender.RollingFileAppender"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;file&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="{a path here}"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appendToFile&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;rollingStyle&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="Date"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;datePattern&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="yyyyMMdd"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;layout&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="log4net.Layout.PatternLayout"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;conversionPattern&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="%date [%thread] %-5level %logger - %message%newline"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;layout&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;filter&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="log4net.Filter.LevelRangeFilter"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;levelMin&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="INFO"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;filter&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;OK – nothing strange here really. And actually it worked fine for a long time. But all of a sudden we have ran into the problems I described above. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;The solution is simply to add the “staticLogFileName” element to the configuration above, setting the value to false;&lt;/p&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;staticLogFileName&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And with that it started to work again. I found some questions around this on &lt;a href="http://stackoverflow.com/questions/533804/append-current-date-to-log-file-with-log4net" target="_blank"&gt;StackOverflow&lt;/a&gt; that was related but not exactly this. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;So if you name your RollingFiles logs with log4net with Dates – be sure to include the staticLogFileName = false setting. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-3333381899174569140?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/3333381899174569140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=3333381899174569140' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3333381899174569140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3333381899174569140'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/12/log4net-and-staticlogfilename-element.html' title='Log4Net, RollingFile named by Date and the staticLogFileName setting'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-8208460981540200585</id><published>2011-12-11T21:30:00.001+01:00</published><updated>2011-12-11T21:51:57.425+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecFlow'/><title type='text'>Creating a tools only NuGet package</title><content type='html'>&lt;p&gt;I have started to help out in a new OSS project. The last one was &lt;a href="http://www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; and now it’s &lt;a href="https://github.com/x97mdr/pickles" target="_blank"&gt;Pickles&lt;/a&gt;. Pickles is a tool that takes .feature-files from SpecFlow or Cucumber and turns it into a nice living documentation. It’s a great addition to SpecFlow. &lt;/p&gt; &lt;p&gt;Ok – one of the things I have been doing in the Pickles project is to create &lt;a href="http://www.nuget.org" target="_blank"&gt;NuGet&lt;/a&gt; packages for the project different runners and especially lately the PowerShell runner. This will be the main way to interact with Pickles locally, which basically means that you’ll just write a command in the &lt;a href="http://docs.nuget.org/docs/reference/package-manager-console-powershell-reference" target="_blank"&gt;Package Manager Console&lt;/a&gt; to generate the documentation frictionless. Later you will probably run it as part of your Nant or MsBuild build files. &lt;/p&gt; &lt;p&gt;I learned a great deal about PowerShell and NuGet when I put that NuGet package together and since it was quite some time since I blogged I thought I’ll write down my experiences. This post is a about the NuGet package. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;The goal of my package is to NOT add any references to any projects. I just want it to drop some assemblies as tools and then use the &lt;a href="http://technet.microsoft.com/en-us/library/dd819454.aspx" target="_blank"&gt;“Import-Module”&lt;/a&gt; PowerShell command to make the commandlet I’ve written available to the Package Manager Console. &lt;/p&gt; &lt;h4&gt;NuSpec&lt;/h4&gt; &lt;p&gt;&lt;a href="http://docs.nuget.org/docs/reference/nuspec-reference" target="_blank"&gt;NuSpec is a file format&lt;/a&gt; in which you specify how your package should be built. It’s actually not necessary in most cases since NuGet can package a Visual Studio project file straight off. But if you want more fine-grained control over how the package is created then you might want to create the NuSpec-file by hand.&lt;/p&gt; &lt;p&gt;The NuSpec-file is just plain XML and here is mine:&lt;/p&gt; &lt;p id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.0"&lt;/span&gt;?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;package&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;metadata&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pickles&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;$version$&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pickles - Gherkin Documentation Generator&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;authors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Marcus Hammarberg&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;authors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;owners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Jeffrey Cameron&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;owners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;projectUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;https://github.com/x97mdr/pickles&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;projectUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;requireLicenseAcceptance&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;false&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;requireLicenseAcceptance&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pickles is an ...&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;summary&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;A documentation generator ...&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;summary&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;copyright&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Copyright © Jeffrey Cameron 2010-2011&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;copyright&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;metadata&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;files&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;file&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="bin\Release\*.dll"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="tools"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;file&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="init.ps1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;target&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="tools\init.ps1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;files&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;package&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Most of the elements speaks clearly for themselves (I’ve shorten the content of some for readability):&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;At line 5 you can see how you can send in a version number to the NuGet Pack command (see below)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Line 15-18 specifies the files I want to include and where I want them to appear in the deployed package&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Noteworthy is that I don’t specify any dependencies here. I don’t want to add any references to the target project. I simply want to copy some files.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Note also that I’m including a powershell file called init.ps1 – see below about that file.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;Init.ps1&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;This is a PowerShell file that runs (if included) when a NuGet package installs. It’s perfect for doing installation stuff. Here is how the file look like for me:&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; param($installPath, $toolsPath, $package)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; Import-Module (Join-Path $toolsPath Pickles.PowerShell.dll)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; Write-Host &lt;span style="color: #006080"&gt;"#############################"&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; Write-Host &lt;span style="color: #006080"&gt;"Pickles installed."&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; Write-Host &lt;span style="color: #006080"&gt;"Comand usage (switches in brackets are optional):"&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; Write-Host &lt;span style="color: #006080"&gt;"Pickle-Features -FeatureDirectory -OutputDirectory [-Language] [-TestResultsFile] [-SystemUnderTestName] [-SystemUnderTestVersion]"&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; Write-Host &lt;span style="color: #006080"&gt;"#############################"&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;On line 1 we have some parameters that NuGet are sending to us. It’s basically some paths to different folder that might be interesting to us&lt;/li&gt;&lt;br /&gt;&lt;li&gt;On line 3 is the important stuff; here I do the Import-Module of the PowerShell commandlet I’ve written. &lt;br&gt;In order to get it to work I have to use another PowerShell command that joins paths to import it from the right folder&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The rest is just me writing out some interesting information (?) to inform the user how to use the command&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;These simple lines will “install” the commandlet into the Package Manger console and it can now be used. With full intellisense for all parameters of the command. Nice!&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;NuGet.Exe and the Pack command&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;NuGet also have a command with which you can &lt;a href="http://docs.nuget.org/docs/reference/command-line-reference" target="_blank"&gt;do a lot of stuff&lt;/a&gt; but here I was interested in the the Pack command. It turns a .nuspec or a Visual Studio project file into a .nupkg file that then can be deployed separately. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here is my command that operate on the .nuspec file I described above:&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; nuget pack Pickles.nuspec -Version %1 &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Nothing strange here,&amp;nbsp; I simply point to the .nuspec-file and pass a parameter as version. This allows me to use this command (.cmd-file) from a DOS-prompt to create new packages by simply setting the version number of the package. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;So for version 0.3 I got a file called “Pickles.0.3.nupkg”.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Trying out your package locally&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;A really nice feature of NuGet is that you can very easily set up a local NuGet repository. I’ve &lt;a href="http://www.marcusoft.net/2011/09/creating-local-nuget-repository-with.html" target="_blank"&gt;blogged about that before&lt;/a&gt; and it’s done is just a few minutes. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;So to try my package out I simply copied it into my local repository (just a folder on my computer) and then went “Install-Package Pickles” in the Package Manager Console in Visual Studio. I even got intellisense for the package name.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Conclusion and lessons learned&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;I had some strange problems with the references to dependencies for my package for a while. But when I cleaned my files up in order to write a &lt;a href="http://stackoverflow.com" target="_blank"&gt;StackOverflow&lt;/a&gt; question about it… the problems went away. Typical! I must have messed up. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;But I learned one very important thing when trying your packages out; Increment the version number for each new version! Or start a new project to import your package into. I suspect that the clean up didn’t always work as expected.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;All in all this is a very nice way to deploy a tool I think. It have taken me quite some time to put together but 70% of that have been me going back and forth trying to figure out why it didn’t work. Most likely that had to do with me using the same version number all the time.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The Pickles NuGet packages will be available from NuGet.org soon. Very soon. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-8208460981540200585?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/8208460981540200585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=8208460981540200585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/8208460981540200585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/8208460981540200585'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/12/creating-tools-only-nuget-package.html' title='Creating a tools only NuGet package'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-7973153048578917460</id><published>2011-11-29T20:27:00.001+01:00</published><updated>2011-11-29T22:34:36.362+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecificationByExample'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>What i learned from 'From User stories to Acceptance tests' with Gojko Adzic</title><content type='html'>I've just returned back home from a course. It's the first course I've attended in over a year and I'm always amazed how much you can learn in a short time; if the course and teacher is good and if you engage yourself in the course.&lt;br /&gt;&lt;br /&gt;This time I knew it would be great since &lt;a href="http://gojko.net/"&gt;Gojko Adzic&lt;/a&gt;&amp;nbsp;was the teacher and the subject was something that I find really interesting and useful - &lt;a href="http://specificationbyexample.com/"&gt;Specification by example&lt;/a&gt;.&lt;br /&gt;I would be completely impossible to write down even a fraction of all the stuff I picked up during the two days but I thought I stop at the main points and write down what stood out for me.&lt;br /&gt;&lt;br /&gt;As I've been following the BDD and Specification by example community intensively for two years I had quite a lot of knowledge on before hand - the main points I wanted to get out of this was practical tips on how to facilitate and handle the early phases of the lifetime of a specification done in this manner. Being a developer I have focused much on the later parts up to now.&lt;br /&gt;&lt;br /&gt;Here are the main topics we discussed, but not in this order as I remember:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Communicating with examples&lt;/li&gt;&lt;li&gt;Key process patterns of successful teams&lt;/li&gt;&lt;li&gt;What makes a good specification&lt;/li&gt;&lt;li&gt;Fitting into a development process&lt;/li&gt;&lt;li&gt;Adoption strategies and patterns&lt;/li&gt;&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;Communicating with examples&lt;/h3&gt;&lt;div&gt;We started this part by doing a simulation (a Black Jack game) in which we tried out what happens when we try to do "traditional" testing on a short development cycle. And our group went into all the traps that I've been preaching against for so long; developers and testers stopped communicating, we didn't involve the customer, we focused on the implementation rather than on business value. We even got the acceptance test case but returned them as we thought it was a mistake. No group asked the customer (Gojko) what he was expecting.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From that we started to look on how hard it is to understand each other and how the telephone game plays out in a software process. For even such simple stuff as to &lt;a href="http://gojko.net/2008/08/29/how-many-points-are-there-in-a-five-point-star/"&gt;how many points a simple symbol has&lt;/a&gt;&amp;nbsp;there were a lot of&amp;nbsp;disagreements.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We saw how using concrete examples could clarify that a great deal. And when we went back to our simulation and applied examples to the requirements we've got we actually could find a whole lot of&amp;nbsp;inconsistencies&amp;nbsp;in them. Here is was really powerful to find business concepts by using examples such as BlackJack and Busted for example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two kind of&amp;nbsp;exercises for creating examples as a group stood out to me:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Diverge and merge - where you intentionally let several groups work on the same example for a while and then merge the groups to compare and learn from each other.&lt;/li&gt;&lt;li&gt;A feedback&amp;nbsp;exercise which&amp;nbsp;reassembled&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Planning_poker"&gt;planning poker&lt;/a&gt; a bit. Write down a case and then each write the expected outcome. Compare and learn.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The main thing you want here is probably not the examples but rather to learn and get a shared understanding of the problem at hand. The examples is a great way to reach there and also to document them in.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;Key process patterns of successful teams&lt;/h3&gt;&lt;div&gt;This part I knew the most about during the course, since I've read the book and done presentation on these patterns. I still learned stuff of course:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;All the teams that was successful in implementing Specification by example specified collaborative and did that using examples&lt;/li&gt;&lt;li&gt;Key examples is not all examples. It's probably 10-15 not 500&lt;/li&gt;&lt;li&gt;Put up a couple of examples and try to break them (drill a hole in them) to see if all relevant key examples has been found&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;We then talked about some common collaboration patterns and when they might be applicable:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;All-team workshops - when stakeholders are available, you need loads of knowledge transfer (you don't know much about the domain) or you want to explore new ideas. Pretty expensive tough.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Three Amigos - get a Business Analyst, Developer and tester together and do a mini-workshop. &lt;a href="http://lh5.ggpht.com/_TI0jeIedRFk/THzCfVkXX9I/AAAAAAAAAlQ/rN05kWnVArs/s1600-h/specws1%5B2%5D.jpg"&gt;Hehe I drew this without knowing&lt;/a&gt;&amp;nbsp;a while back. This is useful when you have mature product that your team knows a bit about.&lt;/li&gt;&lt;li&gt;Ad-hoc conversation where you simple skid over and ask the involved people. This requires people being nearby and you knowing a lot about the product.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Write + Review - you write a specification and then have somebody else review it. Good if your are distributed and have a hard time to get hold of people needed to answer questions.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3&gt;What makes a good specification&lt;/h3&gt;&lt;div&gt;I loved this part and learned loads from this. The main part of this was us&amp;nbsp;dissecting&amp;nbsp;and discussing a big load of examples (great idea - examples to understand how to write examples). Together we came up with a big list of stuff that was good or bad with them.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are the good part, as we finally summarized them:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A descriptive title (what you would Google for to find this document)&lt;/li&gt;&lt;li&gt;Has context under which the example executes&lt;/li&gt;&lt;li&gt;No technical details such as database ids or web page class names&lt;/li&gt;&lt;li&gt;Short - in fact most of the good stories were considerable shorter than the bad ones&lt;/li&gt;&lt;li&gt;Precis - talks only about the example at hand.&amp;nbsp;&lt;/li&gt;&lt;li&gt;A structure in which the test was separated from the examples (&lt;a href="https://github.com/cucumber/cucumber/wiki/Scenario-outlines"&gt;Scenario Outline for Cucumber &lt;/a&gt;features for example)&lt;/li&gt;&lt;li&gt;Boundaries included - we triage and try different values to find the boundaries for the example&lt;/li&gt;&lt;li&gt;More than 1 example (see above)&lt;/li&gt;&lt;li&gt;Uses the business language - the domain language&lt;/li&gt;&lt;li&gt;Has the &lt;i&gt;right&lt;/i&gt;&amp;nbsp;abstraction level. This is a hard one but you reached this when you cannot remove anything without destroying it. Or another way is to ask someone to summarize the things you have written down. If they can and it's still understandable - use that summary.&lt;/li&gt;&lt;li&gt;Clear and&amp;nbsp;measurable&amp;nbsp;expectations&lt;/li&gt;&lt;li&gt;No new concepts introduced simply due to the fact that we're going to test this with a tool&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Other stuff that came up from Gojkos presentation was:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Don't write workflow scripts - write WHAT should be tested not HOW it should be tested. 90% of the team failing with BDD does this. 90%!!!&lt;/li&gt;&lt;li&gt;If you find yourself writing about technical concepts - try to rephrase it into what that technical thing does&lt;/li&gt;&lt;li&gt;Try to find breaking examples to find the boundaries&lt;/li&gt;&lt;li&gt;Show the example to someone else and see if they understand it (given domain knowledge). If so - then you have the right level of self-explanation.&lt;/li&gt;&lt;li&gt;Write the description of the test to be a description on how to read the examples.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3&gt;Fitting into a development process&lt;/h3&gt;&lt;div&gt;This was basically a number of case studies that showed how different teams had fitted the ideas of Specification by example into their process. It was quite interesting as it ranged from fully fledged agile teams to very rigid waterfall-type of processes.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few tips I picked up:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Set aside time before the planning (be it sprint planning or whatever) to prepare some key examples. That will make the actually planning much smoother not halting on the first question.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The more stuff that is unknown the further ahead the initial team should work. Work a sprint ahead if needed.&lt;/li&gt;&lt;li&gt;Get only bullet points with acceptance&amp;nbsp;criteria&amp;nbsp;from BA if they are very busy&lt;/li&gt;&lt;li&gt;Don't try to write out full specifications at workshops - who writes the &lt;a href="http://www.marcusoft.net/2011/09/who-writes-specification-now-again.html"&gt;specification is not important&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Emphasize&amp;nbsp;collaboration and shared understanding&lt;/li&gt;&lt;li&gt;Define tests as early as possible&lt;/li&gt;&lt;li&gt;Make sure that you get a mindset of collective ownership for the specification&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3&gt;Adoption strategies and patterns&lt;/h3&gt;&lt;div&gt;This was something that our group came back to. How do you introduce these concepts? How do you sell it to the team or the stakeholders.&lt;br /&gt;&lt;br /&gt;Firstly you can say that this is a general problem that has to do with any change. For that I would recommend the book &lt;a href="http://www.heathbrothers.com/switch/"&gt;Switch - how to make change when change is hard&lt;/a&gt;&amp;nbsp;that talk about a lot of strategies for change management. A quote that stuck is; "People don't resist change. People resist being changed" - if you get people to think that it's their idea you have gained a lot.&lt;br /&gt;&lt;br /&gt;Gojko had three points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Change the team culture &lt;/b&gt;to a culture of collaboration. Collaborate on specifications and test, which will build trust among team members. Focus on delivering business features and not&amp;nbsp;functionality&amp;nbsp;which will build trust with stakeholders&lt;/li&gt;&lt;li&gt;&lt;b&gt;Remove waste from the process&lt;/b&gt; - make things precis early to establish a clear definition of done. Validate frequently and strive to get a single source of truth - the examples. This will make other things you do&amp;nbsp;unnecessary (such as writing different documents for specifications and tests for example)&lt;/li&gt;&lt;li&gt;Facilitate change - make sure that the examples becomes the main source of information (send links to them to answer questions), document business process (do not "write tests")&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;This section also contained a lot of other stuff but it was discussed and is hard to write down here.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;div&gt;This post was my brain dump. I don't expect anyone to get it if you wasn't there. If you still did I'm very happy. If you didn't get it - please ask a question below and I'll answer to the best of my knowledge.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Again - thank you Gojko for a great course. I learned loads from you. Again.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-7973153048578917460?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/7973153048578917460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=7973153048578917460' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/7973153048578917460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/7973153048578917460'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/what-i-learned-from-from-user-stories.html' title='What i learned from &apos;From User stories to Acceptance tests&apos; with Gojko Adzic'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-5375736326531326102</id><published>2011-11-23T22:34:00.001+01:00</published><updated>2011-11-23T22:34:10.980+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>BDD and technical scenarios</title><content type='html'>&lt;p&gt;I got a question from Sham (Shamresh Khan) that I thought was interesting and also common. So I thought I post my answer here in the public and maybe we all can learn a bit. &lt;/p&gt; &lt;p&gt;Sham’s question was something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;…some of my scenarios/examples, may be very technical (i.e. checking some algorithm for example). If I write these tests under a user story (using the Gherkin syntax), a business analyst will be able to see them which may confuse them as they try to work out what scenarios exist under the user story or am I wrong here? Maybe all tests should be visible under a user story?&lt;/p&gt;&lt;/blockquote&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;TDD and BDD&lt;/h4&gt; &lt;p&gt;This is really one of the things we struggle with when coming from using TDD for a while and then starting doing BDD. In my opinion BDD is more than anything a communication tool that helps all parts of the development team to communicate and understand what is to be built – to build the right thing. &lt;/p&gt; &lt;p&gt;By using concrete scenarios and using in plain text we ensure that everybody can collaborate or at least understand and critique them. That is the main point and gain from &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development" target="_blank"&gt;BDD&lt;/a&gt; – communication and a way to quicker &lt;a href="http://dannorth.net/2010/08/30/introducing-deliberate-discovery/" target="_blank"&gt;find out what we don’t know about the feature in question yet.&lt;/a&gt; &lt;/p&gt; &lt;p&gt;That we get a way to test our system (end to end), and in that way can handle regression testing in a very nice way, is just a side effect. A VERY nice one but still just a side effect. Just like in TDD the main benefit not really is the tests but rather the possibility to take baby steps and produce well designed code. &lt;/p&gt; &lt;h4&gt;What to do?&lt;/h4&gt; &lt;p&gt;So after that long introduction… If you have technical stories or scenarios that your stakeholder cannot understand, I think you have a couple of possibilities:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If the feature in question is a business feature – you should probably discuss it further. If it’s an important business feature it will also be important for the business users. Rephrase it in the language of the business users. Hide the technicalities behind their terms. How it’s actually implemented is NOT important on this level. It’s a TDD-level thing.&lt;/li&gt; &lt;li&gt;If the feature is a truly technical scenario – it shouldn’t be in the BDD-specifications facing the business user at all. It shouldn’t be presented to them and quite frankly – they probably don’t care. (If they do one could wonder if they truly are a business user at all :P)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Actually to combine BDD and TDD is a great way to manage the question you just asked. You first set up the scenarios to get something to discuss around and help you understand and talk about the feature. When that is in place you also have a “definition of done” for the feature. You know how much to implement to fulfill the &lt;em&gt;current&lt;/em&gt; requirements. It’s has been referred to as doing &lt;a href="http://en.wikipedia.org/wiki/Outside%E2%80%93in_software_development" target="_blank"&gt;outside-in development&lt;/a&gt;.&lt;/p&gt; &lt;h4&gt;Tips on how to get there&lt;/h4&gt; &lt;p&gt;The two groups above could have the headings WHAT and HOW. I suggest that BDD should be about WHAT the system does for the business user – not about HOW it does that. Not about HOW it’s implemented. &lt;/p&gt; &lt;p&gt;A good way to ensure that you don’t miss that target is to work you way backwards; &lt;/p&gt; &lt;ul&gt; &lt;li&gt;start with the “So that”-part of the user story – the reason for the user story to exists. If you get that in place everything will be so much easier to understand and reason about. &lt;/li&gt; &lt;li&gt;then for the scenarios start with the “Then”-part – the goal and assertions you are going to make to know that you have fulfilled the goals of the scenarios. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I hope that you got something good out of this Sham. And maybe somebody else too. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-5375736326531326102?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/5375736326531326102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=5375736326531326102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5375736326531326102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5375736326531326102'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/bdd-and-technical-scenarios.html' title='BDD and technical scenarios'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-424518820119560162</id><published>2011-11-11T08:32:00.001+01:00</published><updated>2011-11-11T16:00:49.682+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ÖreDev'/><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>OreDev 2011 - day 3</title><content type='html'>&lt;a href="http://www.marcusoft.net/2011/11/oredev-2011-day-2.html"&gt;Last day&lt;/a&gt;&amp;nbsp;was great. I didn't go to anything that was really bad and I had some real highlights with Dan North, Gojko Adzic and Mark Rendle on Zen standing out as the best.&lt;br /&gt;&lt;br /&gt;After a short and intense Lean Coffee I'm not sitting and waiting for the keynote with &lt;a href="http://www.codinghorror.com/"&gt;Jeff Atwood&lt;/a&gt;, who&amp;nbsp;apparently&amp;nbsp;just introduced himself and then went off the stage yesterday. Let's see if he does the keynote himself today&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;Jeff Atwood on StackOverflow&lt;/h3&gt;&lt;div&gt;Jeff did the talk himself (and talked fast, fast, fast!). He talked about how programmers need rules and likes to follow (or even create) rules. Take Facebook for example - who has a "list of their friends" at home. No-one! But a geek could understand social networks by creating rules around them. A list of friend for example.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Huh - I didn't know that Jeff Atwood did invent the game-ification part of StackOverflow by accident. By just being a geek trying to get the most out of a Q&amp;amp;A situation. All of it; numbers, badges etc. was just a programmer analyzing a social&amp;nbsp;situation&amp;nbsp;and&amp;nbsp;modeling&amp;nbsp;it as a game. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Good game design forces you towards the behavior you want from your players. In Counterstrike you cannot win alone. You need to play with others and as a team. And if your anonymous or not doesn't matter.&lt;/div&gt;&lt;div&gt;The same on StackOverflow:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;You cannot win without teaching&lt;/li&gt;&lt;li&gt;Individual&amp;nbsp;skill is always inferior to communication skills&lt;/li&gt;&lt;li&gt;Discussion is risky; sharing research and experience.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;The ultimate goal is to advance knowledge in the topic for everyone.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Discussions are not promoted because we don't learn from peoples opinions. That's why discussion type questions are downvoted. They will take up place from the questions and answers that StackOverflow wants to be the source of.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Saying No is important to stand out and be pushed into a bland site by the community. "We're playing the StackOverflow game here. If you want to play another game (a.k.a. ask open ended questions) there are other sites". So in a way the community needs to be protected from themselves. With moderation for example.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Tim Huckaby on HTML5 web applications for Windows 8&lt;/h3&gt;&lt;div&gt;So I think I will try to pick up some Windows 8 information and skills during this last day of OreDev. So I'll first start with some HTML 5. Tim Huckaby is a guy is heard in a lot of podcasts. Nice to see him live.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tim started up with stating that we WILL do HTML 5 soon. He started to give a short history of why HTML5 will be big; Apple loves it, Google loves it and Microsoft also loves it.&lt;br /&gt;&lt;br /&gt;15 minutes left of this talk and I'm still to see code. I'm learning a lot on the history and fears of HTML5 (only 54% of the internet users today can use it, for example). &amp;nbsp;On with the code Tim!&lt;br /&gt;&lt;br /&gt;Nope - no code in Visual Studio here. I'm a bit misled here i think. I learned something but it was more entertainment. Not bad entertainment but not very informative.&lt;br /&gt;&lt;br /&gt;Well..... no he didn't have time. It was entertaining but I didn't learn anything of the things I hope for. Sad.&lt;/div&gt;&lt;h3&gt;Mattias Karlsson on Java 7&lt;/h3&gt;&lt;div&gt;I now popped into the Java track again to see a friend and&amp;nbsp;colleague, Mattias Karlsson, doing a talk on the news in Java 7. I'll brace myself on asking any Java vs .NET questions in here :). Go Mattias!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Mattias is stating that the biggest news of Java 7 is that actually is out. From history we was shown that is big news since Java 6 was released in 2006. So the new release is long awaited.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hmmm - there's been trouble in Java-land for quite some time as I understand it from Mattias run through history. Politics and business has ruined progress for quite some time.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Leaving that boring stuff out the news are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;new garbage collector called G1 - which is great news for performance tweaking.&lt;/li&gt;&lt;li&gt;Mattias showed some benchmark result for other more general performance. 40% faster than Java 6 - wow! But Mattias thought that it could be closer to 10%&lt;/li&gt;&lt;li&gt;On the concurrency side a new instruction called Fork/Join is introduced. For me it looked like a more low-level implementation of&amp;nbsp;parallel&amp;nbsp;LINQ. That is - PLINQ hides a lot of the things that you need to implement in Java 7. But it must be great to have it if it was missed before. Ha! Mattias&amp;nbsp;recognized&amp;nbsp;that the model still is very low level - I got it before him :). He hinted that a more&amp;nbsp;declarative&amp;nbsp;/&amp;nbsp;implicit&amp;nbsp;model is on its way in Java 8.&lt;/li&gt;&lt;li&gt;Also the JVM that comes with Java 7 has support for dynamic&amp;nbsp;languages. With features that even Java cannot reach! We were shown a way to "invokedynamic" that is a way to via a string call a string.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Other small changes:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;You can switch on strings now.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Improved exception - catch multiple exceptions in the same catch-clause. Nice!&lt;/li&gt;&lt;li&gt;Hehe - you can add underscores in numbers. So you can write 1000000000 as 1_000_000_000 if you like.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Some better Resource management, such as external resources such as database, string or files. Nice syntax in which you can state the resources you are using in a block. Looks a bit like using in C#&lt;/li&gt;&lt;li&gt;Java 7 has improved it's generic type inference so that you have to write stuff twice&lt;/li&gt;&lt;li&gt;A new new IO - called NewIO2 :)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Mattias ended with a peek into what will come in Java8. Lamdas - yay! A first-class implementation of JavaScript running on the JVM. Cool!&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;Jim Benson on Healty projects&lt;/h3&gt;&lt;div&gt;After a lunch where I had the time to talk with &lt;a href="http://andreasohlund.net/"&gt;Andreas Öhlund&lt;/a&gt; about NService bus and CQRS. I learned about Amazon that actually has their read data on a CDN! Amazingly cool - distribute read data on the internet. Not even hitting your server! Cool cool cool!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK - now on to &lt;a href="http://twitter.com/ourfounder"&gt;@ourfounder&lt;/a&gt; Jim Benson on healthy project. He starts to say that knowledge workers works best when thy are happy.&amp;nbsp;&lt;/div&gt;&lt;div&gt;We got to describe the following to others in the audience:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;What do you do at work?&lt;/li&gt;&lt;li&gt;What does your boss do?&lt;/li&gt;&lt;li&gt;What is the goal for the company you work on?&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Fewer and fewer persons could answer those questions. It gets harder and harder the further away from us you get. And if you don't know the goal of levels above (or below) you you can't have a healthy project.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We create rules to manage our organizations problem with communication between levels. The problem, however, is that those rules make us more likely to fail in following them. We "mess up" to put it short (sorry Jim, no&amp;nbsp;profanity&amp;nbsp;on this blog).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jim made an argument that really stuck with me; a Kanban board is not about moving stuff fast - it's about creating quality software. I've fallen into this trap. I want tickets to move fast, but I wouldn't sacrifice quality of course. But I haven't been teaching that - I've been telling people to go fast and that's the purpose of Kanban.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jim tipped us on something that he called: "Subject well-being". It's simply to write a small smiley on the tickets as you finnish them. Using this technique you is less likely to smooth things over as time has passed from the time you did an awful task to the retrospective. Good tip!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Status meetings was invented by&amp;nbsp;hierarchical&amp;nbsp;organizations to keep them in a tight band. So if you have your status on the board - do you really need a morning meeting to communicate status? No, I say, but maybe to get a team feel and be little better each day.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Conflict avoidance makes conflicts a lot (!) worse. And that doesn't help our project becoming healthy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is the definition of success in your project? Is it possible to hit that exact mark? Could it be changed? Don't&amp;nbsp;over define&amp;nbsp;your success criteria.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The indian company TADA hand out award for the best failure last year. The celebrate failures and act on them.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;David Evans on Time off for good behavior&lt;/h3&gt;&lt;div&gt;David talked about how to extend the useful life of the&amp;nbsp;artifacts&amp;nbsp;we are creating when doing BDD (or ATDD or Specification by example...). The artifacts he talks about is the feature-files, for us Gherkin-geeks.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;David state a list of problems or syndromes:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A BDD specification is NOT just a test. AMEN!&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Script is not specifications. Very common pattern when writing based on the assumption that a feature is a test.&lt;/li&gt;&lt;li&gt;&lt;b&gt;A BDD artifact is more than just as test&lt;/b&gt;; it's a Specification (Now), Test (Soon) and Documentation (Later) all wrapped up in one&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Don't skimp on the descriptive parts of your artifacts&lt;/li&gt;&lt;ul&gt;&lt;li&gt;You should do BDD artifacts to satisfy humans, not tool.&lt;/li&gt;&lt;li&gt;Tips on User stories&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;User stories are for Users. A system is not a stakeholder in the story&lt;/li&gt;&lt;li&gt;Don't write the solution - write why you need that&lt;/li&gt;&lt;li&gt;Put the business value first (In order to). Otherwise you risk that the last part of the story is just re-stating the first line&lt;/li&gt;&lt;li&gt;Let the "In order"-clause always talk about improvement (increase, improve). Change something on a scale.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Keep the Why, What and How separated&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Tips on Scenarios&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Write a first simple positive scenario.&amp;nbsp;Don't only have one scenarios but start with the simple, happy path.&lt;/li&gt;&lt;li&gt;Don't run away and try with every possible edge case. It's important but when we write specifications we only try to find out what we don't know yet&lt;/li&gt;&lt;li&gt;Don't write to much technical details (database-fields for example)&lt;/li&gt;&lt;li&gt;Write your Then-clause first and work your way backwards. Great tip!&lt;/li&gt;&lt;li&gt;Include a keyword from your assertion in the name of the scenario&lt;/li&gt;&lt;li&gt;Make sure that your expectations crisp and the rest will follow to be equally crisp on a as-needed-bases&lt;/li&gt;&lt;li&gt;Look out for Given that are irrelevant to the Thens&lt;/li&gt;&lt;li&gt;Keep the level of abstraction the same&lt;/li&gt;&lt;li&gt;Hour-glass shaped Scenarios; just one line on the WHEN-line!&lt;/li&gt;&lt;li&gt;Bordered edges - examples and counter-examples.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Competing forces of a BDD document&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;As the document is fulfilling different roles (Specification, Test and Documentation) we have different forces pulling in the document.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Scope&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Specification: Specific&lt;/li&gt;&lt;li&gt;Test: Integrated&lt;/li&gt;&lt;li&gt;Documentation: Maintainable&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Detail&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Specification: Clear and terse&lt;/li&gt;&lt;li&gt;Test: Completeness&lt;/li&gt;&lt;li&gt;Documentation: Self-explanatory&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;BDD folks seem to be from Great&amp;nbsp;Britain and use &lt;a href="http://www.prezi.com/"&gt;Prezi&lt;/a&gt; for presentation. David used Prezi to great effect. For example left a final slide that summed up the talk. Thank you, David!&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Gojko Adzic on&amp;nbsp;Visualizing&amp;nbsp;Quality&lt;/h3&gt;&lt;div&gt;I had a really hard time to pick the last session. But ultimately I went with Gojko on the subject of quality. We started early but calling out examples of quality&amp;nbsp;measures. Hard actually - try for yourself. How do you measure the quality to know when you're ready to ship?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Testers are in the information business! Or rather Inforvate (inform and motivate). Gojko talked about &lt;a href="http://www.heathbrothers.com/switch/"&gt;Switch by the Heath brothers&lt;/a&gt;. We need to inform the rider of the elephant but also motivate the elephant.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;He posed the question; What if you disabled most of your functional tests after implementation? Gojko related a story of a company that disabled their functional tests after development was done. They haven't had major bugs in production for a year. They have decided how to measure quality on business value and visualizing it.&lt;br /&gt;&lt;br /&gt;An absence of bugs does not equal a presence of quality. We rather should measure what the people who wants the system, likes and care about. Bug count is not that important.&lt;br /&gt;&lt;br /&gt;Try this; get your stakeholders in your room. Write down 3 things you care most about this software. You'll get more results than any developer team can deliver. Most business users don't know what they want - we need to help them.&lt;br /&gt;&lt;br /&gt;People who ask for control really wants visibility - Elisabeth Hendrickson. Gojko related another story where they simply showed when the last content (in a content&amp;nbsp;management&amp;nbsp;system)&amp;nbsp;was published. They just showed the waiting time. No fixing the system. The complaints - that had be plentiful - stopped.&lt;br /&gt;&lt;br /&gt;Visualize quality&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Low tech testing dashboard - show a traffic light kind of status on how you feel about the quality on different areas in the system&lt;/li&gt;&lt;li&gt;Risk/Test heatmaps or charts&lt;/li&gt;&lt;li&gt;Use &lt;a href="http://gojko.net/effect-map/"&gt;effect maps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://googletesting.blogspot.com/2011/10/google-test-analytics-now-in-open.html"&gt;ACC (Attribute component capabilities) &amp;nbsp;Matrix&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The main point is - don't measure bug counts, that is not value. That is just measuring failure. Measure whats important for the users of the system. And visualize it - you can it in a concrete and talk-&lt;b&gt;about&lt;/b&gt;-state.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Go and give your suggestions - &lt;a href="http://visualisingquality.org/"&gt;visualisingquality.org&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;div&gt;So with that another great stay at &lt;a href="http://www.oredev.org/"&gt;OreDev&lt;/a&gt; was over. I'm tired but happy as always after these kinds of events. Thank you everybody!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-424518820119560162?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/424518820119560162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=424518820119560162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/424518820119560162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/424518820119560162'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/oredev-2011-day-3.html' title='OreDev 2011 - day 3'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-2535742331658073774</id><published>2011-11-10T17:24:00.000+01:00</published><updated>2011-11-10T17:25:37.559+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ÖreDev'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>OreDev 2011 - day 2</title><content type='html'>As always - after the first day my head was just spinning. I was so tired that I slept before I hit the pillow. But today I'm feeling great again and am ready for another great day of learning.&lt;br /&gt;&lt;h3&gt;Dan North on Embracing uncertainty&lt;/h3&gt;&lt;a href="http://dannorth.net/"&gt;Dan North&lt;/a&gt;&amp;nbsp;is one of my true&amp;nbsp;heroes&amp;nbsp;in our industry. I've learned a lot of the stuff that I'm excited about from stuff he written and spoke about. This is about embracing uncertainty - which seems to sit nice with the whole BDD - &lt;a href="http://dannorth.net/2010/08/30/introducing-deliberate-discovery/"&gt;Deliberate Discovery&lt;/a&gt; body of knowledge. Here's a few things I jotted down:&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;ul&gt;&lt;li&gt;Patterns of effective delivery (behavior&amp;nbsp;patterns that is)&lt;/li&gt;&lt;li&gt;How we turned the&lt;a href="http://www.agilemanifesto.org/"&gt; agile manifesto&lt;/a&gt; upside down nowadays&lt;/li&gt;&lt;li&gt;The half-time of&amp;nbsp;requirements&amp;nbsp;- how long time before half the requirements needs to be rewritten&lt;/li&gt;&lt;li&gt;"We would rather be &lt;b&gt;wrong&lt;/b&gt;&amp;nbsp;than be uncertain!"&lt;/li&gt;&lt;li&gt;Christianity (!) and how faith become religion. Or values becoming rules and structure. And the values disappear in the structure. Jesus was anti-religion of the structures in his time.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The answer don't matter -&amp;nbsp;struggling&amp;nbsp;with question is.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Kent Beck didn't talk about the 12&amp;nbsp;practices&amp;nbsp;of XP. He focused on values and said: What I want to do is to get business and IT to talk each others. The practices was just ONE way to reach his goal.&lt;/li&gt;&lt;li&gt;Get a handle on uncertainty to be able to manage it. One way to do that is embracing uncertainty:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;embracing uncertainty of scope - with rolling wave planning for example&lt;/li&gt;&lt;li&gt;embracing uncertainty of technology - start code by sketching out stuff for example&lt;/li&gt;&lt;li&gt;embracing uncertainty of effort - for example beyond budgeting (measure&amp;nbsp;stuff and handling money as it was your own)&lt;/li&gt;&lt;li&gt;embracing uncertainty of structure -&amp;nbsp;structure&amp;nbsp;only gives you an illusion of control. you can't predict the future&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Real options: a model of uncertainty -&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Options: making a deal that someone to buy the right to do something in the future. Buy the right to buy a bunch of SEK at a fixed price for example.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Real options - betting against yourself in your everyday&amp;nbsp;decisions.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Create options for every&amp;nbsp;decision&amp;nbsp;&lt;/li&gt;&lt;li&gt;"Never commit early unless you know why"&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Deliberate discovery - "Some unexpected bad things will happen" - go and find them. Optimize for finding them. You can actively reduce that ignorance.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Goes without saying - that was great!&lt;/div&gt;&lt;h3&gt;Greg Young on&amp;nbsp;When not to use CQRS&lt;/h3&gt;&lt;div&gt;Greg is going&amp;nbsp;stone-age&amp;nbsp;on us. No slides, no whiteboard and no sound! :) Nice! &lt;br /&gt;The hall is &lt;b&gt;packed&lt;/b&gt; - this promise to be great.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;CQRS and Event Sourcing is not&amp;nbsp;suitable&amp;nbsp;for monolithic applications. We need bounded contexts - a huge point of CQRS (and ES) is decoupling. So if you put everything in one big pile anyway - why bother?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;CQRS applied in non-core (huge return on investment) applications. Is this an area where our company is where we&amp;nbsp;derive&amp;nbsp;our&amp;nbsp;compatible&amp;nbsp;advantage.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Don't use CQRS for the technical reasons - programmer pornography. It could be considered but should be applied within a single bounded context. It's not done for all bounded&amp;nbsp;contexts.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A common problem is to do CQRS (and ES) and making a lot of decisions upfront. Deciding to use BizTalk before you know what you're actually building.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using CQRS and becoming use case centric without buy-in from the business. "Only the development team think is that they are core business." Often combined with not being a domain expert. There is a difference in being an expert in how the system currently works and being domain experts.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nice exercise; sit with the domain expert in just 2 h. Then build the complete system (or at least the domain model). You will fail! But you will raise some important questions. Now go back to the domain expert again and ask those questions. Sit again in 2 h. Delete the code you did the first day. Rinse, lather, repeat.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Don't write a CQRS framework. Hey, don't even USE a CQRS framework. Just do it! You should be able to be up and running with something giving business value in a day. Otherwise you might be focusing on the wrong thing.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Use frameworks for stuff that would take a long time to write it yourself. CQRS could be (and is) written in 200 lines - don't use a framework. MVC would take considerably longer than that. :)&lt;/div&gt;&lt;h3&gt;Richard Öberg on Event sourcing explained&lt;/h3&gt;&lt;div&gt;Richard will talk about what event sourcing is needed for and what it will give you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was probably a bit tired but this didn't grasp me. Richard shows some concise code written in his framework. Ironically Greg Young spent about 40 % of his talk on how you shouldn't write framework.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I liked Richards concept of exposing the events as ATOM feeds. He saves them in JSON format and can then expose them as ATOM feeds for reporting for example. Or send them further to other services.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Storing the events in the first place opens a lot of possibilities; domain events that informs other parts of the system or other systems, reporting, replication, backup and an audit log for free. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By storing the events as the come in gives you a much more&amp;nbsp;fine grained&amp;nbsp;control.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I personally think is that to sell event sourcing to business is a bit scary. But you could probably do ES anyway by simply have a reporting database that is kept in sync with the event source. So that there still is a relation database that most businesses are used to.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Lunch&lt;/h3&gt;&lt;div&gt;I had great discussions with&amp;nbsp;colleagues&amp;nbsp;and friends on CQRS and Specification by example. Again struck by the fact that best learning is taking place in the breaks. Hard to sum up in blog posts though. :)&lt;/div&gt;&lt;h3&gt;Gojko Adzic on Sleeping with the enemy&lt;/h3&gt;&lt;div&gt;Again Gojko is talking about something that really struck a chord with me. So why is testers and developers; us and them? Why does developers "know" more about "developing" and tester more about "testing" than developers?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Independent&amp;nbsp;testing, code freeze,&amp;nbsp;requirements&amp;nbsp;sign-offs and document change&amp;nbsp;management - none of these were done by any of the amazingly successful teams that Gojko interviewed for his book. There were the team with no bugs in production for the last 5 years, doing releases every other weeks, for examples. Or having so few bugs that they don't even use a bug tracking tools - another example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Disbanded the developers team and the tester team and created a team that is responsible for testing. And developing. Hey - they are responsible for the quality of the product. And they level out the knowledge gap (developing, testing) to better understand and help each other.&amp;nbsp;&lt;/div&gt;&lt;div&gt;In the process they removed a bottleneck (undermanned in the testing department).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We took a quick poll on who should own test automated functional test? The audience&amp;nbsp;argumented&amp;nbsp;for both but Gojko disagreed,&amp;nbsp;arguing&amp;nbsp;that programmers HATE doing automated tests and hence minimizing. &amp;nbsp;Testers should/could spend time their time on designing tests (that testers are good at) and programmers can then automate them (a typical developer skill).&amp;nbsp;&lt;/div&gt;&lt;div&gt;Nice - but I disagree with the&amp;nbsp;incentive&amp;nbsp;for programmers to do it.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gojko told a story where this kind of co-operation occurred by the developers just sitting next to the tester. Not testing. What&amp;nbsp;happened? They started to suggest what could be automated, they learned about the problems that the testers experienced and where problems and&amp;nbsp;misunderstandings&amp;nbsp;occurred in the system. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Developers and testers need to start working together. Get together as a whole team and ask yourself; what is our number 1 problem and how shall we solve it?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A story on a very productive team that produced excellent quality. But after a while they needed to test a lot of platforms and hired a tester to help them with setting that up. They hired a brilliant tester. But quality took a nose dive. Why? Because all of a sudden they had a tester - who had become responsible for testing. Everybody else stopped to care about test - something they did before!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Testers should be responsible for ensuring that the right things, testing the critical ("hard") stuff and teaching other how to test.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Testers is a common bottleneck in companies today. Why? Because they take on to big a responsibility - move the testing responsibility to everybody.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Mark Rendle on Zen and the art of Software&lt;/h3&gt;&lt;div&gt;I moved myself into the excellence-track (hey look at me:)) to see Mark Rendle, the creator of &lt;a href="https://github.com/markrendle/Simple.Data/"&gt;Simple.Data&lt;/a&gt;&amp;nbsp;and a general interesting guy. And from the topic of the presentation this promise to be interesting too :).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Mark started with some book tips:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Pragmatic programmer&lt;/li&gt;&lt;li&gt;Design patterns&lt;/li&gt;&lt;li&gt;Code complete&lt;/li&gt;&lt;li&gt;Clean code&lt;/li&gt;&lt;li&gt;Zen &amp;amp; the art of motorcycle maintenance&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;That last one is a bit surprising and the topic for this talk. It's a book about quality.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Mark is reading from the book and gives comments - novel way for a talk, I must say.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We're talking about what it takes to create quality software; stripping away all the xDD and tools.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Put yourself in the mind of the user. They will use the software. Maybe 8 h a day. So if the software is boring, breaks or hard to use - your are ruining 1/3 of the users life!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Classical understanding (art or code for example) and romantic (art or UI for example). The understanding of the system for the user is actually the UI not the code.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gumption, a old scottish word; what happens with someone who connects with quality - he is filled with gumption. Drive and enthusiasm. So what is the Gumption traps then? What draws Gumption from us?&lt;/div&gt;&lt;div&gt;&lt;b&gt;External Gumption traps&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Getting it wrong - be safe on this by having regression tests for examples.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Intermittent failure - this that is wrong becomes right as you start fixing it. The only way find these kind of failure is to setup a whole lot of profiling.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Parts - third party products in our business. Choose parts from people/companies with Gumption.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Internal Gumption traps&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Value rigidity - "my programming language is better than yours". This is a fast moving business - you can't have value&amp;nbsp;rigidity. Expect that you will slow down when you learn new things&lt;/li&gt;&lt;li&gt;Ego - similar to the value rigidity. Approach everything with the attitude as if your were a complete idiot. One day you'll find that you is not an idiot anymore&lt;/li&gt;&lt;li&gt;Anxiety - don't dare do anything of fear of failure. Get control with a Kanban-board or similar&lt;/li&gt;&lt;li&gt;Boredom - flow is the other end of boredom. To get in to flow you can use TDD.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Impatience - give yourself more time. Overestimate. Otherwise you'll end up taking shortcuts&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Living right - no job is not "just a job". You do your job to feel good about yourself!&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is quality? How do you know when you delivered quality? &lt;/div&gt;&lt;div&gt;Code is not software by itself. It's software when an user actually starts to use it. Quality cannot be&amp;nbsp;measured&amp;nbsp;until that moment.&lt;br /&gt;&lt;br /&gt;The end of the talk was almost a bit emotional... until a phone rang and Mark had too use some profanity to make it stop. So in the same talk we got laughs, tears (well ... almost) and profanity. Pretty amazing for a technical talk :)&lt;/div&gt;&lt;h3&gt;Mark Rendle on Phone Apps Unlimited&amp;nbsp;&lt;/h3&gt;&lt;div&gt;And then I went out for awhile. My brain was going slower and slower so I need some air. It worked wonders and now I'm back for another, very different, Mark Rendle talk. This time on Phone Applications. Sadly I have to leave early, but hey I'll get some goodness as long as I'm in here.&lt;br /&gt;&lt;br /&gt;I talked with Mark before the so I know that the talk will be about moving so much as possible onto a server that your applications can call via HTTP. That means that you can write simple simple applications (views if you want) to call into the server.&lt;br /&gt;&lt;br /&gt;65% of the internet traffic in the US is from mobile traffic and climbing. Windows 8 is a not windows anymore, it's mobile platform. With these quotes Mark got our sense and urgency.&lt;br /&gt;&lt;br /&gt;All different platforms (Android, IOS, Windows Phone 7) all have different tools and&amp;nbsp;languages. So what could we do?&lt;br /&gt;&lt;br /&gt;Well in the cloud we have unlimited resources and can chose our platform and languages. So we try to move as much as possible to the server (in the cloud).&lt;br /&gt;&lt;br /&gt;As such Mark has created a &lt;a href="http://pocketgcc.sourceforge.net/pcsharp/"&gt;Pocket C# &lt;/a&gt;- a small IDE in the phone. The actual compiling and all the heavy lifting is done on the server. The writing of code and viewing of the result is done on the phone. Nice!&lt;br /&gt;&lt;br /&gt;For example - use &lt;a href="http://www.dropbox.com/"&gt;DropBox&lt;/a&gt; to store files. It's simple and straightforward to build. Using &lt;a href="http://nuget.org/List/Packages/ReactiveOAuth"&gt;ReactiveOAuth&lt;/a&gt;&amp;nbsp;to do authentication.&lt;br /&gt;&lt;br /&gt;Use &lt;a href="http://watwp.codeplex.com/"&gt;Windows Azure Toolkits for Phones&lt;/a&gt;&amp;nbsp;to reach the &lt;a href="http://www.microsoft.com/windowsazure/"&gt;Azure services&lt;/a&gt;&amp;nbsp;such as&amp;nbsp;SQL Azure or Azure storage for example. And some great great scalability "for free" :)&lt;br /&gt;&lt;br /&gt;I suggest everybody interested in great ways of building phone applications using your existing skills to find the code from this talk. Some great stuff in here!&lt;/div&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;div&gt;And now I'm off meeting an old friend.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-2535742331658073774?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/2535742331658073774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=2535742331658073774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2535742331658073774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2535742331658073774'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/oredev-2011-day-2.html' title='OreDev 2011 - day 2'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-5241683517940752704</id><published>2011-11-09T19:05:00.000+01:00</published><updated>2011-11-09T19:05:12.509+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ÖreDev'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>OreDev 2011 - day 1</title><content type='html'>I was very fortunate to go to OreDev this year. It's just a great show - I described it as a "free bar of knowledge alcohol for learn-o-holics".&lt;br /&gt;I thought I'll take a few moments just to jot down some highlights and stuff I picked up during my first day at &lt;a href="http://www.oredev.org/" target="_blank"&gt;OreDev 2011&lt;/a&gt;. This is mostly for me... but you can read it if you want.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;Jon Skeet on Async in .NET 4.0&lt;/h3&gt;&lt;div&gt;I was late to the conference and missed the keynote, that I learned was awesome, and also late to this talk. Jon Skeet on the asynchronous features of .NET 4.0. I picked up some stuff though - most noteable I'll check out the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx" target="_blank"&gt;EduAsync&lt;/a&gt;&amp;nbsp;blog posts and code that shows of all interesting features.&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Aslam Kahn on Functional programming&lt;/h3&gt;&lt;div&gt;From this great session I picked up how Alsam had learned functional programming and how that changed how he thought about functional programming; building from simple structures and doing simple transformations on them, to finally abstract concepts on top of that.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Stop think about interactions between objects and start thinking of values of data and transformations on those data instead. Keep it immutable and return something from every function.&lt;/div&gt;&lt;div&gt;That doesn't come out right here but was great.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.slideshare.net/aslamkhn/not-quite-object-oriented" target="_blank"&gt;His slides is here&lt;/a&gt;.&lt;/div&gt;&lt;h3&gt;Sebastian Lambla on Restful API&lt;/h3&gt;&lt;div&gt;This was a great presentation. Loads of fun and a real practical introduction to REST. Thought me to:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Send links back to the client so they now WHERE to go next; Link: ; rel="next"&lt;/li&gt;&lt;li&gt;Send back an empty form so the client knows WHAT to send back&lt;/li&gt;&lt;li&gt;Don't version - but break if data is needed. If not needed use optional values&lt;/li&gt;&lt;li&gt;Send control data in the form so that the client knows HOW to send additional requests&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;All this will reduce coupling between the client and the server.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;Phil Haack on Mobile in ASP.NET 4&lt;/h3&gt;&lt;div&gt;Phil struggled with the technology for the presentation but still showed some nice features and ways to make you web application be more mobile friendly.&amp;nbsp;&lt;/div&gt;&lt;div&gt;I'll sure check out &lt;a href="http://jquerymobile.com/" target="_blank"&gt;JQueryMobile&lt;/a&gt; that looks awesome&amp;nbsp;&lt;/div&gt;&lt;h3&gt;Christian Johansen on TDD and JavaScript&lt;/h3&gt;&lt;div&gt;This was another great session on how to do TDD in JavaScript. Amusing fact was that 100% of the people in the audience did TDD. 0% (!) of us did it in JavaScript.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Christian had some mean skills and the flow of the session was great. I'll check out JsTestDriver and maybe even check out his book.&lt;/div&gt;&lt;h3&gt;Felix Geisendörfer on Node.js&lt;/h3&gt;&lt;div&gt;And finally I went to learn some more about &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt;. I think it sound very cool and I was blown away; this is huge (#2 watched project on GitHub, 230 contributors).&lt;/div&gt;&lt;div&gt;And the performance was equally impressive due to that everything in Node.js is what's called a "Non-blocking call" or&amp;nbsp;asynchronously if you want.&amp;nbsp;&lt;/div&gt;&lt;div&gt;And then my day came to a full circle with async again. &amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-5241683517940752704?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/5241683517940752704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=5241683517940752704' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5241683517940752704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/5241683517940752704'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/oredev-2011-day-1.html' title='OreDev 2011 - day 1'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-508246732156716014</id><published>2011-11-02T08:00:00.000+01:00</published><updated>2011-11-03T16:34:05.677+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecificationByExample'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecFlow'/><title type='text'>SpecFlow.Assist.Dynamic–maxing out with Simple.Data</title><content type='html'>&lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; came about from my own need when I wrote something that used &lt;a href="https://github.com/markrendle/Simple.Data" target="_blank"&gt;Simple.Data&lt;/a&gt;. I saw the power and simplicity (duh!) in Simple.Data by using dynamics. And I started to thinking on how it could be used in &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; to further simplify and shorten up the code in my steps. &lt;br /&gt;This is the third and final post on SpecFlow.Assist.Dynamic. Again this is not the formal documentation. It can be found &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/wiki" target="_blank"&gt;here&lt;/a&gt;. These are just my personal preferences and thoughts on how to use it. This time with Simple.Data. And it won’t be long. &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;SpecFlow and Simple.Data&lt;/h3&gt;First you should check out Darren Cauthons &lt;a href="http://darrencauthon.posterous.com/61641417" target="_blank"&gt;post&lt;/a&gt; on using SpecFlow and simple data together. It shows the great use of a lightweight, simple data access framework in SpecFlow. &lt;br /&gt;As I said in my earlier post test data management is something that you often have to handle in your scenarios. Simple.Data is more than up to the job. &lt;br /&gt;&lt;h3&gt;SpecFlow.Assist.Dynamic and Simple.Data&lt;/h3&gt;So I thought I’ll take Darrens example from the post and rewrite it using SpecFlow.Assist.Dynamic. &lt;br /&gt;Here is the feature Darren is using, updated to be a bit more readable for a non-technical person (spaces in headers):&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; Scenario: Submit a valid create account form&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;  Given the following accounts exist&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;      | First name | Last name | Email   |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;      | Howard     | Roark     | h@r&lt;span style="color: red;"&gt;.&lt;/span&gt;com |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;  When I submit the following Create Account form&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;      | Field      | Value   |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;      | First name | John    |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;      | Last name  | Galt    |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;      | Email      | j@g&lt;span style="color: red;"&gt;.&lt;/span&gt;com |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;  Then the following accounts should exist&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;      | First name | Last name | Email   |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;      | Howard     | Roark     | h@r&lt;span style="color: red;"&gt;.&lt;/span&gt;com |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;      | John       | Galt      | j@g&lt;span style="color: red;"&gt;.&lt;/span&gt;com |&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;SpecFlow.Assist.Dynamic will convert the “First name” header into “FirstName” as you &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/wiki/Conventions-used" target="_blank"&gt;might remember&lt;/a&gt;. As will the statically typed SpecFlow.Assist table helpers if I remember correctly.&lt;br /&gt;I first create the Simple.Data dynamic database object in the a method marked with the attribute BeforeScenario. And while I’m there I clear out the Accounts table as well:&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; dynamic DB { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; [BeforeScenario]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Setup()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     DB = Database.Open();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     DB.Accounts.DeleteAll();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the Given step I’m using the step argument transformations that comes with SpecFlow.Assist.Dynamic and get a &lt;span style="font-family: 'Courier New';"&gt;IList&amp;lt;dynamic&amp;gt;&lt;/span&gt; from the Table as parameter to the step definition. This can then be sent right on to the Simple.Data database object, like this:&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; [Given(&lt;/span&gt;&lt;span style="background-color: white; color: #006080; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;@"the following accounts exist"&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; x(IList&amp;lt;dynamic&amp;gt; accounts)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     DB.Accounts.Insert(accounts);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Bom! Table loaded – one line.&lt;br /&gt;In the When-step I have faked up a controller. Here I am using SpecFlow.Assist.Dynamic to get a single instance, again with the use of the step argument transformations; this time it will turn the Table into a &lt;span style="font-family: 'Courier New';"&gt;dynamic:&lt;/span&gt;&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; [When(&lt;/span&gt;&lt;span style="background-color: white; color: #006080; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;@"I submit the following Create Account form"&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; y(dynamic account)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     var fakeController = &lt;span style="color: blue;"&gt;new&lt;/span&gt; FakeAccountController(DB);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     fakeController.Create(account);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;The actual FakeAccountController looks like this:&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: blue; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;public&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: blue; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;class&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt; FakeAccountController&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; dynamic _database;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; FakeAccountController(dynamic database)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;         _database = database;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Create(dynamic account)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;         _database.Accounts.Insert(account);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Finally the Then-step compares the Table from the scenario to the content of the database. For now I just compare the number of rows, which is super lazy… but it’s ten o’clock and I’m tired…&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; [Then(&lt;/span&gt;&lt;span style="background-color: white; color: #006080; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;@"the following accounts should exist"&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; z(IList&amp;lt;dynamic&amp;gt; expectedAccounts)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     IList&amp;lt;dynamic&amp;gt; accountsInDb = DB.Accounts.All().ToList();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Assert that they are the same&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     expectedAccounts.Count.Should().Equal(accountsInDb.Count);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: green;"&gt;// ...&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;So by marrying the great Simple.Data framework with my small efforts in SpecFlow.Assist.Dynamic we can now move clear-text scenario data from and to the database very easily and with just a few lines of code.&lt;br /&gt;&lt;br /&gt;I hope you found this helpful and the SpecFlow.Assist.Dynamic could be useful for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-508246732156716014?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/508246732156716014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=508246732156716014' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/508246732156716014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/508246732156716014'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/specflowassistdynamicmaxing-out-with.html' title='SpecFlow.Assist.Dynamic–maxing out with Simple.Data'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-651375687003503</id><published>2011-11-01T08:00:00.000+01:00</published><updated>2011-11-03T16:39:48.397+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecificationByExample'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecFlow'/><title type='text'>SpecFlow.Assist.Dynamic–how to use it</title><content type='html'>This is the second post about &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt;.Assist.Dynamic – a little tool I wrote to help you write less code in your step definitions, and focus on the actual step instead of infrastructure. You can read the &lt;a href="http://www.marcusoft.net/2011/10/specflowassistdynamicwhat-is-it.html"&gt;first post here&lt;/a&gt; – it explains little about what &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; is.&lt;br /&gt;In this post I’ll show you how some ways I use the dynamic features to and some tricks that you might not know about.&lt;br /&gt;Again – this is not the documentation for SpecFlow.Assist.Dynamic – &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/wiki" target="_blank"&gt;that can be found here&lt;/a&gt;.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;Installation&lt;/h3&gt;With the power of &lt;a href="http://www.nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; it’s super-easy to install SpecFlow.Assist.Dynamic by simply go:&lt;br /&gt;&lt;blockquote&gt;Install-Package SpecFlow.Assist.Dynamic&lt;/blockquote&gt;(Sidenote: Ha! It’s good to try out your own stuff. Found a bug in the 0.2 version on NuGet. Fixed it with the 0.2.1 version )&lt;br /&gt;That will also pull down the latest version of &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; and other dependencies needed.&lt;br /&gt;&lt;h3&gt;Test data management&lt;/h3&gt;I found out that the most maintainable way to write scenarios is to have them initialize their own test data. Or at least on the feature level. I’ve tried to do it by restoring back ups but that has two drawbacks. &lt;br /&gt;First – it takes too long. And test that takes too long are not run. &lt;br /&gt;Secondly – the features (specifications?) are not easy to follow. You have to know what test data is being read back. It’s hidden for most users. &lt;br /&gt;So why do we still try this approach? Laziness I guess… It’s just to much code to write.&lt;br /&gt;&lt;h3&gt;Adding test data – single instances&lt;/h3&gt;There are two main features where &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; helps you; adding test data in the Given-steps and comparing the outcome to the test data in you Then-steps. &lt;br /&gt;For example for this Given step:&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; Scenario: Searching for books&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     Given the following books in the system&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;         | Title         | Author            | ISBN       |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;         | The Goal      | Eliah Goldratt    | 123345678  |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;         | Stick         | Ted and Dan Heath | 9955663322 |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;         | The Good book | God et&lt;span style="color: red;"&gt;.&lt;/span&gt; al        | 1          |&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I can write the following short statements with &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Binding]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; DemoSteps&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     [Given(&lt;span style="color: #006080;"&gt;@"the following books in the system"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; GivenTheFollowingBooksInTheSystem(Table table)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;         IList&amp;lt;dynamic&amp;gt; books = table.CreateDynamicSet().ToList();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;         &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (var book &lt;span style="color: blue;"&gt;in&lt;/span&gt; books) { DBHelper.AddBook(book); }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; DBHelper&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddBook(dynamic book)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;         var insertStatement = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format(&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;             &lt;span style="color: #006080;"&gt;"INSERT INTO BOOKS (Title, Author, ISBN) VALUES ('{0}', '{1}', '{2}')"&lt;/span&gt;,&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;             book.Title, book.Author, book.ISBNNumber);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Call into the db...&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;There’s a lot to be said about the data access code, for example you probably are using an ORM of sorts and hopefully you can send dynamic objects to it. I’ll show other ways to do that later. &lt;br /&gt;&lt;br /&gt;Let’s focus on the &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; instead. It’s not much to it – I simply create a list of dynamic objects and use my DBHelper to insert each one into the database.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Shorten it up with Step Argument Transformations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can use a trick that I’ve put into &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; to shorten the code even further. There is a &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; feature called &lt;a href="https://github.com/techtalk/SpecFlow/wiki/Step-Argument-Conversions" target="_blank"&gt;Step Argument Transformation&lt;/a&gt; that I use to shorten up code like the one above. With step argument transformation you can create small conversion methods that is triggered when certain types is used. &lt;br /&gt;&lt;br /&gt;I have supplied three such argument transformations that converts Table arguments into:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A dynamic instance&lt;/li&gt;&lt;li&gt;A IEnumerable&amp;lt;dynamic&amp;gt;&lt;/li&gt;&lt;li&gt;A IList&amp;lt;dynamic&amp;gt;&lt;/li&gt;&lt;/ul&gt;So the example above can be written like this, using these step argument transformations:&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Given(&lt;span style="color: #006080;"&gt;@"the following books in the system"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; GivenTheFollowingBooksInTheSystem(IList&amp;lt;dynamic&amp;gt; books)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (var book &lt;span style="color: blue;"&gt;in&lt;/span&gt; books) { DBHelper.AddBook(book); }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Pretty slick, huh? This is how it works:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; matches my Given statement with the Step definition marked with the Given-attribute above.&lt;/li&gt;&lt;li&gt;From the .feature-file it knows that a table is sent to the step. It send that table.&lt;/li&gt;&lt;li&gt;In the &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;dll step argument methods are found that matches a Table and the IList&amp;lt;dynamic&amp;gt; that I am using in the method signature&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; converts my argument using that method and simply returns a IList&amp;lt;dynamic&amp;gt; containing the data from the table.&lt;/li&gt;&lt;/ul&gt;You can read more &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/wiki/Step-argument-transformations" target="_blank"&gt;about this on my wiki.&lt;/a&gt;&lt;br /&gt;Oh yeah – &lt;strong&gt;very important&lt;/strong&gt;! To get this to work you need to add a configuration into your app.config:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;specFlow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;   &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;stepAssemblies&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;stepAssembly&lt;/span&gt; &lt;span style="color: red;"&gt;assembly&lt;/span&gt;&lt;span style="color: blue;"&gt;="SpecFlow.Assist.Dynamic"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;   &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;stepAssemblies&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon;"&gt;specFlow&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;This make sure that the step arguments are picked up from the dll. &lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Asserting results in the Then-steps&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The other place where &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; shines is when you are asserting that certain result of an action has happened. &lt;br /&gt;If we expand my example from before in to a fully fledged feature, we get this:&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; Scenario: Searching for books&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     Given the following books in the system&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;         | Title         | Author            | ISBN Number |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;         | The Goal      | Eliah Goldratt    | 123345678   |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;         | Stick         | Ted and Dan Heath | 9955663322  |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;         | The Good book | God et&lt;span style="color: red;"&gt;.&lt;/span&gt; al        | 1           |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     When I search for Titles containing 'Goal'&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     Then the results should show the following books&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         | Title         | Author            | ISBN Number |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         | The Goal      | Eliah Goldratt    | 123345678   |&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;I can now write the following steps:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Binding]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; DemoSteps&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; IList&amp;lt;dynamic&amp;gt; _books;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; IEnumerable&amp;lt;dynamic&amp;gt; _filteredBooks;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     [Given(&lt;span style="color: #006080;"&gt;@"the following books in the system"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; GivenTheFollowingBooksInTheSystem(IList&amp;lt;dynamic&amp;gt; books)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (var book &lt;span style="color: blue;"&gt;in&lt;/span&gt; books) { DBHelper.AddBook(book); }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;         _books = books;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     [When(&lt;span style="color: #006080;"&gt;@"I search for Titles containing '(.*)'"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; PerformTitleSearch( &lt;span style="color: blue;"&gt;string&lt;/span&gt; &lt;span style="color: blue;"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;         _filteredBooks = from b &lt;span style="color: blue;"&gt;in&lt;/span&gt; _books&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;                          &lt;span style="color: blue;"&gt;where&lt;/span&gt; b.Title.Contains(&lt;span style="color: blue;"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;                          select b;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;     [Then(&lt;span style="color: #006080;"&gt;@"the results should show the following books"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ResultsContainsBooks(Table table)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt;         table.CompareToDynamicSet(_filteredBooks.ToList());&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Don’t worry about the Given and When-steps, it’s just fake. I have save the original list into a private variable called _books and then simply filter that out in the When-step. In a real example the When-step would probably hit a webpage or a controller that in turn reads the database. And the Given-step would put the right data into the database before that. &lt;br /&gt;&lt;br /&gt;But the interesting (and short!) stuff is the one liner in the Then-step. Here I can again use the power of &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; and simply compare the sent-in table to the result of my When-action. &lt;br /&gt;&lt;br /&gt;And before you start to think about it. This way of writing it is easier than to use the step argument transformations and compare two IList&amp;lt;dynamic&amp;gt; to each other. That will be a lot more code.&lt;br /&gt;&lt;h3&gt;What about single instances?&lt;/h3&gt;I have now only showed you the use for Sets. There’s similar methods for creating instances. Typically they are used to fill out forms or find a certain record in the database.&lt;br /&gt;I leave the usage of those methods as a creative exercise for the reader. Let me know if you did anything that helped you.&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;h3&gt;&lt;span class="Apple-style-span" style="font-size: small; font-weight: normal;"&gt;I have shown you how I use these helpers. Please note that they are inspired to a great deal by the Table helpers in the &lt;/span&gt;&lt;a href="http://www.blogger.com/www.specflow.org" style="font-size: medium; font-weight: normal;" target="_blank"&gt;SpecFlow&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: small; font-weight: normal;"&gt;.Assist namespace that have similar methods but for statically typed objects (that you need to create ^^)&lt;/span&gt;&lt;/h3&gt;I hope you find this helpful. Please let me know if I can improve. &lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://www.marcusoft.net/2011/11/specflowassistdynamicmaxing-out-with.html"&gt;next post&lt;/a&gt; I’ll show a final thing that marries this with &lt;a href="https://github.com/markrendle/Simple.Data" target="_blank"&gt;Simple.Data&lt;/a&gt;. See you then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-651375687003503?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/651375687003503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=651375687003503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/651375687003503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/651375687003503'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/11/specflowassistdynamichow-to-use-it.html' title='SpecFlow.Assist.Dynamic–how to use it'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-4240793233483386742</id><published>2011-10-31T08:00:00.000+01:00</published><updated>2011-11-03T16:37:44.638+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecFlow'/><title type='text'>SpecFlow.Assist.Dynamic–what is it?</title><content type='html'>I have created my first ever &lt;a href="http://nuget.org/List/Packages/SpecFlow.Assist.Dynamic" target="_blank"&gt;NuGet package&lt;/a&gt;! I am so proud. Actually it’s just a small extension to &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; and the excellent &lt;a href="https://github.com/techtalk/SpecFlow/wiki/SpecFlow-Assist-Helpers" target="_blank"&gt;Assist helpers&lt;/a&gt; by &lt;a href="http://www.cauthon.com/" target="_blank"&gt;Darren Cauthon&lt;/a&gt;. But I learned quite a lot about dynamics in the process and I thought I write a post or two on &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt;; what it is, the problem it solves and how it’s made. Later post will be around how to use it and to put it together with &lt;a href="https://github.com/markrendle/Simple.Data" target="_blank"&gt;Simple.Data&lt;/a&gt; to create a real sweet testing experience. &lt;br /&gt;Let me say – before I start – that there is &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/wiki" target="_blank"&gt;documentation for usage on the GitHub wiki&lt;/a&gt;. This is a blog posts on how I made &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;SpecFlow.Assist.Dynamic&lt;/a&gt; – not the official documentation.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;The problem&lt;/h3&gt;It’s not a very big problem I’ve solved – but I grew tired of writing small classes that just was for transporting data. For example for the Gherkin-step:&lt;br /&gt;&lt;blockquote&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; Given the following users exists in the database:&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt;     | Name   | Age | Birth date | Length in meters |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     | Marcus | 39  | 1972-10-09 | 1&lt;span style="color: red;"&gt;.&lt;/span&gt;96             |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     | Albert | 3   | 2008-01-24 | 1&lt;span style="color: red;"&gt;.&lt;/span&gt;03             |&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     | Gustav | 1   | 2010-03-19 | 0&lt;span style="color: red;"&gt;.&lt;/span&gt;84             |&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     | Arvid  | 1   | 2010-03-19 | 0&lt;span style="color: red;"&gt;.&lt;/span&gt;85             |&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;I need to implement the following step-definitions (note that I’m using the &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt;.Assists table extension methods here to keep things short):&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Binding]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; DemoSteps&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     [Given(&lt;span style="color: #006080;"&gt;@"the following users in the database"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; x(Table table)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;         IEnumerable&amp;lt;User&amp;gt; listOfUsers = table.CreateSet&amp;lt;User&amp;gt;();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;         &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         &lt;span style="color: green;"&gt;// insert in database code goes here&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         &lt;span style="color: green;"&gt;//foreach (var user in listOfUsers)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;         &lt;span style="color: green;"&gt;//{&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;         &lt;span style="color: green;"&gt;//    user.Name, user.Age&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;         &lt;span style="color: green;"&gt;//}&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; User&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; DateTime BirthDate { get; set; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;double&lt;/span&gt; LengthInMeters { get; set; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;So the actual step definition is pretty concise and slick. And actually the only thing that bothers me is that class User. It’s only needed by the step definition and it’s only purpose is to transport some data.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;The solution&lt;/span&gt;&lt;br /&gt;As I started to use &lt;a href="https://github.com/markrendle/Simple.Data" target="_blank"&gt;Simple.Data&lt;/a&gt; I realized that &lt;a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx" target="_blank"&gt;dynamics&lt;/a&gt; could solve this problem for us. So that instead can write:&lt;br /&gt;&lt;span id="lnum1" style="background-color: white; color: #606060; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; text-align: left; white-space: pre;"&gt;   1:&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', courier, monospace; font-size: 11px; line-height: 16px; white-space: pre;"&gt; [Binding]&lt;/span&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; DemoSteps&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     [Given(&lt;span style="color: #006080;"&gt;@"the following users in the database"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; x(Table table)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;         IEnumerable&amp;lt;dynamic&amp;gt; listOfUsers = table.CreateDynamicSet();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;         &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         &lt;span style="color: green;"&gt;// insert in database code goes here&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         &lt;span style="color: green;"&gt;//foreach (var user in listOfUsers)&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;         &lt;span style="color: green;"&gt;//{&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;         &lt;span style="color: green;"&gt;//    user.Name, user.Age&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;         &lt;span style="color: green;"&gt;//}&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin-bottom: 0em; margin-left: 0em; margin-right: 0em; margin-top: 0em; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Just the code we need. No extra data carriers. Of course you’ll sacrifice intellisense, which is a big hurdle for a lot of us. But I got used to it – so can you. &lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;How to get it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The easiest way, by far, is to &lt;a href="http://nuget.org/List/Packages/SpecFlow.Assist.Dynamic" target="_blank"&gt;download it via NuGet.&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;Install-Package SpecFlow.Assist.Dynamic&lt;/span&gt;&lt;/blockquote&gt;If you want to help out…you are more than welcome. I’m not planning on doing any more work on this right now. But I hope that you see a bug or a improvement possibilities. &lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic" target="_blank"&gt;Let me know via GitHub&lt;/a&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;How it’s made&lt;/span&gt;&lt;br /&gt;The first thing I did was actually to write &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; scenarios for how I wanted the new functionality to work. Even though this was a good thing, as test first is, I would not recommend using &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; to test out unit level stuff. The major benefit with &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; and Cucumber, if you ask me, is that business users can read and understand the specifications.&lt;br /&gt;&lt;br /&gt;After that I simply created new &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank"&gt;extension methods&lt;/a&gt; on the &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; Table object:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; IEnumerable&amp;lt;dynamic&amp;gt; CreateDynamicSet(&lt;span style="color: blue;"&gt;this&lt;/span&gt; Table table)&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;One for each of the new features I wanted to support, four in all:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;CreateDynamicInstance&lt;/strong&gt; – creates an instance from a table. This can be done either for tables with one row or with two column tables. &lt;br /&gt;In the case of one row tables the header values are used as property names. &lt;br /&gt;In the case of the two column table the first column is presumed to contain the property values and the second the values for those properties (&lt;a href="https://github.com/marcushammarberg/SpecFlow.Assist.Dynamic/blob/master/Specs/DynamicInstancesFromTable.feature" target="_blank"&gt;for examples see this&lt;/a&gt;)&amp;nbsp; &lt;/li&gt;&lt;li&gt;&lt;strong&gt;CreateDynamicSet&lt;/strong&gt; – creates a IEnumerable&amp;lt;dynamic&amp;gt; for a several rows. The headers are the property names as before. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;CompareDynamicInstance&lt;/strong&gt; (to table) – this compares a instance of a object you send to the method to a table. The table is parsed using the CreateDynamicInstance–method as above. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;CompareDynamicSet&lt;/strong&gt; – and finally you can compare a set of object to a table. The table is parsed using the CreateDynamicSet method as above.&lt;/li&gt;&lt;/ul&gt;So, I have tried to use the same conventions as the one used in the &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt;.Assist helpers;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spaces can be used in table headers but are removed in property values (“Birth Date” becomes “BirthDate” for example) &lt;/li&gt;&lt;li&gt;I uppercase every new word even though it’s not like that in the table. So “Birth date” in the table header becomes “BirthDate” on the dynamic object&lt;/li&gt;&lt;/ul&gt;I also added a convention of my own that has to do with types on the dynamic object. I try to parse types from the values in the table in this order:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;First try to parse it as a DateTime &lt;/li&gt;&lt;li&gt;Then as a Integer &lt;/li&gt;&lt;li&gt;Then as a Double &lt;/li&gt;&lt;li&gt;And as a fall back I use a string&lt;/li&gt;&lt;/ul&gt;I wanted to do this to be able to do some more safe comparisons etc.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Challenges and solutions in the implementation&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Creating object properties from header strings&lt;/span&gt;&lt;br /&gt;One of the first tricks I learned about is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx" target="_blank"&gt;ExpandoObject&lt;/a&gt;. By reading up on this I learned a lot about how dynamics actually works.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;First&lt;/strong&gt; – the keyword “dynamic” only means “don’t do compile-time checking for this variable, it will work in runtime”. Nothing more.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Secondly&lt;/strong&gt; - the base class for a lot of the cool the stuff in System.Dynamics – &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx" target="_blank"&gt;DynamicObject&lt;/a&gt; – is simply a wrapper that gives you the possibility to trap exceptions for when you are accessing members not present on the current object. So if I have written:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; dynamic a = &lt;span style="color: blue;"&gt;new&lt;/span&gt; MyDynamicObject(); &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; a.Name = &lt;span style="color: #006080;"&gt;"Marcus"&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;I’m simply telling the compiler to let me write anything on the “a” object reference. So it swallows the ‘a.Name = “Marcus”’ statement without complaining.&lt;br /&gt;&lt;br /&gt;In order to handle that I can write this simple class, inheriting from DynamicObject:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; MyDynamicObject : DynamicObject &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; TryGetMember(GetMemberBinder binder, &lt;span style="color: blue;"&gt;out&lt;/span&gt; &lt;span style="color: blue;"&gt;object&lt;/span&gt; result)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;base&lt;/span&gt;.TryGetMember(binder, &lt;span style="color: blue;"&gt;out&lt;/span&gt; result);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     }  &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;In the TryGetMember override I can handle access to any member and do something more useful than to crash with a “Member not defined”.&lt;br /&gt;&lt;br /&gt;And that’s exactly what ExpandoObject does. It simply stores all the members, and their value, that you access into an internal IDictionary&amp;lt;string, object&amp;gt;. In fact you can even cast an ExpandoObject into a Dictionary&amp;lt;string, object&amp;gt; and insert your members that way. &lt;br /&gt;&lt;br /&gt;And that’s how I insert new dynamic properties and their values from each table row. Like this:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; ExpandoObject CreateDynamicInstance(TableRow tablerow)&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     dynamic expando = &lt;span style="color: blue;"&gt;new&lt;/span&gt; ExpandoObject();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     var dicExpando = expando &lt;span style="color: blue;"&gt;as&lt;/span&gt; IDictionary&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (var header &lt;span style="color: blue;"&gt;in&lt;/span&gt; tablerow.Keys)&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;         var propName = CreatePropertyName(header);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         var propValue = CreateTypedValue(tablerow[header]);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;         dicExpando.Add(propName, propValue);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;     &lt;span style="color: blue;"&gt;return&lt;/span&gt; expando;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Comparing dynamic objects&lt;/span&gt;&lt;br /&gt;One problem that almost stumped me was how to compare dynamic instances. There is no way to check which properties a dynamic instance has. … In the .NET framework. … That I know of.&lt;br /&gt;&lt;br /&gt;But I found the &lt;a href="http://code.google.com/p/impromptu-interface/" target="_blank"&gt;Impromptu Interface&lt;/a&gt; project (and &lt;a href="http://nuget.org/List/Packages/ImpromptuInterface" target="_blank"&gt;NuGet package&lt;/a&gt;). It does a lot of marvelous and strange things but I used it to GetMemberNames. That’s a static method that take an object and returns a list of it’s members. &lt;br /&gt;&lt;br /&gt;And there’s also a method that invoke methods on any object by name – InvokeSet(object, memberName). &lt;br /&gt;&lt;br /&gt;Combining these two made it a lot easier to write the comparisons methods for dynamic instances and sets.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Reflection&lt;/span&gt;&lt;br /&gt;But it was also around this place (having to take a dependency on ImpromtuInterface) that I realized that my solution might be the wrong one. I’m wondering if I might have been closer to a pure “dynamic by the book” solution if I had done a class inheriting from DynamicObject called DynamicSpecFlowTable. In that class I could easier and cleaner have handle how properties are set and comparisions done…&lt;br /&gt;&lt;br /&gt;Well it works fine now. I’ll keep it like this.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;The future&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Actually I would not like to have this NuGet package. I would rather see this included in the &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; main source. But as for now that means that &lt;a href="http://www.blogger.com/www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; needs to take a dependency on ImpromtuInterface and that’s probably not what they want.&lt;br /&gt;&lt;br /&gt;So this has been my training ground for a small adventure in dynamic-land. I’ve enjoyed it. &lt;a href="http://nuget.org/List/Packages/SpecFlow.Assist.Dynamic" target="_blank"&gt;I hope you do too.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-4240793233483386742?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/4240793233483386742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=4240793233483386742' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4240793233483386742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4240793233483386742'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/10/specflowassistdynamicwhat-is-it.html' title='SpecFlow.Assist.Dynamic–what is it?'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-2699078655489363036</id><published>2011-10-14T21:51:00.001+02:00</published><updated>2011-11-03T19:46:59.686+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Simple.Data–the testing story</title><content type='html'>I have fallen for &lt;a href="https://github.com/markrendle/Simple.Data" target="_blank"&gt;Simple.Data&lt;/a&gt;. Big time. It’s so terse and concise that you almost lose the need for data access abstractions altogether. It’s just … there for you. Just &lt;a href="https://github.com/markrendle/Simple.Data/blob/master/README.md" target="_blank"&gt;see for yourself here&lt;/a&gt;. And when have this power at your fingertips it’s easy to forget the testing story. &lt;br /&gt;How should I use Simple.Data so that I still can write unit and acceptance tests with code using it?&lt;br /&gt;In my unit-tests I do not want to call the database, of course, because that would slow my unit-level tests down. Also if I do automated acceptance I want to go end-to-end, testing the full stack of the application. But there the database access will slow me down, often in the form of a network hop as well.&lt;br /&gt;Have no fear! &lt;a href="http://twitter.com/#!/markrendle" target="_blank"&gt;Mr Rendle&lt;/a&gt; have set us up with a couple of ways to mock out the actual call to the database on the lowest level, but still go through Simple.Data. &lt;br /&gt;In this blog post I want to show you a couple of ways to write unit-tests that doesn’t hit the database, but still use Simple.Data.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;Using the XmlMockAdapter&lt;/h3&gt;When you install Simple.Data via &lt;a href="http://www.nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; you might be surprised to find a lot of packages there. There one for each adapter (supporting 7 different databases and counting), a core package, a sample and our friend &lt;a href="http://nuget.org/List/Packages/Simple.Data.Mocking" target="_blank"&gt;Simple.Data.Mocking&lt;/a&gt;. This package installs, according to the description; XML-based mocking for the Simple.Data data access library. &lt;br /&gt;I create a Class Library and NuGet’ed the following packages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Install-Package &lt;a href="http://www.nunit.org/" target="_blank"&gt;NUnit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Install-Package ShouldFluent (&lt;a href="http://www.marcusoft.net/2010/11/should-substitutetwo-new-great-friends.html" target="_blank"&gt;excellent assertion library&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Install-Package Simple.Data.Mocking&lt;/li&gt;&lt;/ul&gt;I can now write some tests. Lets try to simply call a mocked database, in a known state and return some rows for us:&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [TestFixture]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; CallingSimpleDataDirectlyTests&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; XmlMockAdapter _mockAdapter;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     [TestFixtureSetUp]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; MyTestInitialize()&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;         _mockAdapter = &lt;span style="color: blue;"&gt;new&lt;/span&gt; XmlMockAdapter(&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;                 &lt;span style="color: #006080;"&gt;@"&amp;lt;Root&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;                     &amp;lt;Users _keys="&lt;span style="color: #006080;"&gt;"Id"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Id="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"System.Int32"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Key="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"System.Guid"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"1"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"marcus@marcusoft.net"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Password="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"secretPassword"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"2"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"kalle@marcusoft.net"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Password="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"qwerty"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"3"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"john@marcusoft.net"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Password="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"1q2s3e4r"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;                     &amp;lt;/Users&amp;gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;                   &amp;lt;/Root&amp;gt;");&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;         MockHelper.UseMockAdapter(_mockAdapter);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;     [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; FindByEmail_ShouldFindRecord()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Arrange&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt;         var db = Database.Open();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum28" style="color: #606060;"&gt;  28:&lt;/span&gt;         var user = db.Users.FindByEmail(&lt;span style="color: #006080;"&gt;"marcus@marcusoft.net"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum29" style="color: #606060;"&gt;  29:&lt;/span&gt;         &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum30" style="color: #606060;"&gt;  30:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum31" style="color: #606060;"&gt;  31:&lt;/span&gt;         Assert.AreEqual(1, user.Id);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum32" style="color: #606060;"&gt;  32:&lt;/span&gt;         Assert.AreEqual(&lt;span style="color: #006080;"&gt;"marcus@marcusoft.net"&lt;/span&gt;, user.Email);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum33" style="color: #606060;"&gt;  33:&lt;/span&gt;         Assert.AreEqual(&lt;span style="color: #006080;"&gt;"secretPassword"&lt;/span&gt;, user.Password);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum34" style="color: #606060;"&gt;  34:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum35" style="color: #606060;"&gt;  35:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;So here (and yes, I’ve stolen the sample from the Simple.Data repository’s test project) we create a XmlMockAdapter in the Setup. On row 9 through 16 we load it up with some XML data. This can of course be read from a file if you want to, but then your pushing the envelope on what a &lt;strong&gt;unit&lt;/strong&gt;-test is, in my opinion. &lt;/div&gt;&lt;br /&gt;Line 18 is important – that tells Simple.Data to use our _mockAdapter. So that the next time we open a database the Xml mock adapter will be used. In a later version of the code, I’ve peeked, you can write something like this:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; Database.UseMockAdapter(_mockAdapter);&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;which in my opinion is much clearer. However it works in the same way. &lt;br /&gt;&lt;br /&gt;On line 25 our test code begins by opening the database for us, which will use the XmlMockAdapter, remember. The rest of the test is simple data access code using Simple.Data to pull back a record and validating against it. Note that we’re using “Users” that is the name of the Xml-element Users as our table name.&lt;br /&gt;&lt;br /&gt;Here are some other tests using the same setup method above, and performing insert, updates and deletes:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Delete_should_delete_a_user()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; numberDeleted = Database.Default.Users.Delete(Id: 2);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     numberDeleted.Should().Equal(1);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Update_should_update_the_email()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; email = &lt;span style="color: #006080;"&gt;"marcus@marcusoft.net"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; updated = Database.Default.Users.UpdateById(Id: 3, Email: email);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;     updated.Should().Equal(1);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;     &lt;span style="color: blue;"&gt;string&lt;/span&gt; updatedEmail = Database.Default.Users.FindById(3).Email;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;     updatedEmail.Should().Equal(email);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Insert_should_insert_new_entry()&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Arrange&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum28" style="color: #606060;"&gt;  28:&lt;/span&gt;     var db = Database.Default;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum29" style="color: #606060;"&gt;  29:&lt;/span&gt;     var numberOfUsersBefore = db.Users.All().Count;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum30" style="color: #606060;"&gt;  30:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum31" style="color: #606060;"&gt;  31:&lt;/span&gt;     dynamic newUser = &lt;span style="color: blue;"&gt;new&lt;/span&gt; ExpandoObject();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum32" style="color: #606060;"&gt;  32:&lt;/span&gt;     newUser.Id = 40;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum33" style="color: #606060;"&gt;  33:&lt;/span&gt;     newUser.Email = &lt;span style="color: #006080;"&gt;"newemail@marcusoft.net"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum34" style="color: #606060;"&gt;  34:&lt;/span&gt;     newUser.Password = &lt;span style="color: #006080;"&gt;"newpassword"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum35" style="color: #606060;"&gt;  35:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum36" style="color: #606060;"&gt;  36:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum37" style="color: #606060;"&gt;  37:&lt;/span&gt;     db.Users.Insert(newUser);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum38" style="color: #606060;"&gt;  38:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum39" style="color: #606060;"&gt;  39:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum40" style="color: #606060;"&gt;  40:&lt;/span&gt;     var numberOfUsersAfter = db.Users.All().Count;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum41" style="color: #606060;"&gt;  41:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I used the Database.Default property which simply gives us the default database in the .config, or in our case just the database with the mock-adapter. It’s just a shorthand for: &lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; var db = Database.Open();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; db.Users.WhatEver;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Using a repository&lt;/span&gt;&lt;br /&gt;In start of this post I said that the Simple.Data helps to write less code. Maybe so that we don’t need to use a separate repository. But maybe you want to use one anyway. To be able to mock out the repository when you’re testing a class using the repository for example.&lt;br /&gt;&lt;br /&gt;Simple.Data actually helps us to test the repository as well, using the XmlMockAdapter. Here is a short example.&lt;br /&gt;&lt;br /&gt;First my, very simple, repository:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; IUserRepository&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt;     IList&amp;lt;&lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt; GetUsersNamedBob();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; UserRepository : IUserRepository&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; dynamic _database;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; UserRepository()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;         _database = Database.Open();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; IList&amp;lt;&lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt; GetUsersNamedBob()&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; _database.Users.FindAllByName(&lt;span style="color: #006080;"&gt;"Bob"&lt;/span&gt;).ToList();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Worth noting here might be that I am not sending anything in to this repository as a dependency, typically you don’t do that to a repository. I am simply using the Database.Open()-method to create a private field, which I’m then using in my methods. &lt;br /&gt;&lt;br /&gt;In my test code I will then use the MockHelper.UseMockAdapter to ensure that the mock adapter will be used when I call the Database-object. Here is my test code:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [TestFixture]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; RepositoryTests&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     [TestFixtureSetUp]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SetUp()&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;         &lt;span style="color: green;"&gt;//Create a mock adapter with some suitable XML&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;         var mockAdapter = &lt;span style="color: blue;"&gt;new&lt;/span&gt; XmlMockAdapter(&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;                 &lt;span style="color: #006080;"&gt;@"&amp;lt;Root&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;                     &amp;lt;Users _keys="&lt;span style="color: #006080;"&gt;"Id"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Id="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"System.Int32"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Key="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"System.Guid"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"1"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"foo"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Name="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"Bob"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"2"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"bar"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Name="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"Bobelina"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"3"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"baz"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Name="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"Bob"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;                         &amp;lt;User Id="&lt;span style="color: #006080;"&gt;"4"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Email="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"baz"&lt;/span&gt;&lt;span style="color: #006080;"&gt;" Name="&lt;/span&gt;&lt;span style="color: #006080;"&gt;"Bobelina"&lt;/span&gt;&lt;span style="color: #006080;"&gt;"/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;                      &amp;lt;/Users&amp;gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;                    &amp;lt;/Root&amp;gt;");&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Set up the database to use our mock adapter&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;         MockHelper.UseMockAdapter(mockAdapter);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt;     [Test]&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum23" style="color: #606060;"&gt;  23:&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; using_mock_adapter_in_a_repository()&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum24" style="color: #606060;"&gt;  24:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum25" style="color: #606060;"&gt;  25:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Arrange&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum26" style="color: #606060;"&gt;  26:&lt;/span&gt;         var repo = &lt;span style="color: blue;"&gt;new&lt;/span&gt; UserRepository();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum27" style="color: #606060;"&gt;  27:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum28" style="color: #606060;"&gt;  28:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum29" style="color: #606060;"&gt;  29:&lt;/span&gt;         var result = repo.GetUsersNamedBob();&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum30" style="color: #606060;"&gt;  30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum31" style="color: #606060;"&gt;  31:&lt;/span&gt;         &lt;span style="color: green;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum32" style="color: #606060;"&gt;  32:&lt;/span&gt;         Assert.AreEqual(2, result.Count);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum33" style="color: #606060;"&gt;  33:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum34" style="color: #606060;"&gt;  34:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see this gives me the ability to test out the code in the repository. &lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;The future of mocking in Simple.Data&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the GitHub repository there is a branch (&lt;a href="https://github.com/markrendle/Simple.Data/tree/dict-query" target="_blank"&gt;dict-query&lt;/a&gt;) that contains something really interesting; an in-memory adapter for Simple.Data. &lt;br /&gt;&lt;br /&gt;The things I’ve show so far is nice but they require you to write (boring) Xml code. It might not be too bad but if we have an in-memory adapter you can simply insert the data you need using the standard Insert-methods of Simple.Data. &lt;br /&gt;&lt;br /&gt;A test would then look something like this (peeking the source again):&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum1" style="color: #606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum2" style="color: #606060;"&gt;   2:&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; InsertAndFindWithTwoColumnsShouldWork()&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum3" style="color: #606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum4" style="color: #606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Arrange&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum5" style="color: #606060;"&gt;   5:&lt;/span&gt;     MockHelper.UseMockAdapter(&lt;span style="color: blue;"&gt;new&lt;/span&gt; InMemoryAdapter());&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum6" style="color: #606060;"&gt;   6:&lt;/span&gt;     var db = Database.Open();&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum7" style="color: #606060;"&gt;   7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum8" style="color: #606060;"&gt;   8:&lt;/span&gt;     &lt;span style="color: green;"&gt;// insert some users&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum9" style="color: #606060;"&gt;   9:&lt;/span&gt;     db.Users.Insert(Id: 1, Name: &lt;span style="color: #006080;"&gt;"Albert"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum10" style="color: #606060;"&gt;  10:&lt;/span&gt;     db.Users.Insert(Id: 2, Name: &lt;span style="color: #006080;"&gt;"Marcus"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum11" style="color: #606060;"&gt;  11:&lt;/span&gt;     db.Users.Insert(Id: 3, Name: &lt;span style="color: #006080;"&gt;"Gustav"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum12" style="color: #606060;"&gt;  12:&lt;/span&gt;     db.Users.Insert(Id: 4, Name: &lt;span style="color: #006080;"&gt;"Arvid"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum13" style="color: #606060;"&gt;  13:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum14" style="color: #606060;"&gt;  14:&lt;/span&gt;     &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum15" style="color: #606060;"&gt;  15:&lt;/span&gt;     var numberOfRecords = db.Users.All().Count;&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum16" style="color: #606060;"&gt;  16:&lt;/span&gt;     Assert.AreEqual(4, numberOfRecords);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum17" style="color: #606060;"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum18" style="color: #606060;"&gt;  18:&lt;/span&gt;     var albert = db.Users.FindByIdAndName(1, &lt;span style="color: #006080;"&gt;"Albert"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum19" style="color: #606060;"&gt;  19:&lt;/span&gt;     Assert.IsNotNull(albert);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum20" style="color: #606060;"&gt;  20:&lt;/span&gt;     Assert.AreEqual(1, albert.Id);&lt;/pre&gt;&lt;pre style="background-color: white; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum21" style="color: #606060;"&gt;  21:&lt;/span&gt;     Assert.AreEqual(&lt;span style="color: #006080;"&gt;"Albert"&lt;/span&gt;, albert.Name);&lt;/pre&gt;&lt;pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"&gt;&lt;span id="lnum22" style="color: #606060;"&gt;  22:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;From the name of the branch (dict-query) you can deduce how that’s implemented. It’s a Dictionary holding the tables and it’s rows. I actually took a stab of implementing it myself but when I saw that Mark had it in place already I thought I help him writing some documentation instead . This blog post is a start.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;I am very impressed that Mark Rendle has supplied a mocking possibility with Simple.Data. It gives us a way to mock out the absolutely lowest level of database interaction, giving us the possibilities to test the full stack of the application without having to pay the network or database interaction toll.&lt;br /&gt;&lt;br /&gt;I hope you found this helpful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-2699078655489363036?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/2699078655489363036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=2699078655489363036' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2699078655489363036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2699078655489363036'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/10/simpledatathe-testing-story.html' title='Simple.Data–the testing story'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-4605714862823598113</id><published>2011-10-07T10:42:00.001+02:00</published><updated>2011-11-03T19:48:44.402+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Is Scrum a –ism that doesn’t work for real?</title><content type='html'>The other day I got my hands on the &lt;a href="http://www.scrum.org/scrumguides" target="_blank"&gt;Scrum Guide 2011&lt;/a&gt;. It’s a updated version of how Ken Schwaber and Jeff Sutherland looks at Scrum, it’s practices and state today. It’s well worth a read – especially if you haven’t read up on Scrum in a while. &lt;br /&gt;&lt;br /&gt;And let me here in the outset of this post also state that I have use Scrum a lot and it helped me and my teams a lot as well. &lt;strong&gt;I like Scrum &lt;/strong&gt;to be short – but (had to be one right) I think that some situations doesn’t fit perfectly with Scrum. &lt;br /&gt;&lt;br /&gt;After that short side note, let’s get back to the real thing. After I read the article I had an opportunity to sit down with &lt;a href="http://twitter.com/#!/morgsterious" target="_blank"&gt;Morgan Ahlström&lt;/a&gt;, a fellow lean / agile coach here at &lt;a href="http://www.avegagroup.se/" target="_blank"&gt;Avega Group&lt;/a&gt;. We started to discuss about the things we read in the document and finally arrived on the question; can Scrum, as described in the document, actually be done?&lt;br /&gt;&lt;br /&gt;The rest of this blog post are inspired by Morgan and written by me. Any strange stuff and faults are just my own and any great stuff is probably Morgan.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;It’s Scrum ™ or it’s not&lt;/h3&gt;The conclusion section of the Scrum Guide 2011 states (my highlighting):&lt;br /&gt;&lt;blockquote&gt;“Scrum is free and offered in this guide. Scrum’s roles, artifacts, events, and rules are &lt;strong&gt;immutable&lt;/strong&gt; and although implementing &lt;strong&gt;only parts of Scrum is possible, the result is not Scrum.&lt;/strong&gt; Scrum exists &lt;br /&gt;only in its entirety and functions well as a container for other techniques, methodologies, and practices.”&lt;/blockquote&gt;So if you call it Scrum ™ – it has to be done exactly as described in the Scrum Guide 2011, or at least with all the practices described therein, additions are welcome. If you are not – then it’s not Scrum. Simple and to the point. &lt;br /&gt;&lt;br /&gt;The guide starts with stating that Scrum is lightweight, easy to understand but extremely difficult to master.&lt;br /&gt;&lt;br /&gt;When Morgan and I discussed this we asked ourselves what was the best Scrum we’ve seen was like? Between us we have about 14-15 years of Scrum experience. Sadly the best Scrum at least &lt;strong&gt;I’ve&lt;/strong&gt; seen didn’t do all of the prescribed components of the Scrum framework, and the same was for Morgan.&lt;br /&gt;&lt;h3&gt;Common Scrum Pitfalls&lt;/h3&gt;We went back and forth and started to list the most common deviations from true Scrum ™ we’ve seen. Not that this only based of our experience and I would be happy to be corrected on this.&lt;br /&gt;&lt;br /&gt;This is our short list:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The product owner is an unicorn  &lt;/li&gt;&lt;li&gt;Deliver business value each iteration is hard  &lt;/li&gt;&lt;li&gt;Not doing retros and not following up on actions&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;“The product owner is an unicorn”&lt;/h4&gt;This heading is actually a quote from &lt;a href="http://twitter.com/#!/drunkcod"&gt;Torbjörn “DrunkCod” Gyllebring&lt;/a&gt; said at &lt;a href="http://twitter.com/#!/leankaffesump" target="_blank"&gt;LeanKaffeSump&lt;/a&gt; gathering in Stockholm. The reasoning behind it is one that I supports to 100% – a product owner (as described in the document) doesn’t exists. And for that matter – do we really want one?&lt;br /&gt;&lt;br /&gt;The product owner should be “The Product Owner is one person, not a committee” that in order to succeed “… the entire organization must respect his or her decisions”. Among the product owner responsibilities are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Clearly expressing Product Backlog items;  &lt;/li&gt;&lt;li&gt;Ordering the items in the Product Backlog to best achieve goals and missions;  &lt;/li&gt;&lt;li&gt;Ensuring the value of the work the Development Team performs;  &lt;/li&gt;&lt;li&gt;Ensuring that the Product Backlog is visible, transparent, and clear to all, and shows what the Scrum Team will work on next;  &lt;/li&gt;&lt;li&gt;Ensuring the Development Team understands items in the Product Backlog to the level needed&lt;/li&gt;&lt;/ul&gt;Man – that’s one steep order indeed. So she is to understand the business well enough to be the Development Team’s (new term in Scrum 2011, to my knowledge) single source of truth in questions about the product. And then to be able to prioritize the backlog according to business value on such a fine grained level that the items fit in a Sprint or less.&lt;br /&gt;&lt;br /&gt;I have never met a Product Owner ™ to that definition. I have meet proxies in front of a group of people that together constitute those skills – but then you loose the speedy communication needed in short sprints and an agile projects. &lt;br /&gt;&lt;br /&gt;I’ve also met PO that hold a lot of these properties but doesn’t care about the low level stuff that the team cares about. &lt;br /&gt;&lt;br /&gt;I have never been in a project where the PO was close to the team physically. One floor above is the closest I ever got, but then it was an IT-person that proxied some business users.&lt;br /&gt;&lt;br /&gt;I cannot help but making yet another connection here. I am very much into &lt;a href="http://www.specificationbyexample.com/" target="_blank"&gt;Specification by example&lt;/a&gt; and one of the early questions or remarks that &lt;a href="http://gojko.net/" target="_blank"&gt;Gojko Adzic&lt;/a&gt; makes is that many teams expect their customer/product owner to create the backlog for them. That is bad since you in essence ask the customer to design the system for you. It’s much better to harvest the whole teams collective knowledge and write, prioritize and create the backlog items together. The customer can then input and guard that the business values not get lost but leave the discussions of solutions to better suited people in the team.&lt;br /&gt;&lt;h4&gt;Not doing retros and not following up on actions&lt;/h4&gt;The second most common pitfall or inability to live up to true Scrum is to do retrospectives. This is probably the most important meeting but is so often down-prioritized and skipped. I don’t know why it’s skipped actually, but I think that teams fail to see the possibilities to change and improve their process. &lt;br /&gt;&lt;br /&gt;And even if the team are doing retrospectives the actions that comes out of them are seldom followed up or implemented. Common causes for this, that I’ve seen, are the brick wall of the organization in which the Scrum team are acting. &lt;br /&gt;This is not Scrum ™ fault per se, but Scrum doesn’t give much advice and help on how to be better in doing this either. &lt;br /&gt;&lt;h4&gt;Deliver business value each iteration is hard&lt;/h4&gt;Another thing that is very common is that the deliverables is not of business value each sprint.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You have to do upgrade a database  &lt;/li&gt;&lt;li&gt;a new version of the ORM-mapper has been released and need to be integrated in our code base  &lt;/li&gt;&lt;li&gt;in order to squeeze the user story into a single sprint we mock out the external dependencies (and do it “for real” in the next sprint)&lt;/li&gt;&lt;/ul&gt;These are all example of things that is not of business value but still needs to be done. And after a while the requirement of the stories being of business values easily fades a way, leaving the product owner behind. Maybe even the team start to decide that “a new database” will give us business value.&lt;br /&gt;&lt;br /&gt;This is not at all what Scrum intended but I’ve seen it happen in many of my teams. Again and again. Probably reflect my coaching skills – or is it just to hard ro do?  &lt;br /&gt;&lt;h3&gt;Scrum as a –ism&lt;/h3&gt;Putting all of these together and I must ask if Scrum has become an “-ism”?&lt;br /&gt;To clarify my thinking I will take you back to a project I was on about 5 years back. On that particular project we had a Swedish girl that was very left wing indeed and a guy from Cuba. The Swedish girl was convinced that communism could work and you can guess what the Cuban guy thought about that… having fled the country as just one example why he hated communism.&lt;br /&gt;&lt;br /&gt;That discussion had me thinking – the basic ideas with communism is not bad, right? It just cannot be implemented right. Or to put it another way; show me the best implementation of communism in the world – and I’ll show you a dysfunctional country, a ruthless leader or other horrible things. It’s an idea that’s good but it doesn’t work. In reality. On humans.&lt;br /&gt;&lt;br /&gt;Ok – quickly out of the politics (I hate politics) and back to Scrum. Is Scrum an –ism? A great idea that simply cannot be implemented (correctly, Scrum ™ style). In reality. On humans.&lt;br /&gt;&lt;br /&gt;And does that matter?&lt;br /&gt;&lt;h3&gt;Is ScrumBut bad?&lt;/h3&gt;Scrum-but is a term that is used to describe Scrum implementation that does some of Scrum BUT not all. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;“Yes, we do Scrum … but we don’t have PO”  &lt;/li&gt;&lt;li&gt;“Yes, we do Scrum … but we don’t do retrospectives”  &lt;/li&gt;&lt;li&gt;“Yes, we do Scrum … but we don’t deliver business value each sprint”&lt;/li&gt;&lt;/ul&gt;The term is, of course, frowned upon by the Scrum community. But is it really bad?&lt;br /&gt;&lt;br /&gt;Take 100 projects. Say that 80 of them failed. Some are probably not using Scrum, some are probably using Scrum-but (parts of Scrum). And some are probably using Scrum ™. Yes – good people, you can fail using Scrum.&lt;br /&gt;&lt;br /&gt;And the 20 that succeeds. I bet you that not all of them are using Scrum. I’ll bet that some of them are using Scrum-but. And some are probably using Scrum ™. So where does that leave us? It’s seems like it doesn’t matter if you use Scrum ™ or not. It seems like you can fail and succeed either way. &lt;br /&gt;&lt;br /&gt;Yes – but the important thing is what you do with that failure. I have from time to time called Scrum and other agile methods “problem finders”. They are used to find problems in your organization. But from there you have to intervene and DO SOMETHING ABOUT THE PROBLEM. You (the team) are the only one that can act and improve.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;That’s the important thing and the way I sum up agile; get fast feedback and act upon it. Scrum ™, Scrum-but, Non-Scrum or Kanban doesn’t matter – what you do with the feedback does.&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;So if you cannot do proper Scrum ™ as described in the Scrum Guide 2011 – why is it important? It isn’t! Not to us that is – it probably is if you have invented Scrum and are making a living of it. &lt;br /&gt;&lt;br /&gt;Scrum ™ can also be used as a nirvana state. A goal we’re striving for but never reach. And on the way Scrum-but can be used. &lt;br /&gt;&lt;br /&gt;That’s my two cents on the subject. Hope you got something out of this discussion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-4605714862823598113?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/4605714862823598113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=4605714862823598113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4605714862823598113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4605714862823598113'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/10/is-scrum-dead-is-scrum-aism.html' title='Is Scrum a –ism that doesn’t work for real?'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-1798314656243096071</id><published>2011-09-26T22:05:00.001+02:00</published><updated>2011-09-27T20:27:37.769+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Kanban-inzg the Avega Group Office–reflections</title><content type='html'>&lt;p&gt;This is the third post in a short series on how &lt;a href="http://twitter.com/#!/morgsterious" target="_blank"&gt;Morgan&lt;/a&gt; and me went about to introduce Kanban and some Lean thinking to two support teams of the &lt;a href="http://www.avegagroup.se" target="_blank"&gt;Avega Group&lt;/a&gt; office. You can read &lt;a href="http://www.marcusoft.net/2011/09/kanban-inizing-avega-group.html" target="_blank"&gt;post 1&lt;/a&gt; and &lt;a href="http://www.marcusoft.net/2011/09/kanban-inizing-avega-group_19.html" target="_blank"&gt;post 2&lt;/a&gt; before this to get the complete picture.&lt;/p&gt; &lt;p&gt;With this post I wanted to do some reflections on how the introduction of Kanban took hold for the teams and also what Morgan and me learned in the process. We are used to do this for IT-projects and teams working with system development or maintenance. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Reflection on the result for the teams&lt;/h4&gt; &lt;h5&gt;First week&lt;/h5&gt; &lt;p&gt;The immediate and positive responses from the group was reactions like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;“This is very clear and shows us what we are doing”  &lt;li&gt;“I can see dependencies between our tasks. And on the ones where we wait for others”  &lt;li&gt;“We have greater understanding for what we do. And other can see that (what we do) also”  &lt;li&gt;“I think our effectiveness went up 25 %”&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This is all related to visualization and the simple act of putting stuff on the wall (or the board) if you ask me. It’s also very common for teams starting with agile practices to get this kind of boost just by showing what they are doing. &lt;/p&gt; &lt;p&gt;There was also also a buzz around these new different rituals ( morning meeting, moving cards, creating avatars) that made the first week a true revelation for the teams.&lt;/p&gt; &lt;p&gt;One of the more interesting signs of that was that they spontaneously started to evolve the board:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Both teams used different colored stickies to further communicate information.  &lt;ul&gt; &lt;li&gt;One team used a color for each big project they were in. The question was what that helped them with. It was easy to see if one project was taking over the board but did it help them to prioritize? Not so much probably  &lt;li&gt;The other team used a more common &lt;a href="http://leanandkanban.wordpress.com/2009/06/10/classes-of-service-and-policies/" target="_blank"&gt;Classes of Service&lt;/a&gt; concept grouping their tasks in Urgent, Normal and Low priorities&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;One team considered adding a new "To Do”-column for stuff that goes on during the year. So they could prioritize the week from that backlog.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Also it was great to see them starting to collect statistics for what had been completed each day. One team left that on the board to “feel good about themselves” and then put it into a binder for later processing. We have suggested a simple &lt;a href="http://en.wikipedia.org/wiki/Control_chart" target="_blank"&gt;SPC diagram&lt;/a&gt; for starters to track progress and deviations.&lt;/p&gt; &lt;h5&gt;Second week &lt;/h5&gt; &lt;p&gt;The second week the focus has not been great. We tried to urge both teams to do a retrospective on how to improve their process and work but that was down-prioritized. To which Morgan said (love this): “If you gained 25% effectiveness – why not re-invest 5% of that time in improving your further work” &lt;/p&gt; &lt;p&gt;As it seems the week has been very busy and people have been in and out of the office. This has led to skipping of morning meetings and not updating the board, tasks not on the board. &lt;/p&gt; &lt;p&gt;Me and Morgan have to take some of this responsibility on us. We gave them very few instructions and tools and just told them to get going. And they did. But without guidance and continuous coaching to get them further the first inspiration seems to fade quickly. &lt;/p&gt; &lt;p&gt;I think this is also very common – a lot of teams “pick up agile” and just get starting but soon run into problems or don’t know how to go further. That’s the whole idea of a coach. Using the &lt;a href="http://en.wikipedia.org/wiki/Shuhari" target="_blank"&gt;Shu-Ha-Ri&lt;/a&gt; thinking they early on need constant guidance and firm advice to follow the rules strictly. So we left them on their own a bit to much maybe. We have promised to ask them if we may coach them on a more daily basis.&lt;/p&gt; &lt;h4&gt;Coaches reflection&lt;/h4&gt; &lt;p&gt;So that’s how our teams have coped. But what (if anything) did Morgan and I get out of this?&lt;/p&gt; &lt;p&gt;First and foremost we had to up our game. We are used to talk to teams in the IT-business. Many of the have heard of agile or even Scrum and Kanban. We know the common problems and pitfalls – so we are ahead before we start. &lt;/p&gt; &lt;p&gt;But here … we had to go in with a humbleness and use a different language. And, very important, we had to understand what the &lt;strong&gt;problem really was.&lt;/strong&gt; This is a very common mistake that I fall into from time to time – just coming with solution to problems that don’t exist. &lt;/p&gt; &lt;p&gt;So we couldn’t use buzzwords that everyone would smile and nod to. We couldn’t use explanations like Littles Law and “WIP is bad" but rather had to argument using other words. Really hard, but also very good for our own understanding. &lt;/p&gt; &lt;p&gt;We cannot emphasize the use of simple exercises enough (see &lt;a href="http://www.marcusoft.net/2011/09/kanban-inizing-avega-group.html" target="_blank"&gt;the first post&lt;/a&gt;). That made a lot of difference and gave us a common platform to refer back to. We also introduced the exercises in terms of their business (Imagine 3 projects, one is this important one, the other one …). &lt;/p&gt; &lt;p&gt;We tried that particular exercise on an other colleague that just stop in her tracks and said: “Point taken!” She just GOT IT. Those are the exercises you want to use. &lt;/p&gt; &lt;h4&gt;With great powers comes great responsibilities&lt;/h4&gt; &lt;p&gt;Something that Morgan and I have discussed is that we left our teams hanging a bit. We gave them tools and told them that “this is a simple process that you can apply to whatever way your are working today”. But without proper coaching and a helpful hand it quickly degenerates. &lt;/p&gt; &lt;p&gt;I think that this is what has happened to Scrum in many cases. People gets ga-ga over the power of Scrum and starts to implement it with the knowledge at hand. That leads to that the core values of Scrum and agile easy get misused or misunderstood. And then you end up in implementations like:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Yes – we are doing Scrum here. Well we have no board, or Scrum master or product owner. But we have daily meetings and don’t much documentation.&lt;/p&gt; &lt;p&gt;Kanban – of course. We have been running it a year! Well we don’t have any WIP-limits and not all tasks are on the board…&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Implementing a process change will be hard. Problems are bound to occur and those will help you to improve your process. But inexperienced teams will need guidance (firm at the outset) through that process. &lt;/p&gt; &lt;p&gt;To just inspire them and not follow through with proper coaching was not very nice or professional of us – we will do something about this. Soon.&lt;/p&gt; &lt;h4&gt;Conclusion&lt;/h4&gt; &lt;p&gt;This has been an interesting journey to follow so far. It’s just beginning of course but already we have seen progress and decay (our bad to some extent). I’ve learned a lot by trying to teach some simple practices in a domain I knew little about. &lt;/p&gt; &lt;p&gt;To do this together with Morgan has been great. It really good to have a speaking partner as you coach a team. Try it for yourselves. &lt;/p&gt; &lt;p&gt;And please – do try to implement Kanban in non-IT related business. You will learn a lot from it. But don’t leave them alone – they will need your help.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-1798314656243096071?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/1798314656243096071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=1798314656243096071' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/1798314656243096071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/1798314656243096071'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/kanban-inzg-avega-group.html' title='Kanban-inzg the Avega Group Office–reflections'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-3657259940402708159</id><published>2011-09-26T14:45:00.001+02:00</published><updated>2011-09-26T14:45:34.880+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SpecificationByExample'/><title type='text'>Executable specification - the whole stack or not</title><content type='html'>&lt;p&gt;This is really an age-old BDD question that pops up from time to time. Just now I got a question from an ex-colleague about it. A bit rephrased it something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Should I test through the GUI all the way down to the database? How do you handle test-data in and test executing speed in those cases?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Many of us first got exposed to BDD tests through web applications and the way that we could test through the actual web page. We use tools like &lt;a href="http://www.watin.org" target="_blank"&gt;Watin&lt;/a&gt;, Selenium and other automation tools to accomplish that. We structure our automation code with page wrappers to get manageable automation code that can be re-used in our step definitions. For some BDD even implies automation (which is not at all the case).&lt;/p&gt; &lt;p&gt;On the "other" side we try to go through the whole stack and go through all the of the application and hit the database as it's supposed to be used by the application. &lt;br&gt;And that's when it strikes us - this thing with test-data is really hard. And a bit slow also. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Through the GUI&lt;/h4&gt; &lt;p&gt;Up to this summer I was all for the whole-stack approach since if you don’t let your acceptance test run through the whole stack you might leave stuff out. Just imagine how much of a web application today that is made up by JavaScript for example, that would get tested if you didn’t test your views. Or for mocked data-access you wouldn’t really know if that integration actually worked until you tested it manually. &lt;/p&gt; &lt;p&gt;When I read the &lt;a href="http://www.Specificationbyexample.com" target="_blank"&gt;Specification by example&lt;/a&gt; book this summer I realized that many teams that are successful in implementing automated acceptance tests didn’t test the whole stack with all of their tests. On the key examples was implemented as full stack tests – while other test for edge cases or test completeness was executed against the “controller level” (as in Model-View-&lt;strong&gt;Controller&lt;/strong&gt;) and mocked data. &lt;/p&gt; &lt;p&gt;I liked that approach very much. In my last project we ran in to major problems with the test execution time. We had 300 acceptance tests that just took too long to execute and was also quite brittle due to some problems with out GUI automation tool of choice.&amp;nbsp; &lt;/p&gt; &lt;p&gt;So if you don’t have to – don’t go through the GUI.&lt;/p&gt; &lt;h4&gt;Mind your language&lt;/h4&gt; &lt;p&gt;Please note that even if you test through the GUI you should not write the test in terms of the GUI. Don’t write test scripts (“Click this”, “Fill out those”, “Choose that” etc.) but rather what focus on the behavior of the system ("Given I am logged in”, “When I add an item to the shopping cart”)&lt;/p&gt; &lt;h4&gt;How about the database&lt;/h4&gt; &lt;p&gt;I would argue in the same manner for the database – if you don’t have to, then don’t hit the real database. But let the key examples go through the whole stack and hit the database directly. &lt;/p&gt; &lt;p&gt;If you go against a real database you have a few options for managing test-data:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have setup/teardown method that creates (and deletes) the test data the tests need. This can in &lt;a href="http://www.cukes.info" target="_blank"&gt;Cucumber&lt;/a&gt;-like settings be accomplished with &lt;a href="http://www.marcusoft.net/2010/12/using-tags-in-specflow-features.html" target="_blank"&gt;hooks and tags&lt;/a&gt;. I would prefer this approach if there’s not too extensive test data to set up.&lt;/li&gt; &lt;li&gt;Create a test database with known test-data and restore it before the tests. Use this approach by selecting out some of your real data too be used in tests. You have test data in a known state.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In the cases where you don’t go against real data (using mocks and stubs) you’ll have more fine grained control over the data your testing on and can create the edge cases (“should not happen”-stuff) easier. Also for these test the execution time will be &lt;strong&gt;much&lt;/strong&gt; lower.&lt;/p&gt; &lt;h4&gt;Conclusion&lt;/h4&gt; &lt;p&gt;If you don’t have to run through the GUI and the complete application stack – don’t! Your test will run much faster and be less brittle. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-3657259940402708159?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/3657259940402708159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=3657259940402708159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3657259940402708159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/3657259940402708159'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/executable-specification-whole-stack-or.html' title='Executable specification - the whole stack or not'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-7479834583625300041</id><published>2011-09-19T09:00:00.000+02:00</published><updated>2011-09-19T09:02:31.079+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Kanban-inizing the Avega Group office–getting the show on the road</title><content type='html'>This is the second post in a small series on how we helped some parts of the &lt;a href="http://www.avegagroup.se/" target="_blank"&gt;Avega Group&lt;/a&gt; office to use Kanban to manage their workflow. &lt;br /&gt;In the &lt;a href="http://www.marcusoft.net/2011/09/kanban-inizing-avega-group.html"&gt;first post we introduced&lt;/a&gt; the teams that we coached to a foundations for why you want to limit your work-in-process, what benefits that could give them and some key elements of Kanban and Lean.&lt;br /&gt;As a final exercise we helped them to create a simple Kanban board for each team. We stressed the fact that the boards not is complete (at any time!) but should change and this is just a suggestion. &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Together with the teams we created a simple board, containing the following columns and policies:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Inbox&lt;/strong&gt; – their to do list for a horizon that feel comfortable. We didn’t limit the number of items here, but suggested that they may think about that. &lt;br /&gt;Also we told them that the size of the items here could vary. When the move it into the next column the work items is broken down into smaller tasks  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Today&lt;/strong&gt; – the items that is due today. We suggested that they should be between 0-8 hours in size and a work in process limit of max 6 per person.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Doing&lt;/strong&gt; – the current work going on. We told them to create &lt;a href="http://www.southparkstudios.se/avatar" target="_blank"&gt;2 avatars&lt;/a&gt; each and used that as WIP-limit for this column.  &lt;ul&gt;&lt;li&gt;This column has a sub column of &lt;strong&gt;Waiting&lt;/strong&gt; for stuff that is waiting for someone or something that hinder the progress&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Done&lt;/strong&gt; – stuff they finished. We suggested that they keep the stickies around until the end of each week , grouped by day. And then to hold a retrospective based on the outcome of the week. What worked? What felt great/bad? &lt;br /&gt;We offered our services for the first retrospectives.&lt;/li&gt;&lt;/ul&gt;And with that we let them loose… &lt;br /&gt;&lt;h4&gt;First steps and hits&lt;/h4&gt;The next morning we found this in one room: &lt;br /&gt;&lt;a href="http://lh3.ggpht.com/-Ymzt_9afvhI/TnI7ta7fCoI/AAAAAAAABDQ/BLHgTSFYbjk/s1600-h/IMG_13345.jpg"&gt;&lt;img alt="IMG_1334" border="0" height="302" src="http://lh3.ggpht.com/-IayJTGyTqNc/TnI7t1YNcKI/AAAAAAAABDU/GudGjMl6DTo/IMG_1334_thumb1.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="IMG_1334" width="403" /&gt;&lt;/a&gt;&lt;br /&gt;and saw this meeting taking place in another place at the office:&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/-wci4GQqDYrI/TnI7uoGbldI/AAAAAAAABDY/wW5NYxCUxps/s1600-h/IMG_13335.jpg"&gt;&lt;img alt="IMG_1333" border="0" height="302" src="http://lh4.ggpht.com/-nVKnTEmwDyI/TnI7vVhADgI/AAAAAAAABDc/6l9F2p1MST4/IMG_1333_thumb1.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="IMG_1333" width="403" /&gt;&lt;/a&gt;&lt;br /&gt;They were up and running. The first few days we got comment like these:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;“Hmmm – why is 4 stickies in waiting? Maybe I can take one of them”  &lt;/li&gt;&lt;li&gt;“Creating avatars was to much fun – we created 4 each “(Breaking the WIP-limit on doing with 100% (writers note))  &lt;/li&gt;&lt;li&gt;“So nice to don’t have to hold all these task in my head”  &lt;/li&gt;&lt;li&gt;“This made communication around the work easier and more concrete”  &lt;/li&gt;&lt;li&gt;“Others will see how much we do. And have done – Ha ha!”&lt;/li&gt;&lt;/ul&gt;And finally a small episode that Morgan oversaw/heard:&lt;br /&gt;As one of the teams was hold a morning meeting two “clients” to the team approached them. One of them saw that they were holding a morning meeting and went away, saying “I’ll be back later then”. The other one didn’t catch that and stood around. Stomping his feet. The team persevered and continued through their meeting. &lt;br /&gt;Well done - team!&lt;br /&gt;&lt;h4&gt;The road forward&lt;/h4&gt;As for now – we have asked the teams to grab any of the Lean/Agile coaches for any questions and at least invite one of us to their Friday retrospectives. That’s not much coaching but we trust them to learn by doing.&lt;br /&gt;Also other teams on the Avega Group office has shown interest in us helping them in a similar fashion… Lean for the win!&lt;br /&gt;I’ll try to post the rest of our story here. &lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;Although we might have helped these teams and their working environment, I think the greatest learning experience was for myself and Morgan. If you are doing Kanban at your software project – take a look around and find other areas that can use the same techniques. You’ll get a deeper understanding of the underlying principles I promise&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-7479834583625300041?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/7479834583625300041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=7479834583625300041' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/7479834583625300041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/7479834583625300041'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/kanban-inizing-avega-group_19.html' title='Kanban-inizing the Avega Group office–getting the show on the road'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-IayJTGyTqNc/TnI7t1YNcKI/AAAAAAAABDU/GudGjMl6DTo/s72-c/IMG_1334_thumb1.jpg?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-2993379680989849936</id><published>2011-09-16T09:00:00.000+02:00</published><updated>2011-09-16T09:00:11.577+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><category scheme='http://www.blogger.com/atom/ns#' term='Kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Kanban-inizing the Avega Group office–setting the stage</title><content type='html'>&lt;p&gt;I have recently returned from parental leave and got to experience office tempo first-hand. Was not prepared for that, but it also had me look around and I saw two teams at &lt;a href="http://www.avegagroup.se"&gt;Avega Group&lt;/a&gt; that was under a lot of stress (they said) and seemed to handle a lot of task simultaneously.  &lt;p&gt;Being dunked deeply in the Kanban-pool it made the hair on my neck stand up and I shivered to my bones. &lt;a href="http://en.wikipedia.org/wiki/Work_in_process"&gt;WIP is bad you know&lt;/a&gt;…  &lt;p&gt;Being a &lt;a href="http://www.avegagroup.se/sv/Elevate/Vara-Coacher/Coacher1/"&gt;Avega Coach&lt;/a&gt; I have some time to spend at the office, so I teamed up with &lt;a href="http://twitter.com/#!/morgsterious"&gt;Morgan&lt;/a&gt;, a fellow Lean/Agile coach here at Avega Group – and we decided to see if we could do anything about it.  &lt;p&gt;In doing so we had to sharpen our arguments and think a bit different. They are not creating systems you know. Both Morgan and I have experiences mostly with software development teams, of course. So we saw a great learning opportunity.  &lt;p&gt;This has just started but I thought I’ll try to blog about the experience here. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;The teams and some background&lt;/h4&gt; &lt;p&gt;The teams we approached were the Support team and the Marketing team. The support team is a small team (3 persons) that handles a lot of the short term activities that makes and office work. But they are also involved in some bigger projects such as an upcoming conference for the whole Avega Group (350 people), and getting activities there to work. Typical task is managing travel arrangements, answering phone and the door, booking events for &lt;a href="http://www.avegagroup.se/Elevate"&gt;Elevate&lt;/a&gt; and even refurnishing the office.  &lt;p&gt;The marketing group is also small team with 3 persons. Their work is made up of a lot of short marketing project combined with some long term stuff, such as the annual report. They have a higher degree of specialization within the group and the work is creative in character. Typical task range from creating presentations, layouting invitations and programs for Elevate events, creating a visual presence at conferences such as &lt;a href="http://www.oredev.org"&gt;OreDev&lt;/a&gt;. Through all their work the Avega Group brand is the most important thing.  &lt;p&gt;Both team deliver with great quality and is very (!) accessible for anyone who need them.  &lt;h4&gt;Humble approach&lt;/h4&gt; &lt;p&gt;First and foremost we needed to check with them if they also saw that they have problem. I had picked up some indices that they were under a lot of stress and I knew that they (both teams) handled LOADS of simultaneous work. Up to 30 small and large projects are some time in progress. I saw them listing it on the whiteboard, then items are delegate and then removed it from the whiteboard.  &lt;p&gt;Secondly – we don’t know much about the work they’re doing. So we need to communicate to them that we don’t want to change what they do – merely the order and when.  &lt;p&gt;So – we simply went up to the team leaders and asked them if they could spare us a minute or five. In character they both answered Yes! and more or less promptly left what they were doing and followed us.  &lt;p&gt;When we asked if we could help – they both were very happy. Arm-waving took place in one instance &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh4.ggpht.com/-S8rl3FrhKp8/TnI_yGgN4QI/AAAAAAAABDg/uiqiIij9K1k/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;.  &lt;p&gt;So we set a date for a workshop – “Monday would be great. All the MD’s are away then – which means that we get a quieter day”. Hmmm – maybe something to talk about?  &lt;h4&gt;The goal&lt;/h4&gt; &lt;p&gt;Our goal for them was not to increase throughput – they are already answering up to the demands from the organization both in throughput and quality. Amazingly and probably not indefinitely since the stress level will take it’s toll on quality at least.  &lt;p&gt;Instead we focus on a steady pace and a more acceptable stress level. And a way to handle the interruptions that will and probably should occur in their normal work. &lt;h4&gt;A practical exercise – learn to count&lt;/h4&gt; &lt;p&gt;We kicked off the workshop with a practical exercise that we hope would give them understanding in that the more projects I focus on at the same time the longer all of them takes.  &lt;p&gt;So we asked them to write down three columns (representing 3 projects they work on) with roman number I – X, A – J and 1 –10. To show how context switching has a bad result on performance we asked them to write each column with a different pen.  &lt;p&gt;The first time around we asked them to write line by line, changing pen and focus constantly. Here is my own result.  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-ZV9VMgbYzcM/TnI_y7DvI6I/AAAAAAAABDk/yypE6uJvCHs/s1600-h/IMG_1338%25255B2%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_1338" border="0" alt="IMG_1338" src="http://lh6.ggpht.com/-LwgPjIABIKE/TnI_zm9hMSI/AAAAAAAABDo/aHC4IP1H5fM/IMG_1338_thumb.jpg?imgmax=800" width="227" height="302"&gt;&lt;/a&gt; &lt;p&gt;The second time (you guess it) we asked them to write column by column finishing the first project before moving on to the next. Here is my result doing that:  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/--g9rkfcY0ww/TnI_0KgcAVI/AAAAAAAABDs/Ek1NVhijTJc/s1600-h/IMG_1337%25255B2%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_1337" border="0" alt="IMG_1337" src="http://lh5.ggpht.com/-NmiGboiOZns/TnI_0oMUHgI/AAAAAAAABDw/mK3GOdfgEI8/IMG_1337_thumb.jpg?imgmax=800" width="227" height="302"&gt;&lt;/a&gt; &lt;h6&gt;Findings&lt;/h6&gt; &lt;p&gt;This game was real eye-opener for the group (although one pair did the exercises in the reversed order &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh4.ggpht.com/-S8rl3FrhKp8/TnI_yGgN4QI/AAAAAAAABDg/uiqiIij9K1k/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;).  &lt;ul&gt; &lt;li&gt;The first time the complete exercise took (with my numbers) roughly 2.5 time longer time (1.12 versus 0.28)  &lt;li&gt;The first column – the most important project – was delivered after 001.10 minutes the first time around and in 8 seconds (!!) the second  &lt;li&gt;The quality suffered in many cases (writing the wrong letters, writing uglier and forgetting rows) in the first exercise – while the second time around almost no-one messed up (I did – if you look closely &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh4.ggpht.com/-S8rl3FrhKp8/TnI_yGgN4QI/AAAAAAAABDg/uiqiIij9K1k/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;)  &lt;li&gt;The general feeling was “calmer and more focused” for the second iteration.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Morgan and I was very happy with the outcome that we thought created an awareness of the problems with the “old way” of doing things.  &lt;h4&gt;Lean and Kanban basics&lt;/h4&gt; &lt;p&gt;From there it was quite easy to drive the main points of Kanban (&lt;a href="http://www.kanban101.com"&gt;Visual workflow, Limit Work-in-process and Help work to flow&lt;/a&gt;) and Morgan did a great presentation of it. But we were careful not to mention to much keywords and concepts focusing instead on the task at hand for them and how they could handle different situations.  &lt;h4&gt;End of part I&lt;/h4&gt; &lt;p&gt;This blog post is getting too long already. I have posted the second part for Monday 0900. So you’ll have to wait until then to get the rest of our work.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-2993379680989849936?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/2993379680989849936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=2993379680989849936' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2993379680989849936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2993379680989849936'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/kanban-inizing-avega-group.html' title='Kanban-inizing the Avega Group office–setting the stage'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-S8rl3FrhKp8/TnI_yGgN4QI/AAAAAAAABDg/uiqiIij9K1k/s72-c/wlEmoticon-smile%25255B2%25255D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-4387080625349899534</id><published>2011-09-13T19:30:00.001+02:00</published><updated>2011-09-13T22:16:34.263+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SpecificationByExample'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><title type='text'>Who writes the specification, now again?</title><content type='html'>&lt;p&gt;There’s been a lot of buzz around &lt;a href="http://specificationbyexample.com/" target="_blank"&gt;Specification by example&lt;/a&gt; lately. At least in my networks and close to me. I hear it almost everyday at the &lt;a href="http://www.avegagroup.se" target="_blank"&gt;office&lt;/a&gt;. A couple of days ago I was asked to do an introduction to the subject to a group of interested people. Striking also is that most people I hear talking about it is not developers (anymore) but rather business/requirements people and testers.&lt;/p&gt; &lt;p&gt;One question that I often get asked and that puzzles me is:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;But who writes the specifications? Business people, developers or testers?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Maybe not exactly like that but something close too that. Actually I think the underlying intent is something else and has to do with ownership…&lt;/p&gt; &lt;p&gt;I have also discussed the topic with a few of my &lt;a href="http://twitter.com" target="_blank"&gt;Twitter&lt;/a&gt; contacts that are involved in a project using Specification by example. In this post I’ll give my view on this – based on experience from a project last winter and from &lt;a href="http://manning.com/adzic/" target="_blank"&gt;the book&lt;/a&gt; by &lt;a href="http://gojko.net" target="_blank"&gt;Gojko Adzic&lt;/a&gt;.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Touches 4 of 7 key process patterns&lt;/h4&gt; &lt;p&gt;In the Specification by example book Gojko Adzic lists seven “key process patterns” – stuff that teams are doing that makes them successful. And that in essence is Specification by example. He doesn’t call it a method or methodology (it can be combined with anything you use to day), but rather refers to these 7 key process patterns. &lt;/p&gt; &lt;p&gt;The patterns are, very briefly (BUY THE BOOK):&lt;/p&gt; &lt;ol&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Deriving scope from goals&lt;/strong&gt; – where the scope for a feature or iteration is derived from the business goals&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Specifying collaboratively&lt;/strong&gt; – the specification and details surrounding a feature is discussed and talked about in a collaborative forum&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Illustrating using examples&lt;/strong&gt; – a practice where you clarifies your intent using concrete examples instead of natural language.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Refining the specification&lt;/strong&gt; – this steps ensures that the specification is concise, conforms to the language in other specifications and adhere to best practices that the teams has agreed upon&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Automating validation without changing specifications&lt;/strong&gt; – with this practice teams uses tools (such as &lt;a href="www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt;, &lt;a href="http://fitnesse.org/" target="_blank"&gt;FitNesse&lt;/a&gt; or &lt;a href="http://concordion.org/" target="_blank"&gt;Concordion&lt;/a&gt;) that can run the examples as executable tests against the system in question and validate that the system fulfills the specification&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Validating frequently&lt;/strong&gt; – the executable specifications are run often – such as part of a daily build – to shorten the feedback loop and get quick feedback on the current status of the system.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Evolving a documentation system&lt;/strong&gt; – where the executable specifications are organized, easy to find and concise so that they can use it when taking the product forward, change features and maintaining the product&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;I think that the question above (Who writes the spec) touches on 4 of the patterns – at least – namely:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Specifying collaborative&lt;/li&gt; &lt;li&gt;Illustrate using examples&lt;/li&gt; &lt;li&gt;Refine the specification&lt;/li&gt; &lt;li&gt;Automate without changing the specification&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Let’s look closer to what the question on who should write the specification means for these different process patterns.&lt;/p&gt; &lt;h4&gt;“Who writes the spec?” and Specifying collaborative&lt;/h4&gt; &lt;p&gt;That the specification is done collaborative is in my opinion a very important pattern. This means that you can do it with the whole team or in smaller groups but don’t let one person alone write the specification. &lt;/p&gt; &lt;p&gt;You could do this as a workshop with the whole team, writing a skeleton specification (with examples) on a white board. Or you can have small feature teams with just a few people representing the different discipline in the team, maybe even writing the specification directly into a tool for automation.&lt;/p&gt; &lt;p&gt;The thing with this practices is that you want to harvest the knowledge of the whole team; so that the business user can focus on how well the example fulfills the business needs, the developer can focus on how this can be implemented and suggest alternative solutions and the tester on how this can be tested and test coverage.&lt;/p&gt; &lt;p&gt;In doing this collaborative the team will (easier) get a collective ownership of the specification. Stuff that you have been a part in creating is much easier to take responsibility for. Compared to a specification that is handed over to you – written by someone else.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;So in this aspect the answer to the question is: &lt;strong&gt;The Team does!&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;h4&gt;“Who writes the spec?” and Illustrate using examples&lt;/h4&gt; &lt;p&gt;This is basically the same as above. If only one person is coming up with examples they tend to reflect that single person views and be limited by his creativity. Compare that to examples that has been created by a team with their collective knowledge and creativity. &lt;/p&gt;  &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Also here to the question is: &lt;strong&gt;The Team does!&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;h4&gt;“Who writes the spec?” and Refining the specification&lt;/h4&gt; &lt;p&gt;Ok – in this process pattern we refine the specification and examples we have created together to conform with the best practices and uses the same language in the rest of the specifications. &lt;/p&gt; &lt;p&gt;So, if you like, this is where you create the actual specification document. It’s of paramount importance that the intent and examples are kept intact even if the language is tweaked into the one used in the other specifications.&lt;/p&gt; &lt;p&gt;If this was code this step would have been called Refactoring. Refactoring has been described as &lt;a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank"&gt;"disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior"&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;Often this is the first step where a computer based tool is needed. So if you’re using &lt;a href="www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; (of course you do, right?) you’ll use Visual Studio 2010 to get the rich experience with formatting, syntax highlighting and auto complete for already implemented steps. &lt;/p&gt; &lt;p&gt;My experience is that this is way over the head of any normal business user. Just installing Visual Studio and explaining what it is was more than some of our users managed in my latest project. And those were people in the IT-department, supporting the users of the system we were building. &lt;/p&gt; &lt;p&gt;So I would suggest that a technical person performs this step. But of course validating and checking with the other people in the team that any changes didn’t change the intent of the specification.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;So here the answer would be: Someone who has enough technical knowledge for the tool does. &lt;strong&gt;But the Team has last say!&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;h4&gt;“Who writes the spec?” and Automate without changing the specification&lt;/h4&gt; &lt;p&gt;In this step it’s up to a developer or a technical tester to connect the examples in the specification to the actual system in question. This is done by “automating” the application, that is writing code that runs the application. This can be tricky and messy if not done right – but it’s also way off the topic of this scope. &lt;a href="http://www.marcusoft.net/2011/04/clean-up-your-stepsuse-page-objects-in.html" target="_blank"&gt;To avoid the mess – read this&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So make no mistake – this is coding! A developer automate the steps in the specification and starts to build the actual system to fulfill them – &lt;a href="http://en.wikipedia.org/wiki/Outside%E2%80%93in_software_development" target="_blank"&gt;one by one&lt;/a&gt;. The progress through the specification can be viewed as the steps are implemented and passes validation.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;For this pattern the answer is: A developer or a technical tester does.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;h4&gt;Conclusion&lt;/h4&gt; &lt;p&gt;So there are a few answers to a question that I almost always get asked as I present Specification by example. I think it might be because that this is where there is a big difference from how we traditionally writes specifications or tests. They are done by a specialist and then handed over to another specialist to be fulfilled. &lt;/p&gt; &lt;p&gt;&lt;em&gt;But that it also where the biggest improvements and benefits can be achieved.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;When you have done this many times I suspect that all the 4 patterns above (or at least the 3 first I have listed) can be done all at once. Sitting around a computer and simply entering the specification and it’s example directly into the tool of choice.&lt;/p&gt; &lt;p&gt;I hope you found this helpful.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-4387080625349899534?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/4387080625349899534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=4387080625349899534' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4387080625349899534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/4387080625349899534'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/who-writes-specification-now-again.html' title='Who writes the specification, now again?'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-2503147979131111501</id><published>2011-09-13T18:49:00.001+02:00</published><updated>2011-09-13T20:54:10.365+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Life of a consultant'/><title type='text'>Twitter for beginners</title><content type='html'> &lt;p&gt;I got a question from 3 colleagues on what &lt;a href="http://twitter.com" target="_blank"&gt;Twitter&lt;/a&gt; is and how we should use it. I don’t claim to be an expert but I use it quite a lot everyday. So here is my introduction to Twitter – with my own opinions on how to use it. There are &lt;a href="http://edweb.sdsu.edu/courses/edtec570/spring09/activities/opd/twitter.htm" target="_blank"&gt;other introductions&lt;/a&gt;, like this by &lt;a href="http://www.hanselman.com/blog/HowToTwitterFirstStepsAndATwitterGlossary.aspx" target="_blank"&gt;Scott Hanselmann&lt;/a&gt;, of course – but since they asked I might as well put it up here.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;What is it?&lt;/h4&gt; &lt;p&gt;From &lt;a href="http://en.wikipedia.org/wiki/Twitter" target="_blank"&gt;Wikipedia&lt;/a&gt; we learn that:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;b&gt;Twitter&lt;/b&gt; is an online &lt;a href="http://en.wikipedia.org/wiki/Social_network_service"&gt;social networking&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Microblogging"&gt;microblogging&lt;/a&gt; service that enables its users to send and read text-based posts of up to 140 &lt;a href="http://en.wikipedia.org/wiki/Character_(computing)"&gt;characters&lt;/a&gt;, informally known as "tweets."&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So you send short messages (tweets) that is picked up by anyone who follows you. You can follow a number of people to subscribe to their updates. Everything is public (almost see DM below) and can be viewed by anyone by going to &lt;a href="http://twitter.com/marcusoftnet" target="_blank"&gt;your Twitter-page&lt;/a&gt; – that’s basically it. &lt;/p&gt; &lt;p&gt;But as with many simple things there are much more than meets the eyes. &lt;/p&gt; &lt;h4&gt;What does X means?&lt;/h4&gt; &lt;p&gt;Since the text messages only allow for 140 characters there are a few conventions and tricks that are used to communicate intent and more information in that short space. Here are few of them:&lt;/p&gt; &lt;h5&gt;# – hashtag (or tags for short)&lt;/h5&gt; &lt;p&gt;By writing a tag (#avegaConference for example) in your tweet other people can pick up what you have to say in a subject. Also you can easy follow the discussion going on for that tag. An example might clarify the use a bit:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Say that you are at a big conference with hundreds of other people. Of course you don’t follow all of them. That’s very impractical. But the conference might use a certain tag (#oredev, #javaZone2011 etc) and by including that tag in your message this can be picked up by other that search for that tag in all tweets.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You can find the most popular tags by &lt;a href="http://trendistic.indextank.com/" target="_blank"&gt;searching for trending topics&lt;/a&gt; actually that’s a great way to keep up-to-date with important topics. The revolution in Egypt for example used #tahir (if I remember correctly) to collect all tweets about the event at Tahir Square.&lt;/p&gt; &lt;h5&gt;@[a Twitter user name]&lt;/h5&gt; &lt;p&gt;When you mention a Twitter user you write the @-sign followed by the twitter name (aka Twitter handle) for that user; &lt;a href="http://twitter.com/marcusoftnet" target="_blank"&gt;@marcusoftnet&lt;/a&gt; to mention me for example. Most Twitter client applications can inform you on all the times somebody has mentioned you. &lt;/p&gt; &lt;p&gt;As special case of mentioning is to write the user name first in your tweet. That means that you direct the message to that user. It’s visible to that person and all the persons following both you and the person you mention.&lt;/p&gt; &lt;p&gt;So for example if I tweet:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“Saw &lt;a href="http://twitter.com/hugohaggmark" target="_blank"&gt;@hugohaggmark&lt;/a&gt; eating at Vapiano today. Again!”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Everybody who follows me will see that tweet and know about Hugos lunch business. But if I instead write:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="mailto:&amp;ldquo;@hugohaggmark"&gt;“@hugohaggmark&lt;/a&gt; do you want to tag along to Vapiano today? Again.”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Hugo will see this, but also the people who follow both me and Hugo. &lt;/p&gt; &lt;p&gt;Using this technique you can direct a message to anyone with a twitter account (&lt;a href="http://twitter.com/#!/BarackObama" target="_blank"&gt;@barackObama&lt;/a&gt; for example). &lt;/p&gt; &lt;h5&gt;RT - retweet&lt;/h5&gt; &lt;p&gt;A retweet is simply repeating what somebody else has said. This is the reason that news and other information can travel very, very fast on Twitter . &lt;/p&gt; &lt;p&gt;You simple start your tweet with RT and then a copy of the tweet you are re-tweeting. Most client application has built-in functionality to do this for you.&lt;/p&gt; &lt;p&gt;For example, if &lt;a href="http://twitter.com/#!/hakanforss" target="_blank"&gt;@hakanforss&lt;/a&gt; tweets this noteworthy information:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“Don’t forget Lean Coffe tomorrow at Le Café”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Everybody that follows Håkan will see this. Including me, since I follow Håkan. So I can simply re-tweet that information to all the people who are following me, by tweeting:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="mailto:&amp;ldquo;RT@hakanforss"&gt;“RT @hakanforss&lt;/a&gt; - Don’t forget Lean Coffe tomorrow at Le Café”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;With this simple mechanism we have now shared this information with hundreds of users, who in turn can retweet it. It’s an information sharing avalanche that cannot be stopped. &lt;/p&gt; &lt;h5&gt;Smiles, abbreviations etc&lt;/h5&gt; &lt;p&gt;Smiles and other abbreviations are plentiful. I would stick to a few since not many are well known. Here are a few that I use:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;:) – I’m happy, that was fun&lt;/li&gt; &lt;li&gt;:( – I’m sad, sadly etc&lt;/li&gt; &lt;li&gt;;) – pun intended, irony&lt;/li&gt; &lt;li&gt;FTW – for the win and exclamation of triumph (#specflow #ftw)&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;Replies &lt;/h5&gt; &lt;p&gt;If you reply to a tweet be sure to the Reply-function. Doing so give Twitter a chance to keep a nice thread going for you so that you can see the conversation in chronological order. Here is one example from the Twitter website:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-pEB0p9BmEBw/Tm-mzblgjNI/AAAAAAAABCg/Vu0mJIbSd-Y/s1600-h/twitter%252520reply%252520chain%25255B6%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="twitter reply chain" border="0" alt="twitter reply chain" src="http://lh5.ggpht.com/-yeoIjXxHBis/Tm-mztJrm3I/AAAAAAAABCk/dSwbVyzD3UM/twitter%252520reply%252520chain_thumb%25255B4%25255D.png?imgmax=800" width="211" height="294"&gt;&lt;/a&gt;&lt;/p&gt; &lt;h4&gt;&amp;nbsp;&lt;/h4&gt; &lt;h5&gt;DM – direct message&lt;/h5&gt; &lt;p&gt;You can send private messages to someone you follow and who follows you. Start your tweet with “DM” and only you two will see the message. For example:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="mailto:&amp;ldquo;DM@attefall"&gt;“DM @attefall&lt;/a&gt; Isn’t this one boring meeting? And it stinks from the person next to me :(”&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;That will not be picked up by anyone else. I would still use this function with care. It’s all too easy to forget the DM…. And if other people in the meeting, in my example follows you… You get the picture.&lt;/p&gt; &lt;h4&gt;Integration with other social networks&lt;/h4&gt; &lt;p&gt;Most other social networks can import your tweets. Mine show up on &lt;a href="http://www.linkedin.com" target="_blank"&gt;on LinkedIn&lt;/a&gt; for example. &lt;/p&gt; &lt;p&gt;I have also hooked up a nice service called &lt;a href="http://www.facebook.com/selectivetwitter" target="_blank"&gt;SelectiveTweets&lt;/a&gt; that publish any tweets I do which include the tag “#fb” to &lt;a href="http://www.facebook.com/" target="_blank"&gt;Facebook&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;There are numerous applications that can use the tweets you send (if you grant permissions of course) to &lt;a href="klout.com/#/marcusoftnet" target="_blank"&gt;do all kind&lt;/a&gt; &lt;a href="http://twournal.com/" target="_blank"&gt;of fun stuff&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;More and more site allow you to sign in using your Twitter-account as well. &lt;/p&gt; &lt;h4&gt;How do I use it?&lt;/h4&gt; &lt;p&gt;Finally my own opinions on how to use Twitter. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;First and foremost – let it wash over you. Don’t try to read every single tweet. Twitter has been called “The River of Crap” :). So if you don’t read for a day or two – no sweat. Pick up where you are now.&lt;/li&gt; &lt;li&gt;Follow people that YOU think are interesting. You are putting your information feed together for you. Most twitter users don’t get upset if you don’t follow them back – as has been know to happen on Facebook.&lt;/li&gt; &lt;li&gt;Get started by checking out some interesting tag and start to add your opinion on them. Soon you’ll be hooked too.&lt;/li&gt; &lt;li&gt;I have few hashtags and saved searches that I use to keep myself informed on certain areas. Great for keeping up to date – you can’t get information faster.&lt;/li&gt; &lt;li&gt;TURN IT OFF – when doing work that requires your concentration.&lt;/li&gt; &lt;li&gt;Be polite – remember that most of the things you write are publically accessible. I don’t tweet stuff that I cannot say to someone’s face or in public.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Conclusion&lt;/h4&gt; &lt;p&gt;There you have my short introduction to Twitter and how to use it. Used right it can be a great source to news and information. &lt;/p&gt;  &lt;p&gt;I hope you found useful. At least you Ulrica and friends &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://lh5.ggpht.com/-n4iRTeoulWI/Tm-m0GwpVEI/AAAAAAAABCo/1RwOSUj44fM/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-2503147979131111501?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/2503147979131111501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=2503147979131111501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2503147979131111501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/2503147979131111501'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/twitter-for-beginners.html' title='Twitter for beginners'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-yeoIjXxHBis/Tm-mztJrm3I/AAAAAAAABCk/dSwbVyzD3UM/s72-c/twitter%252520reply%252520chain_thumb%25255B4%25255D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-8903492296720178197</id><published>2011-09-05T15:08:00.001+02:00</published><updated>2011-09-05T15:52:44.514+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>The dynamic keyword, ExpandoObject–a short intro for me</title><content type='html'>&lt;p&gt;Right away – this blog post is mostly for me. I have not been dabbling enough with the “dynamic” keyword to say that I know it. This is what and how I understand it now.&lt;/p&gt; &lt;p&gt;So, if you care to read this… please be gentle with your comments. I love to see them and learn that I was wrong – I’m most certainly am.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;dynamic keyword&lt;/h4&gt; &lt;p&gt;Since .NET 4.0 we have a new keyword – &lt;a href="http://msdn.microsoft.com/en-us/library/dd264741.aspx" target="_blank"&gt;dynamic&lt;/a&gt;. If you read the &lt;a href="http://msdn.microsoft.com/" target="_blank"&gt;MSDN&lt;/a&gt; documentation you’ll learn that:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run time.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Ok, but what useful is that? I mean you *could* write this, you probably shouldn’t but you could:&lt;/p&gt; &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;// Any object can be typed dynamic&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #008000"&gt;// The dynamic keyword just means that &lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt;// the operations will be evaluated at runtime&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; dynamic s = &lt;span style="color: #006080"&gt;"Marcus again"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; Assert.AreEqual(s.Length, 12);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;We now have a “dynamic” string. So the “s.Length” part compiles fine, but that’s actually just because the compile time checking is disabled. If I had written “s.StringLength” instead – that would also compile, but fail in runtime – since the string-class doesn’t implement a “StringLength” property.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Eeeh – so it’s a way to bypass the compiler and mess up? &lt;/p&gt;&lt;br /&gt;&lt;p&gt;I must admit that up to recently I hadn’t tried the dynamic keyword out and hence my thinking about it was here somewhere. &lt;/p&gt;&lt;br /&gt;&lt;h4&gt;ExpandoObject using dynamic to add stuff at runtime&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;The first many of us (me that is) hear about is the mystically named &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx" target="_blank"&gt;ExpandoObject&lt;/a&gt;. You can add property or method you like to the ExpandoObject – and it just works. So, yes it’s a bit mystical. Let’s see it in action:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; dynamic de = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ExpandoObject();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; de.Name = &lt;span style="color: #006080"&gt;"Marcus"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; de.Age = 39;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; de.GetBirthCertificate = &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Func&amp;lt;DateTime, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(now =&amp;gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;                      de.Name + &lt;span style="color: #006080"&gt;" was born "&lt;/span&gt; + (now.Year - de.Age));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;p&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; Assert.AreEqual(&lt;span style="color: #006080"&gt;"Marcus was born 1972"&lt;/span&gt;, &lt;br&gt;                                de.GetBirthCertificate(DateTime.Now));&lt;/p&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Yes – it’s super easy to add properties for Name and Age and then use them in a dynamic function that is defined by a lambda expression and use the dynamic variables. Even though those properties doesn’t exists on the ExpandoObject it compiles (since the variable is dynamic the compiler checking is disabled, remember) and works fine when we run it. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;But how on earth can that work?&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;DynamicObject&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Also included in the 4.0 release were a couple of classes that take full advantage of the dynamic keyword. They inherit from &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx" target="_blank"&gt;DynamicObject&lt;/a&gt; (some way or another) and it’s used as a base class for specifying dynamic behavior at runtime. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;On the DynamicObject is a couple of interesting methods that you can override, for example TryGetMember, TrySetMember and TryInvokeMember. These method are run when a dynamic property is accessed and you can gracefully handle the non-existing member. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;In the case of ExpandoObject it internally holds a IDictionary&amp;lt;string, object&amp;gt; that simply stores the name of the property as the key and the value as ... well … the value.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Actually it’s not too hard to implement. Here’s a rudimentary implementation for properties only:&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; [TestFixture]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MarcusExpandoTests&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     [Test]&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; void should_be_able_to_use_marcusexpando()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span style="color: #008000"&gt;// My own Expando... &lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span style="color: #008000"&gt;// Oh how close i was to name it MarcusSpandex&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;dynamic&lt;/span&gt; m = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MarcusExpando();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;         m.Name = "Marcus";&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;         m.Age = 39;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;         Assert.AreEqual("Marcus &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; 39 &lt;span style="color: #0000ff"&gt;old&lt;/span&gt;. My God!", &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;             string.Format("{0} &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; {1} &lt;span style="color: #0000ff"&gt;old&lt;/span&gt;. My God!", m.Name, m.Age));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;     }   &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MarcusExpando : DynamicObject&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;p&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;     private readonly IDictionary&amp;lt;string, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; _dic = &lt;br&gt;                      &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Dictionary&lt;/span&gt;&amp;lt;string, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;();&lt;/p&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; override bool TrySetMember(SetMemberBinder binder, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!_dic.ContainsKey(binder.Name))&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;             _dic.&lt;span style="color: #0000ff"&gt;Add&lt;/span&gt;(binder.Name, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;             _dic[binder.Name] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt;  31:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; override bool TryGetMember(GetMemberBinder binder, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;result&lt;/span&gt;)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt;  32:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt;  33:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;result&lt;/span&gt; = _dic[binder.Name];&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt;  34:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt;  35:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt;  36:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;If you check row 21 you’ll see how I override the methods TrySetMember. Then I can pickup the name of the dynamic property the developer used and store it, with the value, in a dictionary. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;On row 31 it’s easy to override TryGetMember and retrieve the value from the dictionary. &lt;/p&gt;&lt;br /&gt;&lt;h4&gt;So how can this be flexed&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Well, there’s a million ways to use this, but to water your appetite check out &lt;a href="https://github.com/markrendle/Simple.Data/wiki/Finding-data" target="_blank"&gt;Simple.Data&lt;/a&gt;. It’s a data access tool that uses dynamic to the full. Here’s an example:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; IEnumerable&amp;lt;User&amp;gt; u = Database&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;         .Users&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;         .FindByAllByName(&lt;span style="color: #006080"&gt;"Bob"&lt;/span&gt;)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;         .Cast&amp;lt;User&amp;gt;();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt; It looks like magic but now we can understand it. Ok – this is how I understand it without reading the source.&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Database is the base object in Simple.Data. It inherits from DynamicObject and hence can use TryGet/SetMember and other methods for doing dynamic operations&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When the user writes “.Users” Simple.Data stores that name to be used as the table name in the query we’re about to construct. So there is a table in the database called “Users”…&lt;/li&gt;&lt;br /&gt;&lt;li&gt;“.FindAllByName(“Bob”)” – this will again be picked up by TryGetMember and we can parse out the “FindAllBy” and “Name” part of the method name and the “Bob” argument. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finally we cast the result to a IEnumerable of the concrete User class. So that’s simply going to a concrete implementation, filling out the User class with the columns returned by the query. &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;All in all we now have the parts to construct this query:&lt;/p&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; * &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Users &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; Name = &lt;span style="color: #006080"&gt;'Bob'&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Neat – right?&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;The right use of the dynamic keyword can significantly shorten your code. It take some time to get used to and fully understand (I’m not there yet) and I think that care need to be taken on where you use it. But in the right places – and with the right introduction to the rest of the team – it’s very useful.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I hope that I wasn’t the only one that got anything from this. But if so … I’m now happy that I understand and can use the dynamic keyword. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36533086-8903492296720178197?l=www.marcusoft.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.marcusoft.net/feeds/8903492296720178197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36533086&amp;postID=8903492296720178197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/8903492296720178197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36533086/posts/default/8903492296720178197'/><link rel='alternate' type='text/html' href='http://www.marcusoft.net/2011/09/dynamic-keyword-expandoobjecta-short.html' title='The dynamic keyword, ExpandoObject–a short intro for me'/><author><name>Marcus Hammarberg</name><uri>http://www.blogger.com/profile/12641801738629569831</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/_TI0jeIedRFk/SaGe8YGEdII/AAAAAAAAABE/9Q4_un92yVI/S220/marcuseuff2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36533086.post-640926282847787172</id><published>2011-09-01T15:07:00.001+02:00</published><updated>2011-09-01T16:03:37.637+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Creating a local NuGet repository with dependencies bundles</title><content type='html'>&lt;p&gt;I’m loving &lt;a href="http://www.nuget.org" target="_blank"&gt;NuGet&lt;/a&gt; and it’s totally changed the way I look on brining in external dependencies to my projects. &lt;a href="http://www.marcusoft.net/2011/02/nuget-uninstall-remove-dependencies.html" target="_blank"&gt;I've written about that before&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;But sometimes you want to install several packages into a project. For example, when you install &lt;a href="www.specflow.org" target="_blank"&gt;SpecFlow&lt;/a&gt; into a project you also have to install a test framework such as &lt;a href="http://www.nunit.org/" target="_blank"&gt;NUnit&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/ms182489(v=vs.80).aspx" target="_blank"&gt;MsTest&lt;/a&gt;. And maybe an assertion framework or a mocking framework. &lt;/p&gt; &lt;p&gt;But this package will contain your (or your company) preferences and maybe not be suitable to publish to NuGet.org for everyone to download.&lt;/p&gt; &lt;p&gt;In this post I’ll show you how to easily create a&amp;nbsp; local package where you can setup the dependencies you want. And how to use it in your solution.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;h4&gt;Strategy&lt;/h4&gt; &lt;p&gt;Our sneaky plan is to basically create a package that only has dependencies. No code. And then store it in a local NuGet Repository.&lt;/p&gt; &lt;h4&gt;Install NuGet Package Explorer&lt;/h4&gt; &lt;p&gt;This will to large extent be done in the .nuspec file. A XML-file that you can edit with any text editor. Or use the excellent &lt;a href="http://nuget.codeplex.com/releases/view/59864" target="_blank"&gt;NuGet Package Explorer&lt;/a&gt;. Go get it now. You want be sorry.&lt;/p&gt; &lt;h4&gt;Create a local NuGet repository&lt;/h4&gt; &lt;p&gt;A local NuGet repository is simply a folder with NuGet packages. You can follow the first 4 steps in &lt;a href="http://gregorsuttie.wordpress.com/2011/01/03/using-a-nuget-local-repository/" target="_blank"&gt;this excellent blog post&lt;/a&gt; or just go:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a folder (mine is in C:\Dev\LocalNuGet)&lt;/li&gt; &lt;li&gt;In Visual Studio go Tools-&amp;gt;Library Package Manager-&amp;gt;Package Manager Settings and add your path above to the Package Sources:&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-jW0Q6Ymm4vk/Tl-Qmqj4qkI/AAAAAAAABBg/3tXjLnqUNrs/s1600-h/adding%252520new%252520nuget%252520package%252520source%25255B2%25255D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top: 0px; border-right: 0px; padding-top: 0px" title="adding new nuget package source" border="0" alt="adding new nuget package source" src="http://lh5.ggpht.com/-n34J70F2SuA/Tl-Qnb6o0pI/AAAAAAAABBk/iH5qSo5veR4/adding%252520new%252520nuget%252520package%252520source_thumb.jpg?imgmax=800" width="404" height="234"&gt;&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Double check that everything is fine, by going to the Package Manager console and try to select your package source in the d
