评估具有延迟的布尔值,但未正确计时
Boolean with delay is evaluated, but not properly timed
我有一个执行 Runnable
的方法,然后将它完成所花费的时间传递给另一个方法:
public static void benchmark(Runnable runnable) {
LocalDateTime before = LocalDateTime.now();
runnable.run();
logToDocument(before, LocalDateTime.now());
}
当我使用这种方法来计时网页的加载时,两个时间戳完全相同,即 LocalDateTime before = LocalDateTime.now()
和 logToDocument(before, LocalDateTime.now())
同时发生,即使我在现实中观察到每个页面加载需要几秒钟。我调用benchmark
的方法如下:
public static void subTestDelay(boolean log, boolean condition, int delay, String message) {
if (log) {
SoftAssert softAssert = new SoftAssert();
ExtentTestManager.benchmark(() -> {
if (!condition) {
tempData.failStatus();
softAssert.fail("Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ").concat(message));
}
});
softAssert.assertAll();
} else {
Assert.assertTrue(condition, "Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ").concat(message));
}
}
变量condition
,在本例中,是这样的:
public static boolean expectedPageIsLoaded(WebDriver driver, int seconds, String pageName) {
final By loadingBar = By.cssSelector("div[class*='progress']");
final Wait<WebDriver> wait = new FluentWait<>(driver).withTimeout(Duration.ofSeconds(seconds)).pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class).ignoring(NullPointerException.class);
String originalPageName = driver.findElement(By.tagName("body")).getAttribute("page-name");
if (originalPageName == null) {
originalPageName = "no previous page";
tempData.setAction(tempData.REDIRECT);
tempData.setArbitraryData(driver,tempData.TRIGGER, tempData.NAVIGATION, tempData.ORIGIN, originalPageName, tempData.DESTINATION, "user authentication");
}
ExtentTestManager.log(logger, Level.INFO, "Loading page: ".concat(pageName).concat("; Waiting a maximum of: ").concat(String.valueOf(seconds)).concat(" seconds"));
try {
startDateTime = LocalDateTime.now();
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(loadingBar));
wait.until(wd -> (GenericTestMethods.pageName(wd).equals(pageName) && wd.findElements(loadingBar).size() == 0));
endDateTime = LocalDateTime.now();
ExtentTestManager.log(logger, Level.INFO, "Page: ".concat(pageName).concat(" loaded after: ").concat(String.valueOf(Duration.between(startDateTime, endDateTime).toMillis())).concat(" milliseconds"));
return true;
} catch (TimeoutException ex) {
return false;
}
}
当我连续测试 4 个网页时,我得到了每个页面加载的正确持续时间,如您在此处所见:
12:35:36.774 [main] INFO test_classes.base.DriverInit - Loading page: user authentication; Waiting a maximum of: 180 seconds
12:35:39.902 [main] INFO test_classes.base.DriverInit - Page: user authentication loaded after: 3124 milliseconds
12:35:41.333 [main] INFO test_classes.base.DriverInit - Loading page: user_cockpit; Waiting a maximum of: 180 seconds
12:35:46.474 [main] INFO test_classes.base.DriverInit - Page: user_cockpit loaded after: 5140 milliseconds
12:35:47.947 [main] INFO test_classes.base.DriverInit - Loading page: organization_overview_time_focus; Waiting a maximum of: 180 seconds
12:35:50.013 [main] INFO test_classes.base.DriverInit - Page: organization_overview_time_focus loaded after: 2066 milliseconds
12:35:51.210 [main] INFO test_classes.base.DriverInit - Loading page: project_time_overview; Waiting a maximum of: 180 seconds
12:35:52.604 [main] INFO test_classes.base.DriverInit - Page: project_time_overview loaded after: 1393 milliseconds
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 25.446 s - in TestSuite
此反馈来自 boolean
expectedPageIsLoaded
:
startDateTime = LocalDateTime.now();
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(loadingBar));
wait.until(wd -> (GenericTestMethods.pageName(wd).equals(pageName) && wd.findElements(loadingBar).size() == 0));
endDateTime = LocalDateTime.now();
ExtentTestManager.log(logger, Level.INFO, "Page: ".concat(pageName).concat(" loaded after: ").concat(String.valueOf(Duration.between(startDateTime, endDateTime).toMillis())).concat(" milliseconds"));
然而,我从benchmark
得到的反馈是每次加载页面前后都有两个时间戳,它们总是相同的。为了说明这一点,我修改了 benchmark
以打印出 Runnable
前后的时间戳。这是我得到的:
Before loading: 2021-11-03T12:42:42.855008800
After loading: 2021-11-03T12:42:42.855008800
Before loading: 2021-11-03T12:42:51.505117900
After loading: 2021-11-03T12:42:51.505117900
Before loading: 2021-11-03T12:42:55.145636200
After loading: 2021-11-03T12:42:55.145636200
Before loading: 2021-11-03T12:42:57.555875200
After loading: 2021-11-03T12:42:57.555875200
看来我的subTestDelay
方法中的condition
计算正确,但是忽略了实际花费的时间。我怀疑这是因为 benchmark
方法中的 runnable.run()
是在另一个线程上执行的,但我缺乏找到解决方案的经验。谁能指引我正确的方向?
我终于解决了这个问题!对于那些感兴趣的人,这就是我所做的。
我编辑了 subTestDelay
以接受 Supplier<Boolean> condition
而不是 boolean condition
。现在,condition.get()
的计算是定时的。这似乎是解决问题的原因(虽然我不知道为什么)。
subTestDelay
现在看起来像这样:
public static void subTestDelay(boolean log, Supplier<Boolean> condition, int delay, String message) {
String msg = "Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ");
if (log) {
Assert.assertTrue(ExtentTestManager.benchmark(() -> {
if (!condition.get()) {
tempData.failStatus();
return false;
}
return true;
}), msg.concat(message));
} else {
Assert.assertTrue(condition.get(), msg.concat(message));
}
}
benchmark
也被编辑为接受 Supplier<Boolean>
而不是 Runnable
:
public static boolean benchmark(Supplier<Boolean> supplier) {
LocalDateTime before = LocalDateTime.now();
boolean returnValue = supplier.get();
logToDocument(before, LocalDateTime.now());
return returnValue;
}
相同的测试现在产生正确的结果:
Before loading:2021-11-05T11:08:39.758627100
After loading:2021-11-05T11:08:43.953063700
Before loading:2021-11-05T11:08:45.309372500
After loading:2021-11-05T11:08:52.510232700
Before loading:2021-11-05T11:08:53.963683900
After loading:2021-11-05T11:08:56.048520300
Before loading:2021-11-05T11:08:57.233896600
After loading:2021-11-05T11:08:58.438004100
我有一个执行 Runnable
的方法,然后将它完成所花费的时间传递给另一个方法:
public static void benchmark(Runnable runnable) {
LocalDateTime before = LocalDateTime.now();
runnable.run();
logToDocument(before, LocalDateTime.now());
}
当我使用这种方法来计时网页的加载时,两个时间戳完全相同,即 LocalDateTime before = LocalDateTime.now()
和 logToDocument(before, LocalDateTime.now())
同时发生,即使我在现实中观察到每个页面加载需要几秒钟。我调用benchmark
的方法如下:
public static void subTestDelay(boolean log, boolean condition, int delay, String message) {
if (log) {
SoftAssert softAssert = new SoftAssert();
ExtentTestManager.benchmark(() -> {
if (!condition) {
tempData.failStatus();
softAssert.fail("Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ").concat(message));
}
});
softAssert.assertAll();
} else {
Assert.assertTrue(condition, "Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ").concat(message));
}
}
变量condition
,在本例中,是这样的:
public static boolean expectedPageIsLoaded(WebDriver driver, int seconds, String pageName) {
final By loadingBar = By.cssSelector("div[class*='progress']");
final Wait<WebDriver> wait = new FluentWait<>(driver).withTimeout(Duration.ofSeconds(seconds)).pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class).ignoring(NullPointerException.class);
String originalPageName = driver.findElement(By.tagName("body")).getAttribute("page-name");
if (originalPageName == null) {
originalPageName = "no previous page";
tempData.setAction(tempData.REDIRECT);
tempData.setArbitraryData(driver,tempData.TRIGGER, tempData.NAVIGATION, tempData.ORIGIN, originalPageName, tempData.DESTINATION, "user authentication");
}
ExtentTestManager.log(logger, Level.INFO, "Loading page: ".concat(pageName).concat("; Waiting a maximum of: ").concat(String.valueOf(seconds)).concat(" seconds"));
try {
startDateTime = LocalDateTime.now();
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(loadingBar));
wait.until(wd -> (GenericTestMethods.pageName(wd).equals(pageName) && wd.findElements(loadingBar).size() == 0));
endDateTime = LocalDateTime.now();
ExtentTestManager.log(logger, Level.INFO, "Page: ".concat(pageName).concat(" loaded after: ").concat(String.valueOf(Duration.between(startDateTime, endDateTime).toMillis())).concat(" milliseconds"));
return true;
} catch (TimeoutException ex) {
return false;
}
}
当我连续测试 4 个网页时,我得到了每个页面加载的正确持续时间,如您在此处所见:
12:35:36.774 [main] INFO test_classes.base.DriverInit - Loading page: user authentication; Waiting a maximum of: 180 seconds
12:35:39.902 [main] INFO test_classes.base.DriverInit - Page: user authentication loaded after: 3124 milliseconds
12:35:41.333 [main] INFO test_classes.base.DriverInit - Loading page: user_cockpit; Waiting a maximum of: 180 seconds
12:35:46.474 [main] INFO test_classes.base.DriverInit - Page: user_cockpit loaded after: 5140 milliseconds
12:35:47.947 [main] INFO test_classes.base.DriverInit - Loading page: organization_overview_time_focus; Waiting a maximum of: 180 seconds
12:35:50.013 [main] INFO test_classes.base.DriverInit - Page: organization_overview_time_focus loaded after: 2066 milliseconds
12:35:51.210 [main] INFO test_classes.base.DriverInit - Loading page: project_time_overview; Waiting a maximum of: 180 seconds
12:35:52.604 [main] INFO test_classes.base.DriverInit - Page: project_time_overview loaded after: 1393 milliseconds
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 25.446 s - in TestSuite
此反馈来自 boolean
expectedPageIsLoaded
:
startDateTime = LocalDateTime.now();
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(loadingBar));
wait.until(wd -> (GenericTestMethods.pageName(wd).equals(pageName) && wd.findElements(loadingBar).size() == 0));
endDateTime = LocalDateTime.now();
ExtentTestManager.log(logger, Level.INFO, "Page: ".concat(pageName).concat(" loaded after: ").concat(String.valueOf(Duration.between(startDateTime, endDateTime).toMillis())).concat(" milliseconds"));
然而,我从benchmark
得到的反馈是每次加载页面前后都有两个时间戳,它们总是相同的。为了说明这一点,我修改了 benchmark
以打印出 Runnable
前后的时间戳。这是我得到的:
Before loading: 2021-11-03T12:42:42.855008800
After loading: 2021-11-03T12:42:42.855008800
Before loading: 2021-11-03T12:42:51.505117900
After loading: 2021-11-03T12:42:51.505117900
Before loading: 2021-11-03T12:42:55.145636200
After loading: 2021-11-03T12:42:55.145636200
Before loading: 2021-11-03T12:42:57.555875200
After loading: 2021-11-03T12:42:57.555875200
看来我的subTestDelay
方法中的condition
计算正确,但是忽略了实际花费的时间。我怀疑这是因为 benchmark
方法中的 runnable.run()
是在另一个线程上执行的,但我缺乏找到解决方案的经验。谁能指引我正确的方向?
我终于解决了这个问题!对于那些感兴趣的人,这就是我所做的。
我编辑了 subTestDelay
以接受 Supplier<Boolean> condition
而不是 boolean condition
。现在,condition.get()
的计算是定时的。这似乎是解决问题的原因(虽然我不知道为什么)。
subTestDelay
现在看起来像这样:
public static void subTestDelay(boolean log, Supplier<Boolean> condition, int delay, String message) {
String msg = "Timeout after waiting ".concat(String.valueOf(delay)).concat(" seconds for ");
if (log) {
Assert.assertTrue(ExtentTestManager.benchmark(() -> {
if (!condition.get()) {
tempData.failStatus();
return false;
}
return true;
}), msg.concat(message));
} else {
Assert.assertTrue(condition.get(), msg.concat(message));
}
}
benchmark
也被编辑为接受 Supplier<Boolean>
而不是 Runnable
:
public static boolean benchmark(Supplier<Boolean> supplier) {
LocalDateTime before = LocalDateTime.now();
boolean returnValue = supplier.get();
logToDocument(before, LocalDateTime.now());
return returnValue;
}
相同的测试现在产生正确的结果:
Before loading:2021-11-05T11:08:39.758627100
After loading:2021-11-05T11:08:43.953063700
Before loading:2021-11-05T11:08:45.309372500
After loading:2021-11-05T11:08:52.510232700
Before loading:2021-11-05T11:08:53.963683900
After loading:2021-11-05T11:08:56.048520300
Before loading:2021-11-05T11:08:57.233896600
After loading:2021-11-05T11:08:58.438004100