有谁知道 Kotlin 是否存在一个好的测试覆盖工具(最好是 Gradle 插件)?我对 JaCoCo 进行了一些研究,但它似乎并不可靠地支持 Kotlin。
最佳答案
根据要求,这是一个使用 Kotlin 的 build.gradle 示例,它结合了 Jacoco 和 Sonarqube 的集成,生成了一个 jar 和源代码,并与 Detekt 绑定(bind)以进行静态分析。
我不得不手动添加一些东西,因为我的工作构建已经通过内部插件应用了 jacoco。
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.10'
id 'org.jetbrains.kotlin.plugin.spring' version '1.2.10'
id 'org.springframework.boot' version '1.5.9.RELEASE'
id 'io.spring.dependency-management' version '1.0.4.RELEASE'
id 'io.gitlab.arturbosch.detekt' version '1.0.0.RC6'
id "org.sonarqube" version "2.6.2".
}
apply plugin: 'jacoco'
ext {
springBootVersion = '1.5.9.RELEASE'
springCloudVersion = 'Dalston.SR4'
kotlinVersion = '1.2.10'
detektVersion = '1.0.0.RC6'.
}
//======================= Project Info =============================================
group = 'group'
version = '0.14'
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-starter- parent:$springBootVersion")
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
}
}
repositories {
jcenter()
}
//======================= Dependencies =============================================
dependencies {
// Version MUST be explicitly set here or else dependent projects will not be able to build as Gradle will not know
// what version to use
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
compile 'org.springframework.boot:spring-boot-starter-web'
compile('org.springframework.ws:spring-ws-support') {
exclude(module: 'javax.mail')
}
compile 'org.springframework.boot:spring-boot-starter-actuator'
// Spring security
compile 'org.springframework.security:spring-security-web'
compile 'org.springframework.security:spring-security-config'
compile 'javax.servlet:javax.servlet-api'
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
compile('org.apache.httpcomponents:httpclient')
compile 'com.nimbusds:nimbus-jose-jwt:4.23'
}
//======================= Tasks =============================================
defaultTasks 'build'
tasks.bootRepackage.enabled = false
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = 1.8
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
compileJava.options.encoding = 'UTF-8'
test.testLogging.exceptionFormat = 'full'
// ********************************
ext.coverageExclusions = [
// Configuration
'com.bns.pm.config.*',
// data classes
'com.bns.pm.domain.*',
// Account Service domain objects
'com.bns.pm.account.domain.*',
// Other items
'com.bns.pm.exceptions.DataPowerFaultException.Companion',
'com.bns.pm.controllers.ServiceExceptionHandler*',
'com.bns.pm.service.callback.DPWebServiceMessageCallback',
'com.bns.pm.service.HealthCheckService',
'com.bns.pm.util.SystemPropertiesUtilKt',
]
check.dependsOn jacocoTestCoverageVerification
jacocoTestCoverageVerification {
violationRules {
rule {
element = 'CLASS'
// White list
excludes = coverageExclusions
limit {
minimum = 0.70
}
}
}
}
jacocoTestReport {
description 'Generates Code coverage report. Fails build if it does not meet minimum coverage.'
reports {
xml.enabled = true //XML required by coveralls and for the below coverage checks
html.enabled = true
csv.enabled = false
}
def reportExclusions = coverageExclusions.collect {
it.replaceAll('\\.', '/') + (it.endsWith('*') ? '' : '*')
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it, excludes: reportExclusions)
})
}
}
test.finalizedBy jacocoTestReport
afterEvaluate {
sonarqube {
properties {
property 'sonar.jacoco.reportPath', "${buildDir}/jacoco/test.exec"
property "detekt.sonar.kotlin.config.path", "detekt.yml"
property 'sonar.java.binaries', "$projectDir/build/classes/kotlin"
property 'sonar.coverage.exclusions', coverageExclusions.collect {
'**/' + it.replaceAll('\\.', '/') + (it.endsWith('*') ? '' : '*')
}
}
}
}
// Ensure source code is published to Artifactory
// Have to redefine publishing with new name as Accelerator Plugin already defined mavenJava
task sourceJar(type: Jar) {
from sourceSets.main.allSource
classifier 'sources'
}
publishing {
publications {
mavenJava2(MavenPublication) {
from components.java
artifact(sourceJar) {
classifier = 'sources'
}
}
}
}
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = "${artifactory_projectRepoKey}"
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
defaults {
publications('mavenJava2')
}
}
}
artifactoryPublish {
dependsOn jar
}
detekt {
version = detektVersion
profile("main") {
input = "$projectDir/src"
config = "$projectDir/detekt.yml"
filters = ".*/resources/.*,.*/tmp/.*"
output = "$project.buildDir/reports/detekt"
}
}
check.dependsOn detektCheck
关于gradle - Kotlin 测试覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48220460/
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel