等待事件触发在Silverlight单元测试单元测试、事件、Silverlight

2023-09-03 03:57:42 作者:熟到陌路

我使用Silverlight的单元测试框架来测试一些视图管理器类。有些测试需要的的PropertyChanged 的事件被解雇。

I am using the Silverlight Unit Testing Framework to test some View Manager classes. Some tests require the PropertyChanged events to be fired.

我目前使用的组合 EnqueueConditional 和 WaitHandles

示例1

[TestMethod]
[Asynchronous]
[Timeout(1000)]
public void TestNotificationExample()
{
    var manager = new UserManager();

    var waitHandle = new ManualResetEvent(false);
    manager.PropertyChanged += (sender, propChangArgs) =>
                                {
                                    waitHandler.Set();
                                };
    manager.DoTheThingThatTriggersNotification();
    // The notification event fires aynshronously to this
    EnqueueConditional (() => waitHandler.WaitOne(0));
    // Enqueue other tests here....
    EnqueueTestComplete();
}

这工作。但我有问题,困扰着我:

This works. But I've got questions nagging at me:

我是不是真的需要使用一个WaitHandle的?它会执行,如果我只是用一个布尔值一样呢?

Do I actually need to use a WaitHandle? Would it perform equally as well if I just used a bool?

例2

bool fHasFiredEvent = false;
manager.PropertyChanged += (sender, propChangeArgs) =>
                           { 
                               fHasFiredEvent = true;
                           }
manager.DoTheThingThatTriggersNotification();    
EnqueueConditional (() => fHasFiredEvent);
EnqueueTestComplete();

还是会更好,如果我不停的WaitHandle中,却失去了TimeoutAttribute和超时的等待?

Or would it be better if I kept the WaitHandle, but lost the TimeoutAttribute and timed out on the Wait?

示例3

[TestMethod]
[Asynchronous]
public void TestNotificationExample()
{
    var manager = new UserManager();

    var waitHandle = new ManualResetEvent(false);
    manager.PropertyChanged += (sender, propChangArgs) =>
                                {
                                    waitHandler.Set();
                                };
    manager.DoTheThingThatTriggersNotification();
    EnqueueCallback (() => Assert.IsTrue(waitHandler.WaitOne(1000));
    EnqueueTestComplete();
}

所以,现在我已经写了三个例子,和他们所有的工作。因此,我的最后一个问题是

So now I've written three examples, and they all work. So my final question is

这将有最好的 性能? (尽管 差可以忽略不计,它的 纯粹的学术亚达内容十分重要。有意思的是为了自身利益。) 请所有的三个例子已 根本缺陷? Which would have the best performance? (Even though the difference is negligible and it's purely academic yada yada yada. It's interesting for its own sake.) Do any of the three examples have fundamental flaws?

推荐答案

而无需实际运行真正的code的三个例子,我不知道我能给出一个权威的答案,但我的建议是使用#2,引导好清楚的#1和#3。

Without actually running real code in the three examples, I don't know that I can give an authoritative answer, but my advice would be to use #2, and steer well clear of #1 and #3.

我已经通过了源杰夫·威尔科克斯'的Silverlight单元测试框架戳,而我记得,他用的是聪明,但真正可怕的黑客为EnqueueConditional,也就是说,他反复调用传递给En​​queueConditional了predicate( )上的计时器/后台线程,检查每个时间,看看它是否返回true。 (这不是你想在生产code什么的,但它不够好测试框架的逻辑,我想。)

I've poked through the source for Jeff Wilcox' Silverlight Unit Test Framework, and as I recall, he uses a clever but really horrible hack for the EnqueueConditional, i.e., he repeatedly calls the predicate passed to EnqueueConditional() on a timer/background thread, checking each time to see if it returns true. (It's not what you want in production code, but it's good enough for a test framework is the logic, I suppose.)

所以,如果你的测试需要几秒钟就可以完成,我希望你waitHandler.WaitOne()是(a)被调用无数次,每次阻塞线程,因为它去;或(b)阻止一个线程,该线程可以应该做其他事情,以及。我想,一个(C)也是可以的,比如,你可能会得到幸运的了WaitOne()不会阻碍任何重要的,并且只会被调用一次。但可以肯定的#2是使用该测试框架的标准的方式,除非你有特殊原因,引进的WaitHandle的更复杂的逻辑,我不会试图推动该方向的测试框架。

So if your test takes a couple seconds to complete, I would expect your waitHandler.WaitOne() either (a) to be called numerous times, blocking each thread as it goes; or (b) to block a thread that may be supposed to be doing other things as well. I suppose a (c) is also possible, i.e., you might get lucky, the WaitOne() wouldn't block anything important, and would only get called once. But certainly #2 is the "standard" way of using this test framework, and unless you had a specific reason to introduce the more complex logic of a WaitHandle, I wouldn't try to push the test framework in that direction.

也就是说,如果有人想闲逛,并提供一个更加权威的答案,我所有的耳朵: - )

That said, if anybody wants to poke around and deliver a more authoritative answer, I'm all ears :-).