【问题标题】:Virtual Keyboard test isn't working with my Keyboard Wedge虚拟键盘测试不适用于我的键盘楔
【发布时间】:2014-05-29 12:53:32
【问题描述】:

我已经安装了 com0com,以便我可以编写 NUnit 测试。以防万一键盘楔的定义不同,它的简要描述是一个软件,它监听串行通信设备,读取发送给它的任何数据(在我的情况下将其格式化为 ASCII 数据)然后将其发送到虚拟键盘。此代码在生产中确实有效,但我们现在需要记录我们的代码或进行单元测试以证明它应该如何使用。所以这是我的测试

    [Test()]
    public void WedgeSendsTextToVirtualKeyboardTest()
    {
        (var form = new Form())
        using(var sp = new System.IO.Ports.SerialPort("COM"+COMB, 115200))
        using (var wedge = new KeyboardWedgeConfiguration(WEDGE_KEY))
        {
            sp.Open();

            TextBox tb = SetupForm(form);
            TurnOnKeyboardWedge(wedge);
            form.Activate();
            form.Activated += (s, e) =>
                {
                    tb.Focus();
                };
            while (!tb.Focused) { }

            string str = "Hello World";
            sp.Write(str);

            //wait 1 second. This allows data to send, and pool in the wedge
            //the minimum wait time is 200ms. the string then gets put into bytes
            //and shipped off to a virtual keyboard where all the keys are pressed.
            System.Threading.Thread.Sleep(1000);
            Expect(tb.Text, Is.EqualTo(str));

        }
    }
    private static TextBox SetupForm(Form form)
    {
        TextBox tb = new TextBox();
        tb.Name = "tb";
        tb.TabIndex = 0;
        tb.AcceptsReturn = true;
        tb.AcceptsTab = true;
        tb.Dock = DockStyle.Fill;
        form.Controls.Add(tb);
        form.Show();
        return tb;
    }

    private static void TurnOnKeyboardWedge(KeyboardWedgeConfiguration wedge)
    {
        wedge.Port = COMA;
        wedge.PortForwardingEnabled = true;
        wedge.Baud = 115200;
        System.IO.Ports.SerialPort serialPort;

        wedge.StartRerouting();
        Assert.IsTrue(wedge.IsAlive(out serialPort));
        Assert.IsNotNull(serialPort);
    }

当测试运行时,表单显示,文本框中没有文本,然后测试退出,最后一个断言失败 (Expect(tb.Text, Is.EqualTo(str));) 说 tb.Text 是 string.Empty。我尝试了许多不同的策略来关注该文本框(我假设这至少是问题所在)。有一次我让我的睡眠时间更长,以便我有时间点击文本框并输入自己,但我无法点击该框(我假设这是因为睡眠操作......这也可能是为什么我的楔子也不能在那里输入)所以我该如何解决这个问题并让我的测试通过。这段代码再次在生产环境中工作,所以我 100% 确信这是我的测试(可能是睡眠操作)

【问题讨论】:

  • 我认为this question/answer 可以帮助指导您。您可以做类似的事情,将表单移动到它自己的线程,并将串行端口写入另一个线程,然后等待它们。

标签: c# winforms nunit


【解决方案1】:

在这个问题stackoverflow question 的帮助下,我能够通过测试(非常感谢 Patrick Quirk)。它实际上是一个小的变化。我什至不确定我的解决方案是否 100% 正确,但是当表单弹出时,输入了文本并且我的测试通过了。解决方案是两部分系统。首先,我必须创建一个扩展Form 的类,覆盖Text 属性,并监听ActivatedFormClosing 事件。在 Form Closing 我会设置我的文本,在 Activated 我告诉我的TextBox 有焦点。

    private class WedgeForm : Form
    {
        public override string Text { get { return text; } set { text = value; } }

        string text = string.Empty;
        private TextBox tb;

        public WedgeForm()
        {
            InitializeControls();

            Activated += (s, e) => { tb.Focus(); };
            FormClosing += (s, e) => { this.Text = tb.Text; };
        }

        private void InitializeControls()
        {
            tb = new TextBox();
            tb.Name = "tb";
            tb.TabIndex = 0;
            tb.AcceptsReturn = true;
            tb.AcceptsTab = true;
            tb.Multiline = true;
            tb.Dock = DockStyle.Fill;
            this.Controls.Add(tb);
        }
    }

然后使用其他问题/答案中提供的 InvokeEx 方法我的测试易于设置

    [Test()]
    public void WedgeSendsTextToVirtualKeyboardTest()
    {
        using (var form = new WedgeForm())
        using (var wedge = new KeyboardWedgeConfiguration(WEDGE_KEY))
        {
            TurnOnKeyboardWedge(wedge);

            string actual = MakeWedgeWriteHelloWorld(form, wedge); ;
            string expected = "Hello World";

            Expect(actual, Is.EqualTo(expected));
        }
    }

    private static string MakeWedgeWriteHelloWorld(WedgeForm form, KeyboardWedgeConfiguration wedge)
    {
        var uiThread = new Thread(() => Application.Run(form));
        uiThread.SetApartmentState(ApartmentState.STA);
        uiThread.Start();

        string actual = string.Empty;
        var thread = new Thread
            (
                () => actual = InvokeEx<Form, string>(form, f => f.Text)
            );

        using (var sp = new System.IO.Ports.SerialPort("COM" + COMB, 115200))
        {
            sp.Open();
            sp.Write("Hello World");
        }
        //wait 1 second. This allows data to send, and pool in the wedge
        //the minimum wait time is 200ms. the string then gets put into bytes
        //and shipped off to a virtual keyboard where all the keys are pressed.
        Thread.Sleep(1000);
        InvokeEx<Form>(form, f => f.Close());
        thread.Start();
        uiThread.Join();
        thread.Join();

        return actual;
    }

在运行此测试时我必须记住的一件小事是不要到处点击,因为如果该文本框失去焦点,我就会陷入困境。但是测试只有1秒长..我想我会活下去的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 2015-01-02
    • 2013-04-02
    • 1970-01-01
    相关资源
    最近更新 更多