虚拟键盘测试不能使用我的Keyboard Wedge

时间:2014-05-29 12:53:33

标签: c# winforms nunit

我已经安装了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%确信这是我的测试(可能是睡眠操作)

1 个答案:

答案 0 :(得分:0)

我能够在这个问题stackoverflow question的帮助下完成测试通过(非常感谢Patrick Quirk)。它实际上是一个小变化。我甚至不确定我的解决方案是否100%正确,但是当表单弹出时,输入文本并且我的测试通过。解决方案是两部分系统。首先,我必须创建一个扩展Form的类覆盖Text属性,并监听ActivatedFormClosing事件。在表单结束时,我会设置我的文本,并在激活时,我告诉我的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);
        }
    }

然后使用其他qustion / answer中提供的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秒......我想我会活下去。