<?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:blogger='http://schemas.google.com/blogger/2008' 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-1636867873184018667</id><updated>2024-11-01T06:32:28.226-04:00</updated><title type='text'>Michael Meadows</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://michael-meadows.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://michael-meadows.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>WalkingDisaster</name><uri>http://www.blogger.com/profile/10578904054029129551</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/5644/3144/1600/JuliAndDad_small.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1636867873184018667.post-4275879032230322731</id><published>2010-08-15T10:34:00.001-04:00</published><updated>2010-08-15T10:34:00.184-04:00</updated><title type='text'>Git Saved my @$$: Episode I–The Phantom Branch</title><content type='html'>&lt;p&gt;I have been enjoying &lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt; for a while now.&amp;#160; Since switching to Git on my current project, we have been quietly succeeding.&amp;#160; However, whether through disinterest, or laziness, I avoided really understanding how it worked.&amp;#160; That is, until it saved my ass.&lt;/p&gt;  &lt;p&gt;So here’s the deal.&amp;#160; I was on a tear.&amp;#160; I just finished coding and testing a feature.&amp;#160; As I am now wont to do, I was working on a local feature branch (PO-updates).&amp;#160; It was time to merge back to our development branch.&amp;#160; Actually, it was time to &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#using-git-rebase&quot;&gt;rebase&lt;/a&gt;, but I merged out of ignorance.&amp;#160; There were merge conflicts in the project (*.proj) file, but I was on fire.&amp;#160; Not time to pay attention to the output.&amp;#160; I ran all my unit tests, and [blam] green bar!&amp;#160; Ok, merge complete (or so I thought).&amp;#160; Time to delete the feature branch.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGwj_mBOY8hx-nK2ZN40XWNQVhnu4Hwdgk2uSLMP75P7tGRAMIFugoOEk47Lpg0Hb-js2Z23oGKhP0wcETui7qtto4BseFwBgf4raAawK1fHasAtevWGsGDxuP2fSBldOWruHUVCsD6tu5/s1600-h/Oops%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;Oops&quot; border=&quot;0&quot; alt=&quot;Screenshot of me not noticing the warning &amp;quot;error: the branch &amp;#39;PO-updates&amp;#39; is not fully merged. If you are sure you want to delete it, run &amp;#39;git branch -D PO-updates&amp;quot;, and me (of course) running &amp;quot;git branch -D PO-updates&amp;quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghY2r_OUZsnQDTK1PyORbh1tSd2kKMdHripsHoe2r8O_Rpq3Ig9ztmh3Kqu4oX1K38VqmmVRZwCxhNVJHMWJ-qOzQ-0cvEJN_LT27RktAy6KfGyBMA1xajaa9axwn-sNUNyq9VGTOp-Hfv/?imgmax=800&quot; width=&quot;508&quot; height=&quot;246&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Oh crap!&amp;#160; After the initial freaking out was over, I took a deep breath and reviewed what I knew about Git (which was very little).&amp;#160; Well, as it so happens, I was working in the same session where I did the final commit for that branch.&amp;#160; The command “ci” is just a shell script that adds new files then commits changes.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUuOb6Ja7Wq4QOyYXi7oBYLCUxZUxHhixXlNLZzZD7cE_gXlQVIldS-so-LsYOhA6qLChVUggHfLUEYft90ZE87K2xW1cwaaX2HQJSaSDucjNHWdv5AN4Z6NWU1pP6nQsUgNTacN7_Eevg/s1600-h/The_branch_id%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;Finding the branch ID&quot; border=&quot;0&quot; alt=&quot;A screenshot of my last commit (with comment &amp;quot;finished&amp;quot;).  It shows that the ID for the branch &amp;quot;PO-updates&amp;quot; is 1c5680b.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuFA7Z0EfDXCXrmHm3n7O9hoIRvjiBGX1DIhZMYpKYf6mBmDtyfw8t6GDfJKMBRGTvFINPJtMooKEbOOyqG87BMRYNsfvo7ikGlckwX5Kfrv8fNdQuqGG9nrbXM_iojoyQfcjhn5ipvzM_/?imgmax=800&quot; width=&quot;360&quot; height=&quot;77&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hm, I wonder what I can do with this information.&amp;#160; The ID of the branch PO-updates is 1c5680b.&amp;#160; Maybe lets see if I can see the log just for this branch.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheLVZb1y0CRAzmMZxazVJISHG_qH7rAAsRBqDBX6E4H_V3YTixq_0tbSWgHyu-rp00YaAMyPE_rLvivlaDr3nSdIxIe2oYsLLg-z24XIsFVRrSGrgsWbZxef1qtCgwE_G_vHRMjtwc6CM-/s1600-h/The_commit_id%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;Finding the commit ID&quot; border=&quot;0&quot; alt=&quot;&amp;quot;git log 1c5680b&amp;quot; yields the id of the commit &amp;quot;finished&amp;quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggeFpbnEZt4-yNaxuxSF4xMZyv_eo3vOUMPapVtJi2UREkDHp_f6TOC5JOSyuaUtudngrmh5-o6TMUfnLrI7W7hAbwmm6ZFABI5X_T9m1b3R03OFJQpLJ12lvHs6i8mrKHtl-rRRDG1c55/?imgmax=800&quot; width=&quot;364&quot; height=&quot;107&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Holy $#!+ that worked!!&amp;#160; Now I have this big long @$$ commit ID (c15680b2647bfcb02d7ed6723a30d9fe2cd62e7 for anyone who cares).&amp;#160; After pondering what I could do with that for a while, I formulated this hypothesis.&amp;#160; Git seems to let you do just about anything.&amp;#160; I wondered if it would let me merge that merge the last commit in to a new branch.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPR3iTEHexoY2Nyu6fBrIvyQ9J2o8Im8StMfzss1tLTqRfaas0sN7o2mqyDg3i-8Fkq60y-z_n3MW4NmC8IPKch_E80oPMFVnxTYSNsNEg4CLUGwJXqh5L82eaz2BRmvIO2VC6_-EecwO4/s1600-h/Restoring_to_new_branch%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;Create a new branch&quot; border=&quot;0&quot; alt=&quot;Creating a new branch.  &amp;quot;git co -b PO-changes-deux&amp;quot; then merging changes from the big honking ID for the last commit.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHmpgEavQDhWgPwOuygngedLEgzXuLS9Hfp5UVaO91rLNNf0yVVSrXHIOeK6TC0FGqYHqaDnioJZA5MOPxlwgEitYq3sffKudvoy36ZnMP0n4lpSi1_sOYBjI5-nP04vehgo8LT2MUHB2X/?imgmax=800&quot; width=&quot;379&quot; height=&quot;95&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Double holy $#!+ b@man! I think it just did something amazing.&amp;#160; Did it really just merge a commit from a deleted branch into a new branch?&amp;#160; Is it possible that it would be cool enough to not immediately purge the deleted files from history?&amp;#160; I nervously opened up my project.&amp;#160; In truth, Git had me at “git init,” but that was the very moment where I became a sincere Git fanboy.&amp;#160; I don’t enter into fandom lightly, since I tend to think of fanboys as mindless zombies, but this was too much.&amp;#160; I LOVE GIT!&lt;/p&gt;  &lt;p&gt;All that I had left to do was to rename the branch to the proper name.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha9_r0Ar3-7ZxwuJrTfNGIm3cP7VqaSzDZP9l2wJyYfZ9fQzgGBejuUCDNfMC_eV4xIULtqjOvBtIZ0A7w9Lzknm9wzRft0S9OgzZ_wF1iJugjNIm8ELJNUBz8gglBzwlWoa5T9E54a9CH/s1600-h/Complete_process%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;Rename the branch&quot; border=&quot;0&quot; alt=&quot;git branch -m PO-changes-deux PO-changes&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_qDof_c-pqrabbT9acZMGnBrGt7L8Y00MFwpT84CzlqOU8eJF9f164OIiFODhL7EwDWf3l-O4PuMxPpWLsHGYmOD204qq7MkTfjgsrQPECvNsRZf7rAD2t3K90oTr70Zmsq8xZDYOkbVH/?imgmax=800&quot; width=&quot;374&quot; height=&quot;37&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now I no longer delete feature branches when I’m done with them.&amp;#160; I created a shell script called “archive” that surrounds the branch name in parentheses.&amp;#160; “archive PO-changes” would have changed the branches name to “(PO-changes)”.&amp;#160; I also created a shell script called “shelve” which surrounds the branch name in curly braces.&amp;#160; This allows me to organize the branches and visually differentiate active and inactive branches.&amp;#160; Shelved branches show up at the bottom of a branch list, and archived branches show up at the top.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyVyYW8UAzW9ZLWSZ9VrxQVeLad06aGtgWXnVZdH7mjvkeB-nTYqokM7Q5eFOmObDbCiALFkHDcw9cVkuerUwDvexd0c-B1F8u9LzqH-R7lk896MGps3EXxYuK-XoP7jaKrkHJ5h9CXTi9/s1600-h/image%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; class=&quot;wlDisabledImage&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVUEKX4_tvCnzXyYE24fVIgBiyKEZGX-3w53ITSvEeL3ddNNyxM8UIy6JIeJi67devY4E_FJzjWwJA9OyRI1pa1NQsEfO3x2ah354_XXr5athwHYQTl5UK_YxhP4JIuOtyJz5IBfhpSX3s/?imgmax=800&quot; width=&quot;178&quot; height=&quot;438&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://michael-meadows.blogspot.com/feeds/4275879032230322731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1636867873184018667/4275879032230322731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/4275879032230322731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/4275879032230322731'/><link rel='alternate' type='text/html' href='http://michael-meadows.blogspot.com/2010/08/git-saved-my-episode-ithe-phantom.html' title='Git Saved my @$$: Episode I–The Phantom Branch'/><author><name>WalkingDisaster</name><uri>http://www.blogger.com/profile/10578904054029129551</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/5644/3144/1600/JuliAndDad_small.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghY2r_OUZsnQDTK1PyORbh1tSd2kKMdHripsHoe2r8O_Rpq3Ig9ztmh3Kqu4oX1K38VqmmVRZwCxhNVJHMWJ-qOzQ-0cvEJN_LT27RktAy6KfGyBMA1xajaa9axwn-sNUNyq9VGTOp-Hfv/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1636867873184018667.post-243184310927800183</id><published>2010-04-12T06:37:00.001-04:00</published><updated>2010-04-12T06:37:42.129-04:00</updated><title type='text'>Debug NUnit tests in Visual Studio</title><content type='html'>&lt;p&gt;While developing the NUnit addin for &lt;a href=&quot;http://michael-meadows.blogspot.com/2010/04/lingual-language-driven-test-framework.html&quot; target=&quot;_blank&quot;&gt;Lingual&lt;/a&gt;, I had to come to terms with something painful.&amp;#160; If I use Lingual for my tests, I lose Resharper support for running unit tests in Visual Studio.&amp;#160; While this tradeoff isn’t bad (the NUnit GUI works fine), it also means I lose debugging support, which can be painful.&lt;/p&gt;  &lt;p&gt;If you do BDD right, you find that you don’t need to debug often, but you still do need debugging for those particularly pesky bugs.&amp;#160; Not being able to debug my tests was a nonstarter.&amp;#160; Luckily, I found some tidbits on the internets that led me to the light.&amp;#160; Unfortunately, there’s no “tutorial” style page out there that I thought good enough to link to, so here goes.&lt;/p&gt;  &lt;p&gt;In order to debug NUnit tests in Visual Studio, you need to start the NUnit GUI as an external program from Visual Studio.&amp;#160; As best I can determine, this will start NUnit and immediately attach to the process on which it runs.&lt;/p&gt;  &lt;p&gt;First, if you don’t already have an NUnit project (*.nunit), open the NUnit GUI and create a new project.&amp;#160; Add your test projects to this.&amp;#160; Save it under your solution directory.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOKx-jbjqyUIUFS6v-GHHxg-7lBKdB_16OVo-tJpBfZKKfWdbOUpnXl7O4vxWctLhqaYijst6fMirTIkjatMdjIa9NnsshkuqAVgj47NavuzYSzuZHleAhxPn4whfTjuW5dBKCyA17Momt/s1600-h/image%5B23%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoxDlsnmzeVshbXaQ2_BNT4BOyoC7NguIkIXqZLao88bCqSPrMAgjmAzZdAyzguJepd04mJkx7M7cEltFxXdXY1x-QWk7Bfq_w1KvypY9yYd54MPkE6ihLnrjQKRfG_6SJrmkZe-u4hr1l/?imgmax=800&quot; width=&quot;491&quot; height=&quot;38&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next, in visual studio, in the project properties of your test project, under the “Debug” tab, click the “Start External Program” radio button.&amp;#160; Point it to the location of your NUnit GUI.&amp;#160; Under “Command line arguments” put the path to your nunit project file.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2S0xJtlSVky411jg40w-B_E_xk0C2n9CeusoIsHmmqvSB0Eq89huJ9jhRxQ8hF13-kkRkswSJASVxhoN8T6wf8TqUzCW7GhtdeUwqr92p4pSWB9n1-KajwP-lQV41xynFQst0llAlEcxi/s1600-h/image%5B22%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1x5J6pIpZdAz5UkbfNzmviADKJwxZZgIhCXzF6si7UIxG4_Wi4LO03Dyf9cV5Lqck9sJ3TuLRnBusOS09xh0oCVXI_uD0nrmURD-6PkaMAj3bYta3YOimU-NGEbolhgObT4V68Er338aN/?imgmax=800&quot; width=&quot;514&quot; height=&quot;246&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, you can right click on the project and choose &lt;strong&gt;Debug &amp;gt; Start new instance&lt;/strong&gt;.&amp;#160; This will open the NUnit GUI.&amp;#160; Now, if you run a test that has a breakpoint set, Visual Studio will hit that breakpoint as normal.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVlZnLSH8sYUjYLnRQezcsHogP1W6KiCMDZ5dIngr5iYNrP_yUW6KP2_0mwyWFbTzP55RFs8Q64ULJBFWI4VrJ_N33zy_3OUk98lHUj1rhmA3OZ2QkYGX6JCEC-J3B2R2UTaZZNJm2yLrW/s1600-h/image%5B21%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBM8CsCJDa42Ho9lmwj4A0xifuxSLPUpiSA7BqpXFCEj6lo-rdja9tw8yIaZ7EfABsmrU4nR-x3ZprL4vB8ydqrz9AtQYLbWRTB49d7zqY0dF4i-bSkOgVV-CehzjboxFImxvQTJwJuB7I/?imgmax=800&quot; width=&quot;569&quot; height=&quot;60&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Alternately, you could set the test project as your startup project.&amp;#160; Do this by right clicking the project and selecting &lt;strong&gt;Set as StartUp Project&lt;/strong&gt;.&amp;#160; Now whenever you run by &lt;strong&gt;F5&lt;/strong&gt;, or &lt;strong&gt;Ctrl-F5&lt;/strong&gt;, the NUnit GUI will start..&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyOpvO2nH0jhZ9N_o5InKlpsah0W6wcAoQ_33gmqbTHKhxA27XpmTgNSSRQWYMm01G3yZdhAelQMctdMw6Wg941txRNc3yf5W_gG1qAvXdNeL2R59DcWycW4N3zmqRB6t6-B0Y5muur5VJ/s1600-h/image%5B27%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsbxwQSlqIde7nLZjt-uIc0wRsVNJ6n54on2evsUFLpsT5GXUMrqgmdyfcSvNsp2yekXjYTVPRL0bxky-rQprUHjBVtMj3Qs7YCR5Gr7xlLzMTcZeDMon7zsYLobFeF96I8sRqEg9stgDX/?imgmax=800&quot; width=&quot;383&quot; height=&quot;39&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There are still some pain points, like with Resharper, you could double click on a test, and it would take you to the method, or double click on a test fixture, and it would take you to the class.&amp;#160; Also, I’ll miss the hyperlinks on the stack trace that take you to the code location.&amp;#160; My hope is, though, that the gains in having an expressive language based testing framework will offset the losses in giving up Reshaprer’s integrated testing.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://michael-meadows.blogspot.com/feeds/243184310927800183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1636867873184018667/243184310927800183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/243184310927800183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/243184310927800183'/><link rel='alternate' type='text/html' href='http://michael-meadows.blogspot.com/2010/04/debug-nunit-tests-in-visual-studio.html' title='Debug NUnit tests in Visual Studio'/><author><name>WalkingDisaster</name><uri>http://www.blogger.com/profile/10578904054029129551</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/5644/3144/1600/JuliAndDad_small.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoxDlsnmzeVshbXaQ2_BNT4BOyoC7NguIkIXqZLao88bCqSPrMAgjmAzZdAyzguJepd04mJkx7M7cEltFxXdXY1x-QWk7Bfq_w1KvypY9yYd54MPkE6ihLnrjQKRfG_6SJrmkZe-u4hr1l/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1636867873184018667.post-7847925021411869702</id><published>2010-04-11T21:26:00.001-04:00</published><updated>2010-04-12T08:32:45.634-04:00</updated><title type='text'>Lingual, a language driven test framework</title><content type='html'>&lt;p&gt;I recently drafted a syntax that I thought would be helpful for BDD style unit tests in .Net for NUnit.&amp;#160; I spent the last two weeks ignoring my family whenever I could to kick out something usable.&amp;#160; I’ll blog about lessons learned in trying to extend NUnit later (more frameworks are to follow).&amp;#160; This blog post is intended to explain the fluent BDD implementation.&lt;/p&gt;  &lt;p&gt;The idea started with a question; &lt;a href=&quot;http://pastie.org/897121&quot; target=&quot;_blank&quot;&gt;is this possible&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;It didn’t take long before I got &lt;a href=&quot;http://handcraftsman.wordpress.com/2010/03/31/a-simple-csharp-bdd-test-framework/&quot; target=&quot;_blank&quot;&gt;an answer to my question&lt;/a&gt;.&amp;#160; It wasn’t exactly how I envisioned using the syntax, however, so I went ahead and continued with my effort.&amp;#160; My goals were as follows:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It is testing framework agnostic.&amp;#160; This means that once the tests are developed, they can potentially be run on any testing framework (although I have only done NUnit so far) &lt;/li&gt;    &lt;li&gt;It should itself be extensible, allowing anyone to take advantage of test framework extensions, but not locking the consumers into a particular fluent language. &lt;/li&gt;    &lt;li&gt;It should be easy to use and understand. &lt;/li&gt;    &lt;li&gt;It should not be prescriptive, meaning that it should not require the consumers to change any other aspect of their development to accommodate the framework. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I think in the first version I have gotten pretty close.&amp;#160; I made a lot of compromises to get it working with NUnit, but they’re all under the hood.&amp;#160; I think that over time I can clean up the ugliness and hopefully improve performance to boot.&lt;/p&gt;  &lt;p&gt;One thing to note (a bit of hypocrisy on my part) is that I didn’t write unit tests when developing this framework.&amp;#160; My next step is to test &lt;em&gt;after&lt;/em&gt;.&amp;#160; It’s not TDD, but the API changed so many times between inception and completion, that TDD was very difficult.&lt;/p&gt;  &lt;p&gt;You can get the &lt;a href=&quot;http://github.com/WalkingDisaster/Lingual&quot; target=&quot;_blank&quot;&gt;source&lt;/a&gt;, or &lt;a href=&quot;http://github.com/WalkingDisaster/Lingual/downloads&quot; target=&quot;_blank&quot;&gt;binaries&lt;/a&gt; on github.&lt;/p&gt;  &lt;p&gt;The completed version has a syntax that looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdoPuzT00htGnee-ypn_MoPFjcAUMmEdhYQWhNne8dpghoqxGwkJgCKT6GpnHfwLruXkQO2JJI-rPHw8Phl4fNj4dIBoSfVm4irdOfLtw50sVSta6FF80I1fdfrmgLdXbuFmF2iXgDbUAv/s1600-h/image%5B1%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil9QiANZqIq3YoyZABZ2C5y6J-wb-mh2nO4HNEtlQi9K40rRq1FK6hIlNlB8u_LfTzOqqRhdO8UmypByztGjJQVRNOmK7k7mMRqapYcLbkbDeCWF5h7ul-w7utg14ta6v7OqkcXx2R4siX/?imgmax=800&quot; width=&quot;492&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The NUnit output looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzHrJ-zHEzj_kooxNfpAx9bZJl7D9DqtQwxgX9IR5NRBPw5JhoaIb8gIKS5N7s10z9YmSp-OwAFPatdyeuoWPauns7WZditupdaX4eLh_8MC5kBNzq-0UzS6XEXH9BuZ36iDXMcvZiaO3q/s1600-h/image4%5B7%5D.png&quot;&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTM2CnLtvxnEZ0Yp2v4tj1IfZM7eZv6_c02DjxW4JML8QaPAf-dVXzk1wjzq3E1YHTz42hnK-jhXiHPJ5qvDh_v_q1BlVBO1JR0oHAvPxeWD7rCXLKXdXfiSQAZ02XkHJMkH4v4MDVJ1JZ/?imgmax=800&quot; width=&quot;819&quot; height=&quot;71&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I’ll break it down:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Given is a static class.&amp;#160; You can call “a” or “an” and pass it a generic parameter.&amp;#160; This generic parameter represents your context.&amp;#160; The context is the variables that are needed by your arrange and act methods.&amp;#160; Typically, you would include these as instance members in your test class, but since these tests run anonymously, you instead keep it in the context classes.&amp;#160; I found as I used this method more, I started to like it.&amp;#160; I’ll leave it for you to judge. &lt;/li&gt;    &lt;li&gt;Once you specify the context, you can call “that”, “which”, and “but” in any order.&amp;#160; All of them take a params array of Action&amp;lt;T&amp;gt; delegates where T is the context class you specified in the Given. &lt;/li&gt;    &lt;li&gt;When takes a Func&amp;lt;TContext, TResult&amp;gt; delegate, where TContext is the context defined above, and TResult is the class to&amp;#160; evaluate in your assertions. &lt;/li&gt;    &lt;li&gt;After you specify your when, you can call “then” or “should” or both any number of times.&amp;#160; Either method takes a params array of Action&amp;lt;T&amp;gt; delegates where T is TResult from above. &lt;/li&gt;    &lt;li&gt;Your specification should be in a property that returns an ITestSource &lt;/li&gt;    &lt;li&gt;All of the delegates used in this syntax should be method calls, where the method’s name is the text that describes what is being done.&amp;#160; Use underscores instead of spaces.&amp;#160; When the tests are generated, spaces will be substituted for the underscores. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In your project, you only have to reference Lingual.dll, and you’re ready to roll.&lt;/p&gt;  &lt;p&gt;To get this working in NUnit, take the following files and copy them to the appropriate NUnit addin directory.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Lingual.dll &lt;/li&gt;    &lt;li&gt;Lingual.Proxy.dll &lt;/li&gt;    &lt;li&gt;Lingual.Extensions.NUnit.dll &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Which NUnit directory to copy these to is a little tricky.&amp;#160; Most documentation on the internets would lead you to believe that you should copy it to the &lt;strong&gt;bin/addins&lt;/strong&gt; folder.&amp;#160; I suspect that is is only true for NUnit 2.4.x.&amp;#160; I’m using NUnit 2.5.4, and I had to put it under the &lt;strong&gt;bin/net-2.0/addins&lt;/strong&gt; directory.&amp;#160; Use whichever works for you.&lt;/p&gt;  &lt;p&gt;If you’re currently using &lt;a href=&quot;http://www.testdriven.net/&quot; target=&quot;_blank&quot;&gt;TestDriven&lt;/a&gt;, or &lt;a href=&quot;http://www.jetbrains.com/resharper/&quot; target=&quot;_blank&quot;&gt;Resharper&lt;/a&gt; to run your NUnit tests, you won’t be able to take advantage of the integrated features.&amp;#160; You can, however, launch the NUnit GUI and debug your tests in Visual Studio using &lt;a href=&quot;http://michael-meadows.blogspot.com/2010/04/debug-nunit-tests-in-visual-studio.html&quot; target=&quot;_blank&quot;&gt;this method&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Stay tuned, because I’ll blog about extending Lingual next.&lt;/p&gt;  &lt;p&gt;Please let me know what you think.&amp;#160; What works, what doesn’t work, and what can be improved.&amp;#160; In fact, feel free to extend or add as you please.&amp;#160; I did this because I thought it would make the world a better place, not because I wanted something that is exclusively mine.&amp;#160; Let’s make it ours.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://michael-meadows.blogspot.com/feeds/7847925021411869702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1636867873184018667/7847925021411869702' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/7847925021411869702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1636867873184018667/posts/default/7847925021411869702'/><link rel='alternate' type='text/html' href='http://michael-meadows.blogspot.com/2010/04/lingual-language-driven-test-framework.html' title='Lingual, a language driven test framework'/><author><name>WalkingDisaster</name><uri>http://www.blogger.com/profile/10578904054029129551</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/5644/3144/1600/JuliAndDad_small.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil9QiANZqIq3YoyZABZ2C5y6J-wb-mh2nO4HNEtlQi9K40rRq1FK6hIlNlB8u_LfTzOqqRhdO8UmypByztGjJQVRNOmK7k7mMRqapYcLbkbDeCWF5h7ul-w7utg14ta6v7OqkcXx2R4siX/s72-c?imgmax=800" height="72" width="72"/><thr:total>4</thr:total></entry></feed>