TDD:测试等待功能
TDD: test wait functionality
我有一个 class Foo
,带有类似锁定机制的东西。我们将这些方法称为 lock()
、unlock()
和 waitUntilUnlocked()
。这些方法的实现不感兴趣,因为我想测试它们(TDD)。
现在我想写一个测试 waitUntilUnlocked()
真的等到 unlock()
被调用。我想出的想法如下:
@Test
public void waitUntilUnlocked_waits() {
final Foo foo = createFoo();
final long[] durationInThread = new long[1];
foo.lock();
inThread(() -> {
durationInThread[0] = measureDurationOf(this::sleepSomeTime);
foo.unlock();
});
final long waitingTime = measureDurationOf(foo::waitUntilUnlocked);
assertThat(waitingTime).isGreaterThanOrEqualTo(durationInThread[0]);
}
缺点:这与 sleep()
一起使用会导致速度变慢。此外,我有时会得到奇怪的结果,即断言 不符合 (睡眠时间为 500 毫秒,durationInThread[0]
为 501 毫秒,waitingTime
为 498 毫秒)。
对于 reliable 和 fast 测试,您有更好的想法吗?
我们的想法是编写一个测试,如果你的锁是假的,它最终会失败,但是当涉及到同步时,没有一个快速可靠的黑盒测试.
想象一下另一个人,一个自由职业者,正在写 waitUntilUnlocked()
。他懒洋洋地决定把它写成
waitUntilUnlocked()
{
//haha I know they cannot lock for more than 10 sec, easy money
Thread.sleep(10*1000);
}
您的测试将通过。您正在尝试测试 waitUntilUnlocked()
的调用者将等待 永远 ,这是无法测试的。
更简单的测试方法是结合这两个测试。
第一个是您的测试有点简化。它测试线程确实等待至少一段时间时被锁定。
final Foo foo = createFoo();
foo.lock();
inThread(() -> {
foo.waitUntilUnlocked();
});
long time_millisec = 100;
inThread.join(time_millisec);
bool success = inThread.isAlive();
它永远不会解锁。 time_millisec
是你的参数。无需测量时间。
第二个测试线程在解锁后是否取得进展。您可以添加一个计时器来测量连接完成前的时间。
final Foo foo = createFoo();
inThread(() -> {
foo.waitUntilUnlocked();
});
inThread.join();
return true; //success
只有在 waitUntilUnlocked
终止后,您才能在加入后执行任何操作。
黑盒测试显示了它在您的情况下的局限性
我有一个 class Foo
,带有类似锁定机制的东西。我们将这些方法称为 lock()
、unlock()
和 waitUntilUnlocked()
。这些方法的实现不感兴趣,因为我想测试它们(TDD)。
现在我想写一个测试 waitUntilUnlocked()
真的等到 unlock()
被调用。我想出的想法如下:
@Test
public void waitUntilUnlocked_waits() {
final Foo foo = createFoo();
final long[] durationInThread = new long[1];
foo.lock();
inThread(() -> {
durationInThread[0] = measureDurationOf(this::sleepSomeTime);
foo.unlock();
});
final long waitingTime = measureDurationOf(foo::waitUntilUnlocked);
assertThat(waitingTime).isGreaterThanOrEqualTo(durationInThread[0]);
}
缺点:这与 sleep()
一起使用会导致速度变慢。此外,我有时会得到奇怪的结果,即断言 不符合 (睡眠时间为 500 毫秒,durationInThread[0]
为 501 毫秒,waitingTime
为 498 毫秒)。
对于 reliable 和 fast 测试,您有更好的想法吗?
我们的想法是编写一个测试,如果你的锁是假的,它最终会失败,但是当涉及到同步时,没有一个快速可靠的黑盒测试.
想象一下另一个人,一个自由职业者,正在写 waitUntilUnlocked()
。他懒洋洋地决定把它写成
waitUntilUnlocked()
{
//haha I know they cannot lock for more than 10 sec, easy money
Thread.sleep(10*1000);
}
您的测试将通过。您正在尝试测试 waitUntilUnlocked()
的调用者将等待 永远 ,这是无法测试的。
更简单的测试方法是结合这两个测试。
第一个是您的测试有点简化。它测试线程确实等待至少一段时间时被锁定。
final Foo foo = createFoo();
foo.lock();
inThread(() -> {
foo.waitUntilUnlocked();
});
long time_millisec = 100;
inThread.join(time_millisec);
bool success = inThread.isAlive();
它永远不会解锁。 time_millisec
是你的参数。无需测量时间。
第二个测试线程在解锁后是否取得进展。您可以添加一个计时器来测量连接完成前的时间。
final Foo foo = createFoo();
inThread(() -> {
foo.waitUntilUnlocked();
});
inThread.join();
return true; //success
只有在 waitUntilUnlocked
终止后,您才能在加入后执行任何操作。
黑盒测试显示了它在您的情况下的局限性