我想在多个线程中运行相同的 Cucumber 测试。更具体地说,我有一组功能,在一个线程中运行这些功能效果很好。我使用 JSON 格式化程序记录每个步骤的运行时间。现在我想做负载测试。我更关心多线程环境下每个特性/步骤的运行时间。所以我创建了多个线程,每个线程都运行在同一个特性集上。每个线程都有自己的 JSON 报告。这在理论上可能吗?
由于某些项目设置原因,我无法使用 JUnit 运行器。所以我不得不求助于 CLI 方式:
long threadId = Thread.currentThread().getId();
String jsonFilename = String.format("json:run/cucumber%d.json", threadId);
String argv[] = new String[]{
"--glue",
"com.some.package",
"--format",
jsonFilename,
"d:\\features"};
// Do not call Main.run() directly. It has a System.exit() call at the end.
// Main.run(argv, Thread.currentThread().getContextClassLoader());
// Copied the same code from Main.run().
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env("cucumber-jvm"), argv);
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
runtime.writeStepdefsJson();
runtime.run();
我尝试为每个 Cucumber 运行创建一个单独的线程。问题是,只有一个线程具有有效的 JSON 报告。所有其他线程只创建空的 JSON 文件。这是 Cucumber 设计的还是我遗漏了什么?
最佳答案
我们使用出色的 GPars library 研究了 Gradle 和 Groovy 下的多线程 Cucumber 测试。 .我们有 650 个 UI 测试并且还在增加。
我们在多线程中运行 cucumber-JVM 时没有遇到任何明显的问题,但多线程也没有像我们希望的那样提高性能。
我们在单独的线程中运行每个功能文件。有一些细节需要注意,比如将来自不同线程的 cucumber 报告拼接在一起,并确保我们的步骤代码是线程安全的。我们有时需要在步骤之间存储值,因此我们使用以线程 id 为键的 concurrentHashMap 来存储这种数据:
class ThreadedStorage {
static private ConcurrentHashMap multiThreadedStorage = [:]
static private String threadSafeKey(unThreadSafeKey) {
def threadId = Thread.currentThread().toString()
"$threadId:$unThreadSafeKey"
}
static private void threadSafeStore(key, value) {
multiThreadedStorage[threadSafeKey(key)] = value
}
def static private threadSafeRetrieve(key) {
multiThreadedStorage[threadSafeKey(key)]
}
}
下面是使用 GPars 运行多线程测试的 Gradle 任务代码的要点:
def group = new DefaultPGroup(maxSimultaneousThreads())
def workUnits = features.collect { File featureFile ->
group.task {
try {
javaexec {
main = "cucumber.api.cli.Main"
...
args = [
...
'--plugin', "json:$unitReportDir/${featureFile.name}.json",
...
'--glue', 'src/test/groovy/steps',
"path/to/$featureFile"
]
}
} catch (ExecException e) {
++noOfErrors
stackTraces << [featureFile, e.getStackTrace()]
}
}
}
// ensure all tests have run before reporting and finishing gradle task
workUnits*.join()
我们发现我们需要以执行时间的倒序呈现特征文件以获得最佳结果。
结果是在 i5 CPU 上有 30% 的改进,同时线程数超过了 4 个,这有点令人失望。
我认为线程对于我们硬件上的多线程来说太重了。超过一定数量的线程时,CPU 缓存未命中过多。
使用像 Amazon SQS 这样的线程安全工作队列在不同实例上同时运行现在看来是一个很好的前进方向,尤其是因为它不会遇到线程安全问题(至少在测试框架方面不会)。
由于工作场所的安全限制,我们在 i7 硬件上测试这种多线程方法并非易事,但我很想知道与具有更大 CPU 缓存和更多物理内核的 i7 相比如何。
关于java - Cucumber-jvm线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25005057/
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/