<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Being Cellfish : GUI</title><link>http://blogs.msdn.com/cellfish/archive/tags/GUI/default.aspx</link><description>Tags: GUI</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Practical unit testing of graphical user interfaces</title><link>http://blogs.msdn.com/cellfish/archive/2009/02/15/practical-unit-testing-of-graphical-user-interfaces.aspx</link><pubDate>Sun, 15 Feb 2009 14:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9420196</guid><dc:creator>cellfish</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/cellfish/comments/9420196.aspx</comments><wfw:commentRss>http://blogs.msdn.com/cellfish/commentrss.aspx?PostID=9420196</wfw:commentRss><description>&lt;P&gt;When &lt;A class="" href="http://blogs.msdn.com/cellfish/archive/2009/01/10/unit-testing-graphical-user-interfaces.aspx" mce_href="http://blogs.msdn.com/cellfish/archive/2009/01/10/unit-testing-graphical-user-interfaces.aspx"&gt;I last wrote about TDD and GUI&lt;/A&gt; I was talking quite vaguely about how TDD of GUIs can work. Since then I've thought more on the practical details and by chance the book I was reading at the time (Testdriven by Lasse Koskela) covered this topic. Inspired by that book I've done a few experiments.&lt;/P&gt;
&lt;P&gt;First of all we must decide on what we want to test in the GUI. Usability can never be tested only by applying TDD/BDD. So we don't want to test the looks of the GUI. We should test the functionality of the GUI. There is also two types of graphical components we will be testing. There are user controls where we want to test that certain pixels turn out the way we want and there are other types of graphical components.&lt;/P&gt;
&lt;P&gt;Let's first look at graphical components where we actually want to check pixel colors. What could this be? Well, it could be a custom graph component or a progress bar. Something where we easily can know from how we setup the test that certain pixels will be of a certain color. To test this we should render the user control to an in-memory bitmap and check the color. Using WPF this is pretty easy using the &lt;FONT face=Courier&gt;Render&lt;/FONT&gt; method. Using WinForms we have to use different methods depending on if it is a form or control we're testing. The reason forms are different is that depending on the layout it can be impossible to know the exact offset that should be used so the same method as used for controls cannot be used. On the other hand you should probably not test complete forms by drawing them to a bitmap anyway...&lt;/P&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; PaintControl(Control control, Bitmap b)
&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;        {
&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;            Point offset = GetClientOffset(control);
&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (Control c &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; control.Controls)
&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;            {
&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;                c.DrawToBitmap(b, &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Rectangle(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Point(offset.X + c.Location.X, offset.Y + c.Location.Y), c.Size));
&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;                PaintControl(c, b);
&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;            }
&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;The offset code would not be needed if we can use the protected &lt;FONT face=courier&gt;InvokePaint&lt;/FONT&gt; method.&lt;/P&gt;
&lt;P&gt;So what about all controls where exact pixel match is not needed, what should we test? Well we can always test relative positioning if it makes sense. Things like "the &lt;EM&gt;OK button is always above all other buttons&lt;/EM&gt;" could be tested if we find that useful. Other than that we should focus on testing that the functionality of the user interface is correct. In order to do this and to make our GUI easily tested I think the &lt;A class="" href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target=_blank mce_href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC&lt;/A&gt; (Model-View-Controller) pattern is a great candidate. And probably the best is the variant called &lt;A class="" href="http://en.wikipedia.org/wiki/Model_View_Presenter" target=_blank mce_href="http://en.wikipedia.org/wiki/Model_View_Presenter"&gt;MVP&lt;/A&gt; (Model-View-Presenter) with a passive view. The model is a no-brainer from a TDD perspective. The presenter should be as easy to test. And with a passive view that one should be pretty easy to test too.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9420196" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/cellfish/archive/tags/BDD/default.aspx">BDD</category><category domain="http://blogs.msdn.com/cellfish/archive/tags/TDD/default.aspx">TDD</category><category domain="http://blogs.msdn.com/cellfish/archive/tags/GUI/default.aspx">GUI</category></item><item><title>Unit testing graphical user interfaces</title><link>http://blogs.msdn.com/cellfish/archive/2009/01/10/unit-testing-graphical-user-interfaces.aspx</link><pubDate>Sun, 11 Jan 2009 00:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9222478</guid><dc:creator>cellfish</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/cellfish/comments/9222478.aspx</comments><wfw:commentRss>http://blogs.msdn.com/cellfish/commentrss.aspx?PostID=9222478</wfw:commentRss><description>&lt;P&gt;Once you start using BDD (or TDD (whenever I write BDD I could have written TDD) one common obstacle you encounter is writing tests for your GUI. Most people I know feels it is so hard that they actually don't write tests for their GUI. Instead they keep the GUI layer of the application as thin as possible and reduces the number of defects there that way. Others use tools like &lt;A class="" title=Selenium href="http://blogs.msdn.com/cellfish/archive/2008/04/09/selenium-the-test-tool.aspx" mce_href="http://blogs.msdn.com/cellfish/archive/2008/04/09/selenium-the-test-tool.aspx"&gt;Selenium&lt;/A&gt; to add tests once the GUI is created. In both cases you're not really being a strict BDD practitioner.&lt;/P&gt;
&lt;P&gt;Actually I think this is a very common, pragmatic decision made by many developers since most people find GUIs very hard to test. But are they really? I recently looked at a company internal web cast on testing where the speaker said something like: "&lt;EM&gt;I've written unit tests for user interfaces most part of my career. When I started nobody told med unit testing user interfaces was hard so I just did it&lt;/EM&gt;". This is a very important observation. If you are a convinced BDD practitioner I think you believe that the use of BDD will lead to a better and more testable design. You have also probably experienced how BDD have changed the way you design your code as compared to before you started with BDD and did everything the old fashioned way. So in other areas you have evolved the way you design your code. But still you write your GUI the same way you did before.&lt;/P&gt;
&lt;P&gt;Why do we stick with the same old GUI code then (other than that everybody keeps saying it is impossible)? I think our development tools are one problem here. Our tools are used to design our GUIs and generates lots of code. And that code is not testable so if we want to write testable code we believe we have to write more code manually. And writing GUI code manually is boring, right?&lt;/P&gt;
&lt;P&gt;Albert Einstein once said: "&lt;EM&gt;We can't solve problems by using the same kind of thinking we used when we created them&lt;/EM&gt;". And I think that is very true for this case too. If we want to write unit tests for our GUIs in a BDD manner I think we must rethink how we write our GUIs. One way of doing it is &lt;A class="" title="ShowMe - Can you TDD a GUI" href="http://ellnestam.wordpress.com/2008/12/14/smidig-2008-talk-can-you-tdd-a-gui/" target=_blank mce_href="http://ellnestam.wordpress.com/2008/12/14/smidig-2008-talk-can-you-tdd-a-gui/"&gt;described in this lightning talk&lt;/A&gt; which is in Swedish.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9222478" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/cellfish/archive/tags/BDD/default.aspx">BDD</category><category domain="http://blogs.msdn.com/cellfish/archive/tags/TDD/default.aspx">TDD</category><category domain="http://blogs.msdn.com/cellfish/archive/tags/GUI/default.aspx">GUI</category></item><item><title>Using CSS to fetch user browser history</title><link>http://blogs.msdn.com/cellfish/archive/2008/08/12/using-css-to-fetch-user-browser-history.aspx</link><pubDate>Tue, 12 Aug 2008 08:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8849990</guid><dc:creator>cellfish</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/cellfish/comments/8849990.aspx</comments><wfw:commentRss>http://blogs.msdn.com/cellfish/commentrss.aspx?PostID=8849990</wfw:commentRss><description>&lt;P&gt;If you know what you're looking for in the user's browser history there is a pretty simple way to check if the user have visited a certain site recently or not. Basically you can create an invisible iframe with the link(s) you want to check and then use java script to query the appearance of the link. CSS tell you if the link is visited or not. A more detailed description on how this works can be found &lt;A class="" href="http://www.azarask.in/blog/post/socialhistoryjs/" target=_blank mce_href="http://www.azarask.in/blog/post/socialhistoryjs/"&gt;here&lt;/A&gt;. The way this exploit is used there is actually quite nice I think, since it enhances the user experience. And I have no problem with ads customized to match my browser history. I usually don't see them at all because of the ad blocker but if I could get ads that I'm actually interested in this would also enhance my user experience. So far no harm done. I guess the problem with this exploit is that &lt;A class="" title="Wikipedia: Phising" href="http://en.wikipedia.org/wiki/Phising" target=_blank mce_href="http://en.wikipedia.org/wiki/Phising"&gt;phising&lt;/A&gt; sites like those impersonating a bank or paypal could now customize their phising attack to match the bank (or other service) the user actually have visited recently.&lt;/P&gt;
&lt;P mce_keep="true"&gt;If you use Firefox (which have tried to fix this since 2002) there is &lt;A class="" href="http://crypto.stanford.edu/sameorigin/stanford-safehistory-0.9.xpi" target=_blank mce_href="http://crypto.stanford.edu/sameorigin/stanford-safehistory-0.9.xpi"&gt;a plugin to fix this&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8849990" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/cellfish/archive/tags/GUI/default.aspx">GUI</category><category domain="http://blogs.msdn.com/cellfish/archive/tags/Security/default.aspx">Security</category></item><item><title>Hiding or disabling menu items not available?</title><link>http://blogs.msdn.com/cellfish/archive/2008/08/07/hiding-or-disabling-menu-items-not-available.aspx</link><pubDate>Thu, 07 Aug 2008 10:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8840527</guid><dc:creator>cellfish</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/cellfish/comments/8840527.aspx</comments><wfw:commentRss>http://blogs.msdn.com/cellfish/commentrss.aspx?PostID=8840527</wfw:commentRss><description>&lt;P&gt;About a month ago &lt;A class="" title="Don't hide or disable menu items" href="http://www.joelonsoftware.com/items/2008/07/01.html" target=_blank mce_href="http://www.joelonsoftware.com/items/2008/07/01.html"&gt;Joel Spolsky wrote a very short post&lt;/A&gt; instructing people to not hide or disable menu items that are not available. This I've been working on one of my spare time projects this summer - a project that involves a web based user interface I've given this some thought. At a first glance Joel's recommendation makes sense. At least to me since I've several times found my self in a situation where I see a disabled menu item or button in an application and I know I want to use that command but I have no idea what I needed to do to enable the option. Under such circumstances I would have loved the developers if they'd let me click the darn thing and then tell me what I need to do.&lt;/P&gt;
&lt;P&gt;However, things are never black or white - they're gray. And different situations call for different approaches I think. I also think you should include buttons in this discussion. The good thing is that buttons can be handled in the same way as menu items.&lt;/P&gt;
&lt;H3&gt;Hide vs Disable&lt;/H3&gt;
&lt;P&gt;A user menu should never change its content due to application state. If menu items are hidden and shown the user will have a harder time recognize the menus. It is easier for the user to navigate the menu if it is always the same (except that some things are disabled from time to time). Same applies to buttons since there sooner or later will be a manual with screen shots and if the user does not see all the buttons they will think they have the wrong view.&lt;/P&gt;
&lt;P&gt;There is however one situation I think you should hide the menu item. That is when there is nothing the user can do to enable the item. This typically applies to security settings. If the user does not have access to a certain feature, and never will have unless somebody changes the security policy, it's just annoying to see that option all the time. Personally I hate those web sites where you try to access some page and all you get is a "&lt;EM&gt;you do not have access to this feature&lt;/EM&gt;".&lt;/P&gt;
&lt;H3&gt;Disable vs Enable&lt;/H3&gt;
&lt;P&gt;If you disable an item you have to perform some kind of check when rendering the menu item (or button). You will also have to perform the same check when actually handling the click event in order to protect against programming errors and abuse by an evil user. Sometimes this check may be very expensive to perform. If the check is expensive to perform I tend to leave the item enabled (for a quick rendering routine) and then handle it once the item is clicked. But the error message must be descriptive and clearly point out what the user have to do in order to complete the action.&lt;/P&gt;
&lt;P&gt;I would also leave the item enabled if there is a complex series of actions the user have to perform in order to enable the item. I think it is better to let the user get a descriptive error message telling him what to do rather than just disabling the item.&lt;/P&gt;
&lt;P&gt;Another thing to consider is that many users are afraid of pop-up error messages and even offended since they think they did something wrong. And if you throw an error message in their face for something simple they think they'd understand if the item had been disabled instead they might get angry at your application (and you). You can't please them all but you should consider this. For example if you have an edit view that is used for editing and creating items you might wanna disable the delete-button when in create mode rather than telling the user "they can't delete an item that is not created" when they click it.&lt;/P&gt;
&lt;P&gt;Tool-tips are the rescue. Adding a tool-tip for each disabled item telling the user why the item is disabled is an excellent solution.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;So as usual in the wonderful world of software development, &lt;EM&gt;it depends&lt;/EM&gt;. For items not available to the user at a given time, these are my recommendations:&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;If the user will never have access to the feature - hide it.&lt;/LI&gt;
&lt;LI&gt;If the user may access the feature but it is cumbersome to determine if so is the case - enable it.&lt;/LI&gt;
&lt;LI&gt;If the user may access the feature only after a series of complex, non-obvious&amp;nbsp;actions - enable it.&lt;/LI&gt;
&lt;LI&gt;Otherwise - disable it, preferably with a tool-tip explaining why the item is disabled.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;If the item is enabled the error message when clicked (and the action fails) must be descriptive and tell the user exactly what went wrong and what he can do to complete the action.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8840527" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/cellfish/archive/tags/GUI/default.aspx">GUI</category></item></channel></rss>