July, 2010

  • Kirill Osenkov

    WPF SendKeys or mocking the keyboard in WPF


    This post will only be interesting for the few of those who test WPF UI in-process (i.e. not through out-of-process UI automation frameworks such as White). When using in-process testing, the test lives in the same AppDomain as the code under test and has direct access to all the APIs such as UIElement.RaiseEvent.

    With out-of-process testing, the test lives in a separate process from the application under test. In this case, the test sends the application automation requests (typically using the MSAA or the newer UI Automation library). These requests eventually end up going through the operating system's window messages. The downside of this approach is that since it almost fully emulates the user behavior, the tests are fragile because a sudden Windows Update dialog popup or a random message box from another application can steal the focus from the test application and confuse the test. That's why in-process tests are generally considered more reliable, since they will work even if the application is not focused or even not visible (in case of unit-test).

    Those who have written tests using WinForms before are familiar with the helpful SendKeys class in System.Windows.Forms. It works by going through the operating system's SendInput function and provides good approximation of how the actual user's input would be routed through the system. SendKeys can be used for both in-process and out-of-process testing.

    Another thing that WinForms has is the RaiseKeyEvent methods on Control with KeyEventArgs that easily allow you to mock keyboard events in-process, at the unit-testing level.

    WPF does not provide any alternative to the SendKeys class. It does provide a RaiseEvent method, however the KeyEventArgs class in WPF was explicitly designed in such a way to prevent mocking the modifier keys state. We can see that many people are looking to call RaiseEvent from their tests and provide mock key and modifiers, however it seems that no solution is currently available. See for example this StackOverflow question: http://stackoverflow.com/questions/1263006/wpf-send-keys-redux The official guidance from the WPF team is to go through the operating system and either add a reference to System.Windows.Forms.dll to use SendKeys or directly use the SendInput API to mock the keyboard.

    I've created a little project that works around this limitation and allows you to call RaiseEvent on your WPF controls from your unit-tests and fully mock the modifier key states (Ctrl, Alt, Shift). It implements the SendKeys DSL – a little mini-language to encode keystrokes. It does some very dirty reflection magic to workaround WPF's protection against mocking modifier key states, however it works and might be useful to some people. Warning: it is NOT a replacement for the WinForms SendKeys, it's a completely different thing.

    While it is not recommended for unit tests, it can do a decent job for integration tests, when you actually show your application's UI. Chances that you need this library are very low, but if you happen to need it, then it's probably handy.

    The source is at http://wpfsendkeys.codeplex.com

  • Kirill Osenkov

    Layout Designer prototype is now open-source on CodePlex


    A while back I’ve published a preview of my WPF/Silverlight Layout Designer prototype in this blog post. If you had Silverlight 4 on your machine, you could preview it live from http://layout.osenkov.com.

    Many folks have asked for the source since then. I’m happy to announce that I’ve open sourced the project on CodePlex: http://layout.codeplex.com. I don't think I will have time to evolve it any further, because it already nicely demonstrates the concept and the idea that I wanted to convey. I’ll be happy if you find the techniques/source code useful – feel free to reuse any of it in your projects.

    As always with my hobby projects, there are no comments, no unit-tests, it doesn’t pass FxCop/StyleCop and comes with the usual caveat “AS IS”/”Written on a long weekend”. Please enjoy responsibly!

Page 1 of 1 (2 items)