Skip to content

Commit

Permalink
Merge pull request #93 from radarsh/feature/configure-testlogger-for-…
Browse files Browse the repository at this point in the history
…each-task

Configure testlogger for each task
  • Loading branch information
radarsh committed Oct 28, 2018
2 parents 7016d54 + f84d5cf commit b304d43
Show file tree
Hide file tree
Showing 20 changed files with 336 additions and 56 deletions.
17 changes: 11 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
- image: circleci/openjdk:8-jdk
working_directory: ~/repo
environment:
JVM_OPTS: -Xmx3200m
JVM_OPTS: -Xmx4096m
TERM: dumb
steps:
- checkout
Expand All @@ -23,17 +23,22 @@ jobs:
key: v1-dependencies-{{ checksum "build.gradle" }}
- run:
name: Run tests
command: GRADLE_OPTS="-Xms256m -Xmx1024m" ./gradlew clean test --no-daemon
command: GRADLE_OPTS="-Xms256m -Xmx2048m" ./gradlew build --no-daemon
- run:
name: Code coverage
command: GRADLE_OPTS="-Xms256m -Xmx1024m" ./gradlew jacocoTestReport coveralls --no-daemon
- run:
name: Save reports
command: |
mkdir -p ~/results
mkdir -p ~/reports
find . -type f -regex "./build/test-results/.*xml" -exec cp {} ~/results \;
cp -r build/reports/tests/test/* ~/reports
mkdir -p ~/results/unit
mkdir -p ~/reports/unit
find . -type f -regex "./build/test-results/test/.*xml" -exec cp {} ~/results/unit \;
cp -r build/reports/tests/test/* ~/reports/unit
mkdir -p ~/results/functional
mkdir -p ~/reports/functional
find . -type f -regex "./build/test-results/functionalTest/.*xml" -exec cp {} ~/results/functional \;
cp -r build/reports/tests/functionalTest/* ~/reports/functional
when: always
- store_test_results:
path: ~/results
Expand Down
67 changes: 53 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,59 @@ apply plugin: 'com.adarshr.test-logger'

## Configuration

All the below configuration settings can either be specified in `build.gradle` file or be set at runtime using system
properties or both. For instance, we could have `theme` set to `mocha` in `build.gradle` file but it can be overridden
to be `standard` at runtime by using `-Dtestlogger.theme=standard` on the command line. Since they're system properties
we have a number of ways of specifying them including `JAVA_OPTS` and `gradle.properties`.

The convention used for determining the name of the system property is `testlogger.<configuration setting>`.

- [Switch themes](#switch-themes)
- [Hide exceptions](#hide-exceptions)
- [Define slow threshold](#define-slow-threshold)
- [Hide summary](#hide-summary)
- [Show standard streams](#show-standard-streams)
- [Filter standard streams](#filter-standard-streams)
- [Filter test results](#filter-test-results)
The plugin registers an extension called `testlogger` at project level as well as for each task of type
[`Test`](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html).

The following shows the complete default configuration applied when you configure nothing.

```groovy
testlogger {
theme 'standard'
showExceptions true
slowThreshold 2000
showSummary true
showPassed true
showSkipped true
showFailed true
showStandardStreams false
showPassedStandardStreams true
showSkippedStandardStreams true
showFailedStandardStreams true
}
```

### Project vs task level configuration

Settings configured at the project level can be overridden by redefining them at task level. Settings
not defined at task level will inherit project level values. Consider the below configuration.

```groovy
testlogger {
theme 'mocha' // project level
slowThreshold 5000
}
test {
testlogger {
theme 'standard-parallel' // task level
}
}
```

In the above example, the effective theme will be `standard-parallel` and `slowThreshold` will be `5000` whereas rest of
the settings will retain their default values.

### Overriding settings at runtime

All the above settings can either be specified in `build.gradle` or be set at runtime using system properties or both.
For instance, we could have `theme` set to `mocha` in the build file but it can be overridden to be `standard` at runtime
by using `-Dtestlogger.theme=standard` on the command line. Since they are system properties we have a number of ways of
specifying them including `JAVA_OPTS` and `gradle.properties`.

- The convention used for determining the name of the system property is `testlogger.<configuration setting>`.
- System property overrides will be applied after combining task and project level settings.
- Specifying a system property override will apply the same setting for all tasks, regardless of any configuration
defined in the build file.

### Switch themes

Expand Down
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
skip_tags: true
test_script:
- gradlew clean test --no-daemon
- gradlew build --no-daemon
after_test:
- ps: ./uploadTestResults.ps1
build: off
artifacts:
- path: build/reports/tests/test/**/*.*
- path: build/reports/tests/functionalTest/**/*.*
43 changes: 37 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,11 @@ sourceSets {
groovy {
srcDir 'src/test-functional/groovy'
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
}

test {
testClassesDirs += sourceSets.functionalTest.output.classesDirs
classpath += sourceSets.functionalTest.runtimeClasspath
systemProperty 'file.encoding', 'UTF-8'
}

dependencies {
compile gradleApi()
compile localGroovy()
Expand Down Expand Up @@ -76,3 +71,39 @@ idea {
testSourceDirs += file('src/test-functional/groovy')
}
}


test {
testClassesDirs += sourceSets.functionalTest.output.classesDirs
classpath += sourceSets.functionalTest.runtimeClasspath
systemProperty 'file.encoding', 'UTF-8'

testlogger {
theme 'mocha'
}

exclude 'com/adarshr/gradle/testlogger/functional/**'
}

task functionalTest(type: Test) {
maxParallelForks = 2
testClassesDirs = sourceSets.functionalTest.output.classesDirs
classpath = sourceSets.test.runtimeClasspath + sourceSets.functionalTest.runtimeClasspath
systemProperty 'file.encoding', 'UTF-8'
minHeapSize '128m'
maxHeapSize '512m'

jacoco {
append = true
destinationFile = file("${buildDir}/jacoco/test.exec")
}

testlogger {
theme 'standard-parallel'
}

include 'com/adarshr/gradle/testlogger/functional/**'
}

tasks.build.dependsOn 'functionalTest'
tasks.functionalTest.dependsOn 'pluginUnderTestMetadata', 'testClasses'
2 changes: 1 addition & 1 deletion gradle/coverage.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
jacoco {
toolVersion '0.7.9'
toolVersion '0.8.2'
}

jacocoTestReport {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import static com.adarshr.gradle.testlogger.theme.ThemeType.STANDARD
import static org.gradle.api.logging.configuration.ConsoleOutput.Plain

@CompileStatic
@SuppressWarnings("GroovyUnusedDeclaration")
class TestLoggerExtension {

ThemeType theme = STANDARD
Expand All @@ -26,19 +27,38 @@ class TestLoggerExtension {

private final ConsoleOutput consoleType
private final Map<String, String> overrides
private Set<String> configuredProperties = []

TestLoggerExtension(Project project, Map<String, String> overrides) {
this.consoleType = project.gradle.startParameter.consoleOutput
this.theme = project.gradle.startParameter.consoleOutput == Plain ? PLAIN : this.theme
this.overrides = overrides
}

private TestLoggerExtension(TestLoggerExtension source) {
this.theme = source.theme
this.showExceptions = source.showExceptions
this.slowThreshold = source.slowThreshold
this.showSummary = source.showSummary
this.showStandardStreams = source.showStandardStreams
this.showPassedStandardStreams = source.showPassedStandardStreams
this.showSkippedStandardStreams = source.showSkippedStandardStreams
this.showFailedStandardStreams = source.showFailedStandardStreams
this.showPassed = source.showPassed
this.showSkipped = source.showSkipped
this.showFailed = source.showFailed
this.consoleType = source.consoleType
this.overrides = source.overrides
this.configuredProperties = source.configuredProperties
}

void setTheme(String theme) {
if (consoleType == Plain) {
return
}

this.theme = ThemeType.fromName(theme)
this.configuredProperties << 'theme'
}

void setTheme(ThemeType theme) {
Expand All @@ -47,6 +67,71 @@ class TestLoggerExtension {
}

this.theme = theme
this.configuredProperties << 'theme'
}

void setShowExceptions(boolean showExceptions) {
this.showExceptions = showExceptions
this.configuredProperties << 'showExceptions'
}

void setSlowThreshold(long slowThreshold) {
this.slowThreshold = slowThreshold
this.configuredProperties << 'slowThreshold'
}

void setShowSummary(boolean showSummary) {
this.showSummary = showSummary
this.configuredProperties << 'showSummary'
}

void setShowStandardStreams(boolean showStandardStreams) {
this.showStandardStreams = showStandardStreams
this.configuredProperties << 'showStandardStreams'
}

void setShowPassedStandardStreams(boolean showPassedStandardStreams) {
this.showPassedStandardStreams = showPassedStandardStreams
this.configuredProperties << 'showPassedStandardStreams'
}

void setShowSkippedStandardStreams(boolean showSkippedStandardStreams) {
this.showSkippedStandardStreams = showSkippedStandardStreams
this.configuredProperties << 'showSkippedStandardStreams'
}

void setShowFailedStandardStreams(boolean showFailedStandardStreams) {
this.showFailedStandardStreams = showFailedStandardStreams
this.configuredProperties << 'showFailedStandardStreams'
}

void setShowPassed(boolean showPassed) {
this.showPassed = showPassed
this.configuredProperties << 'showPassed'
}

void setShowSkipped(boolean showSkipped) {
this.showSkipped = showSkipped
this.configuredProperties << 'showSkipped'
}

void setShowFailed(boolean showFailed) {
this.showFailed = showFailed
this.configuredProperties << 'showFailed'
}

TestLoggerExtension combine(TestLoggerExtension another) {
def copyOfThis = new TestLoggerExtension(this)

copyOfThis.properties.findAll { Object property, Object value ->
!copyOfThis.configuredProperties.contains(property) && property != 'class'
}.each { Object property, Object value ->
copyOfThis.setProperty(property as String, another.properties[property])
}

copyOfThis.configuredProperties.clear()

copyOfThis
}

void applyOverrides() {
Expand All @@ -68,6 +153,7 @@ class TestLoggerExtension {
String method = Enum.isAssignableFrom(type) ? 'fromName' : 'valueOf'

setProperty(name, type.invokeMethod(method, overrides[name]))
this.configuredProperties << name
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,38 @@ class TestLoggerPlugin implements Plugin<Project> {

@Override
void apply(Project project) {
project.extensions.create('testlogger', TestLoggerExtension, project, overrides)
createExtensions(project)

project.afterEvaluate {
project.tasks.withType(Test).each { test ->
project.testlogger.applyOverrides()
def testExtension = test.extensions.testlogger as TestLoggerExtension
def projectExtension = test.project.extensions.testlogger as TestLoggerExtension
def combinedExtension = testExtension.combine(projectExtension)

combinedExtension.applyOverrides()

test.testLogging.lifecycle.events = []

def testLogger = new TestLoggerWrapper(project, test)
def testLogger = new TestLoggerWrapper(project, test, combinedExtension)

test.addTestListener(testLogger)
test.addTestOutputListener(testLogger)
}
}
}

private static void createExtensions(Project project) {
project.extensions.create('testlogger', TestLoggerExtension, project, overrides)
project.tasks.withType(Test).each { task ->
task.extensions.create('testlogger', TestLoggerExtension, project, overrides)
}
project.tasks.whenTaskAdded { task ->
if (task instanceof Test) {
task.extensions.create('testlogger', TestLoggerExtension, project, overrides)
}
}
}

private static Map<String, String> getOverrides() {
System.properties.findAll { key, value ->
key.startsWith 'testlogger.'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.adarshr.gradle.testlogger.logger

import com.adarshr.gradle.testlogger.TestDescriptorWrapper
import com.adarshr.gradle.testlogger.TestResultWrapper
import groovy.transform.CompileStatic
import groovy.transform.InheritConstructors

@InheritConstructors
@CompileStatic
class ParallelTestLogger extends TestLoggerAdapter {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.adarshr.gradle.testlogger.logger

import com.adarshr.gradle.testlogger.TestDescriptorWrapper
import com.adarshr.gradle.testlogger.TestResultWrapper
import groovy.transform.CompileStatic
import groovy.transform.InheritConstructors

@InheritConstructors
@CompileStatic
class SequentialTestLogger extends TestLoggerAdapter {

private final Map<String, Boolean> suites = [:]
Expand Down
Loading

0 comments on commit b304d43

Please sign in to comment.