Multithreading 是否有一种方法可以在每个测试类之后报告延迟线程?(junit/maven)
在写得很糟糕的遗留代码库中,单元测试调用的代码会激发从未停止过的线程。在大多数情况下,它没有效果,但在某些情况下,它会大大降低构建速度,在其他情况下,它会在构建过程中导致同一项目中的测试之间产生完全不清楚的副作用:例如,测试A启动线程,然后B在同一JVM中运行,并以某种未定义的方式中断(修复方法是停止该线程) 是否有一些工具可以与junit结合使用,以便在每个测试(或一个类中的一组测试)结束时,如果有任何线程仍在运行,它会使测试失败 这将允许我们快速识别和修复所有现有案例,但也会阻止以这种方式编写新的测试。Multithreading 是否有一种方法可以在每个测试类之后报告延迟线程?(junit/maven),multithreading,unit-testing,junit4,maven-surefire-plugin,Multithreading,Unit Testing,Junit4,Maven Surefire Plugin,在写得很糟糕的遗留代码库中,单元测试调用的代码会激发从未停止过的线程。在大多数情况下,它没有效果,但在某些情况下,它会大大降低构建速度,在其他情况下,它会在构建过程中导致同一项目中的测试之间产生完全不清楚的副作用:例如,测试A启动线程,然后B在同一JVM中运行,并以某种未定义的方式中断(修复方法是停止该线程) 是否有一些工具可以与junit结合使用,以便在每个测试(或一个类中的一组测试)结束时,如果有任何线程仍在运行,它会使测试失败 这将允许我们快速识别和修复所有现有案例,但也会阻止以这种方式编
公共类FailOnLingeringThreadsTestBase
public class FailOnLingeringThreadsTestBase
{
private static Set<Thread> threadsBefore;
@BeforeClass
public static void takePhoto()
{
threadsBefore = Collections.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@AfterClass
public static void spotTheDiffs()
{
Set<Thread> threadsAfter = Thread.getAllStackTraces().keySet();
if (threadsAfter.size() != threadsBefore.size())
{
threadsAfter.removeAll(threadsBefore);
throw new IllegalStateException("Lingering threads in test: " + threadsAfter);
}
}
}
{
私有静态设置线程;
@课前
公众静态照片
{
threadsBefore=Collections.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@下课
公共静态void spotTheDiffs()
{
设置threadsAfter=Thread.getAllStackTraces().keySet();
如果(threadsAfter.size()!=threadsBefore.size())
{
移除所有螺纹后的螺纹(之前的螺纹);
抛出新的IllegalStateException(“测试中的延迟线程:+threadsAfter”);
}
}
}
公共类故障在线处理线程数据库
{
私有静态设置线程;
@课前
公众静态照片
{
threadsBefore=Collections.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@下课
公共静态void spotTheDiffs()
{
设置threadsAfter=Thread.getAllStackTraces().keySet();
如果(threadsAfter.size()!=threadsBefore.size())
{
移除所有螺纹后的螺纹(之前的螺纹);
抛出新的IllegalStateException(“测试中的延迟线程:+threadsAfter”);
}
}
}
显然,Maven/Surefire允许您使用配置钩住侦听器!通过将检查作为org.junit.runner.notification.RunListener的一部分实现,这是一种垂直集成检查的现实方法
以下是我现在使用的:
public class FailOnLingeringThreadsRunListener extends org.junit.runner.notification.RunListener
{
private Set<Thread> threadsBefore;
@Override
public synchronized void testRunStarted(Description description) throws Exception
{
threadsBefore = takePhoto();
super.testRunStarted(description);
}
@Override
public synchronized void testRunFinished(Result result) throws Exception
{
super.testRunFinished(result);
Set<Thread> threadsAfter = spotTheDiffs(threadsBefore);
// only complain on success, as failures may have caused cleanup code not to run...
if (result.wasSuccessful())
{
if (!threadsAfter.isEmpty())
throw new IllegalStateException("Lingering threads in test: " + threadsAfter);
}
}
public static Set<Thread> takePhoto()
{
return Collections.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@AfterClass
public static Set<Thread> spotTheDiffs(Set<Thread> threadsBefore)
{
Set<Thread> threadsAfter = Thread.getAllStackTraces().keySet();
if (threadsAfter.size() != threadsBefore.size())
{
threadsAfter.removeAll(threadsBefore);
return Collections.unmodifiableSet(threadsAfter);
}
return Collections.emptySet();
}
}
公共类FailonLingeringThreadsRunliner扩展org.junit.runner.notification.RunListener
{
私有设置线程之前;
@凌驾
public synchronized void testRunStarted(描述)引发异常
{
threadsBefore=takePhoto();
super.testRunStarted(说明);
}
@凌驾
公共同步的void testRunFinished(结果)引发异常
{
super.testRunFinished(结果);
设置threadsAfter=SpottheDiff(threadsBefore);
//只抱怨成功,因为失败可能导致清理代码无法运行。。。
if(result.wasuccessful())
{
如果(!threadsAfter.isEmpty())
抛出新的IllegalStateException(“测试中的延迟线程:+threadsAfter”);
}
}
公共静态设置takePhoto()
{
返回集合.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@下课
公共静态设置SPOTTheDiff(设置线程之前)
{
设置threadsAfter=Thread.getAllStackTraces().keySet();
如果(threadsAfter.size()!=threadsBefore.size())
{
移除所有螺纹后的螺纹(之前的螺纹);
返回集合。不可修改集(threadsAfter);
}
返回集合;
}
}
以下是我如何在构建中启用它:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<properties>
<property>
<name>listener</name>
<value>testutil.FailOnLingeringThreadsRunListener</value>
</property>
</properties>
</configuration>
</plugin>
...
org.apache.maven.plugins
maven surefire插件
听众
testutil.failonlingeringthreadsrunliner
...
显然,Maven/Surefire允许您使用配置钩住侦听器!通过将检查作为org.junit.runner.notification.RunListener的一部分实现,这是一种垂直集成检查的现实方法
以下是我现在使用的:
public class FailOnLingeringThreadsRunListener extends org.junit.runner.notification.RunListener
{
private Set<Thread> threadsBefore;
@Override
public synchronized void testRunStarted(Description description) throws Exception
{
threadsBefore = takePhoto();
super.testRunStarted(description);
}
@Override
public synchronized void testRunFinished(Result result) throws Exception
{
super.testRunFinished(result);
Set<Thread> threadsAfter = spotTheDiffs(threadsBefore);
// only complain on success, as failures may have caused cleanup code not to run...
if (result.wasSuccessful())
{
if (!threadsAfter.isEmpty())
throw new IllegalStateException("Lingering threads in test: " + threadsAfter);
}
}
public static Set<Thread> takePhoto()
{
return Collections.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@AfterClass
public static Set<Thread> spotTheDiffs(Set<Thread> threadsBefore)
{
Set<Thread> threadsAfter = Thread.getAllStackTraces().keySet();
if (threadsAfter.size() != threadsBefore.size())
{
threadsAfter.removeAll(threadsBefore);
return Collections.unmodifiableSet(threadsAfter);
}
return Collections.emptySet();
}
}
公共类FailonLingeringThreadsRunliner扩展org.junit.runner.notification.RunListener
{
私有设置线程之前;
@凌驾
public synchronized void testRunStarted(描述)引发异常
{
threadsBefore=takePhoto();
super.testRunStarted(说明);
}
@凌驾
公共同步的void testRunFinished(结果)引发异常
{
super.testRunFinished(结果);
设置threadsAfter=SpottheDiff(threadsBefore);
//只抱怨成功,因为失败可能导致清理代码无法运行。。。
if(result.wasuccessful())
{
如果(!threadsAfter.isEmpty())
抛出新的IllegalStateException(“测试中的延迟线程:+threadsAfter”);
}
}
公共静态设置takePhoto()
{
返回集合.unmodifiableSet(Thread.getAllStackTraces().keySet());
}
@下课
公共静态设置SPOTTheDiff(设置线程之前)
{
设置threadsAfter=Thread.getAllStackTraces().keySet();
如果(threadsAfter.size()!=threadsBefore.size())
{
移除所有螺纹后的螺纹(之前的螺纹);
返回集合。不可修改集(threadsAfter);
}
返回集合;
}
}
以下是我如何在构建中启用它:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<properties>
<property>
<name>listener</name>
<value>testutil.FailOnLingeringThreadsRunListener</value>
</property>
</properties>
</configuration>
</plugin>
...
org.apache.maven.plugins
maven surefire插件
听众
testutil.failonlingeringthreadsrunliner