我在服务器上运行JUnit测试时遇到问题。当我在我的机器上运行测试时,完全没有问题。当我在服务器上运行它时,“有时”我的所有服务器都出现故障。这意味着测试有时会在60%的尝试中通过,40%会失败。
我正在使用Mockito。我的测试开始于使用vec.at(1).SetString("Modified string");
模拟一些回复并将每个请求映射到响应,并且我正在使用vec.at(1)->SetString("Modified string");
这是线程安全的。(我的synchronizedSet上的每个修改都发生在{{1然后,我使用MessageListener
来获取特定REST端点的响应并声明一些值。
当测试失败并且我查看Stacktrace时,我看到我的一个映射(总是在同一个对象上)没有工作,并且在我的集合中这个特定请求和响应之间没有映射,当然,我获取Collections.synchronizedSet(new HashSet<>())
请求此端点。
我正在使用Jenkins自动编译和运行测试,我得到失败的堆栈跟踪或我的Printlns,否则,没有可用的调试工具。
这听起来像是一个并发问题。我的意思是,似乎我的集合没有时间在synchronized(mySynchronizedSet){....}
请求端点之前做好准备。我已经测试了锁,睡眠和另一个简单的java并发解决方案,但它们没有帮助,这个问题的概率特性使我陷入了死胡同。
每一个想法都会受到赞赏。
答案 0 :(得分:2)
根据你所说的话,你似乎对3件具体案件的工作方式有误解。
而且最明显的是,我为甚至提到这一点而道歉,但我之所以这样做的原因是因为我正在收集你还在学习(如果你还没有学习,我会道歉!并且同样的速度,你甚至可能没有用它的方式暗示它,所以如果我误读了对不起):你没有和Jenkins一起编译,你正在编译你机器上的任何JDK风格(无论是Oracle, Apple,GCJ等)。 Jenkins是一款自动化工具,可帮助您完成定期运行的繁琐工作。我只提到这个,因为我知道现在的大学生在开放课程中使用IDE,无法区分编译器,运行时和IDE。
通过使用线程安全库,它不会自动使您所做的一切本身都是线程安全的。请考虑以下示例:
final Map<Object, Object> foo = Collections.synchronizedMap(new HashMap <>());
final String bar = "bar";
foo.put(bar, new Object());
new Thread(new Runnable(){
@Override
public void run(){
foo.remove(bar);
}
}).start();
new Thread(new Runnable(){
@Override
public void run(){
if(foo.containsKey(bar)){
foo.get(bar).toString();
}
}
}).start();
无法保证第二个线程对#get(Object)
的调用将在第一个线程调用#remove(Object)
之前或之后发生。考虑一下
#containsKey(Object)
#remove(Object)
#get(Object)
此时,get(Object)
的返回值将为null,对#toString()
的调用将导致NullPointerDereference。你说你正在使用Set,所以这个使用Map的例子主要是为了证明一点:仅仅因为你使用的是线程安全集合,并不会自动使你做的所有线程都安全。我想你正在用你的集合做的事情与这种行为相匹配,但是没有代码片段,我只能推测。
你应该小心编写JUnits的方法。正确的JUnit测试就是所谓的“白盒”测试。换句话说,您了解测试中发生的所有事情,并且您明确地测试了仅在被测单元中发生的所有事情。被测单元只是您调用的方法 - 不您的方法调用的方法,只有方法本身。这意味着,您需要一个好的模拟框架,并模拟您的被测单元可能调用的任何后续方法调用。一些好的框架是JMockit,Mockito + PowerMock等。
这一点的重要性在于您的测试应该测试您的孤立代码。如果您允许网络访问,磁盘访问等,那么您的测试可能会失败,并且可能与您编写的代码无关,并且它会完全使测试无效。在您的情况下,您提示网络访问,因此请假设您的交换机/路由器/等存在吞吐量问题,或者您的NIC缓冲区已满,并且无法快速处理您的程序尝试执行的操作。当然,失败并不好,应该修复,但应该在“黑盒”测试中进行测试。您的测试应该编写,以便消除这些问题,并且只在测试单元的特定方法中测试您的代码,而不是其他任何内容。
编辑:我实际上发布了一个关于可能相关的白盒测试的单独讨论的答案:Is using a test entity manager a legitamate testing practice?