0

Background
I'd like to auto test the Windows Form classes in my project. I'd like to conduct tests like "If Button F5 was clicked, has functionality xyz been executed?".

In order to do that I need to trigger mouse-click or keyboard events.

Environment

  • Gui: Windows Forms
  • Test framework: MSTests
  • Test style: I don't tests an independent exe file

Question
How can I trigger mouse-click or keyboard events on a control?

+α: How to trigger any arbitrary event on an arbitrary control?

Concrete example
I have a GridDataView in my productive form. In my test I run view.Row (0).selected = True to select the first row. Now I'd like to trigger a doubleclick event and an Keys.Enter Key event to simulate these user interactions.

What I've tried so far

  • view.PerformDoubleClick()
  • view.DoubleClick (Nothing,Nothing)
  • view.OnDoubleClick (Nothing)
  • RaiseEvent DoubleClick (Nothing,Nothing)
  • RaiseEvent view.DoubleClick (Nothing,Nothing)

None of these methods worked; some don't even compile

This Microsoft article indicates, that it might be impossible to accomplish, what I'm trying

An event can be raised only from the declaration space in which it is declared. Therefore, a class cannot raise events from any other class, even one from which it is derived.

DarkTrick
  • 2,447
  • 1
  • 21
  • 39
  • Are you asking about automated UI tests here? If so I really would warn against building anything directly into your software as you might find it either causes irrelevant faults or covers up actual faults. There really isn't any substitute for just rolling up your sleeves and doing it yourself. That said there are plenty out automated GUI testing tools already available – Hursey Aug 09 '21 at 03:40
  • Perhaps a misunderstanding. I tried to clearify the question: I don't test an exe, but I test with MSTest in unittest-style. – DarkTrick Aug 09 '21 at 03:47
  • 1
    You don't use unit tests or anything like unit tests to test a UI. Do as already instructed an look into automated GUI testing tools. – jmcilhinney Aug 09 '21 at 03:52
  • These suggestions go OT. I don't want to use a new tool for something I should be able to accomplish as a simple unit test. – DarkTrick Aug 09 '21 at 03:56
  • 1
    It's not a unit test. You should not be able to do it as a unit test. The topic is wrong, hence the suggestion being OT. If you ask how to do the wrong thing, don't be surprised when people tell you to do the right thing instead. – jmcilhinney Aug 09 '21 at 04:03

2 Answers2

0

The only solution I've found is to Subclass every control (widget) you want to operate on and make their On*() methods public.

The code below subclasses a Button to allow OnClick() and OnKeyDown() methods to be used from outside.

Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Public Class MyButton
  Inherits Button


  Public Shadows Sub OnClick (e As System.EventArgs)
      MyBase.OnClick (e)
  End Sub

  Public Shadows Sub OnKeyDown (kevent As KeyEventArgs)
      MyBase.OnKeyDown (kevent)
  End Sub

End Class

Notices regarding KeyDown:

  • Good: Calling OnKeyDown() from outside will not trigger anything if the Form's KeyPreview is set to False. That is consistent with actual key events and therefore good.
  • Bad: Key events won't be forwareded.
    Consider a Form and a Button having a KeyDown event. If the user presses a key on the actual GUI, the event will arrive at both controls/widgets. However, using the method described here, the event will only be triggered within the object was was called upon
DarkTrick
  • 2,447
  • 1
  • 21
  • 39
-2

Can you directly call the OnClick() function of the control? Is it sufficient for your test?

I remember it's impossible to simulate the event, even though it is possible to call the function from outside. This has happened to me too.