Browse Source
- Look for JUnit test symbols, and add JUnit automatically - Look for Spock test symbols, and add Spock automatically - Based on what test libraries were used, invoke relevant embedded testers and accumulate results - Make it so that multiple testers can be invoked through a single 'test' command - Print out total results and write out detailed trace errors in results.txt - Update based on the new artifact resolution mechanismpull/69/head
26 changed files with 990 additions and 12 deletions
@ -0,0 +1,264 @@
@@ -0,0 +1,264 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.command; |
||||
|
||||
import groovy.lang.GroovyObject; |
||||
import joptsimple.OptionSet; |
||||
import org.apache.ivy.util.FileUtil; |
||||
import org.springframework.boot.cli.Log; |
||||
import org.springframework.boot.cli.command.tester.Failure; |
||||
import org.springframework.boot.cli.command.tester.TestResults; |
||||
import org.springframework.boot.cli.compiler.GroovyCompiler; |
||||
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.PrintWriter; |
||||
import java.net.URL; |
||||
import java.util.ArrayList; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Scanner; |
||||
import java.util.Set; |
||||
import java.util.logging.Level; |
||||
|
||||
/** |
||||
* Invokes testing for autocompiled scripts |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
public class TestCommand extends OptionParsingCommand { |
||||
|
||||
private TestOptionHandler testOptionHandler; |
||||
|
||||
public TestCommand() { |
||||
super("test", "Test a groovy script", new TestOptionHandler()); |
||||
this.testOptionHandler = (TestOptionHandler)this.getHandler(); |
||||
} |
||||
|
||||
@Override |
||||
public String getUsageHelp() { |
||||
return "[options] <files>"; |
||||
} |
||||
|
||||
public TestResults getResults() { |
||||
return testOptionHandler.results; |
||||
} |
||||
|
||||
private static class TestGroovyCompilerConfiguration implements GroovyCompilerConfiguration { |
||||
@Override |
||||
public boolean isGuessImports() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isGuessDependencies() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public String getClasspath() { |
||||
return ""; |
||||
} |
||||
|
||||
public Level getLogLevel() { |
||||
return Level.INFO; |
||||
} |
||||
} |
||||
|
||||
private static class TestOptionHandler extends OptionHandler { |
||||
|
||||
private final GroovyCompiler compiler; |
||||
|
||||
private TestResults results; |
||||
|
||||
public TestOptionHandler() { |
||||
TestGroovyCompilerConfiguration configuration = new TestGroovyCompilerConfiguration(); |
||||
this.compiler = new GroovyCompiler(configuration); |
||||
if (configuration.getLogLevel().intValue() <= Level.FINE.intValue()) { |
||||
System.setProperty("groovy.grape.report.downloads", "true"); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected void run(OptionSet options) throws Exception { |
||||
List<?> nonOptionArguments = options.nonOptionArguments(); |
||||
|
||||
Set<File> testerFiles = new HashSet<File>(); |
||||
File[] files = getFileArguments(nonOptionArguments, testerFiles); |
||||
|
||||
/* |
||||
* Need to compile the code twice: The first time automatically |
||||
* pulls in autoconfigured libraries including test tools. Then |
||||
* the compiled code can be scanned to see what libraries were |
||||
* activated. Then it can be recompiled, with appropriate tester |
||||
* groovy scripts included in the same classloading context. Then |
||||
* the testers can be fetched and invoked through reflection against |
||||
* the composite AST. |
||||
*/ |
||||
// Compile - Pass 1
|
||||
Object[] sources = this.compiler.sources(files); |
||||
|
||||
boolean testing = false; |
||||
try { |
||||
check("org.junit.Test", sources); |
||||
testerFiles.add(locateSourceFromUrl("junit", "testers/junit.groovy")); |
||||
testing = true; |
||||
} catch (ClassNotFoundException e) { |
||||
} |
||||
|
||||
try { |
||||
check("spock.lang.Specification", sources); |
||||
testerFiles.add(locateSourceFromUrl("spock", "testers/spock.groovy")); |
||||
testing = true; |
||||
} catch (ClassNotFoundException e) { |
||||
} |
||||
|
||||
if (testing) { |
||||
testerFiles.add(locateSourceFromUrl("tester", "testers/tester.groovy")); |
||||
} |
||||
|
||||
// Compile - Pass 2 - with appropriate testers added in
|
||||
files = getFileArguments(nonOptionArguments, testerFiles); |
||||
sources = this.compiler.sources(files); |
||||
|
||||
|
||||
if (sources.length == 0) { |
||||
throw new RuntimeException("No classes found in '" + files + "'"); |
||||
} |
||||
|
||||
List<Class<?>> testers = new ArrayList<Class<?>>(); |
||||
|
||||
// Extract list of compiled classes
|
||||
List<Class<?>> compiled = new ArrayList<Class<?>>(); |
||||
for (Object source : sources) { |
||||
if (source.getClass() == Class.class) { |
||||
Class<?> sourceClass = (Class<?>)source; |
||||
if (sourceClass.getSuperclass().getName().equals("AbstractTester")) { |
||||
testers.add(sourceClass); |
||||
} else { |
||||
compiled.add((Class<?>)source); |
||||
} |
||||
} |
||||
} |
||||
|
||||
this.results = new TestResults(); |
||||
|
||||
for (Class<?> tester : testers) { |
||||
GroovyObject obj = (GroovyObject)tester.newInstance(); |
||||
this.results.add((TestResults)obj.invokeMethod("findAndTest", compiled)); |
||||
} |
||||
|
||||
printReport(this.results); |
||||
} |
||||
|
||||
private File locateSourceFromUrl(String name, String path) { |
||||
try { |
||||
File file = File.createTempFile(name, ".groovy"); |
||||
file.deleteOnExit(); |
||||
FileUtil.copy(getClass().getClassLoader().getResourceAsStream(path), file, null); |
||||
return file; |
||||
} |
||||
catch (IOException ex) { |
||||
throw new IllegalStateException("Could not create temp file for source: " |
||||
+ name); |
||||
} |
||||
} |
||||
|
||||
private Class<?> check(String className, Object[] sources) throws ClassNotFoundException { |
||||
Class<?> classToReturn = null; |
||||
ClassNotFoundException classNotFoundException = null; |
||||
for (Object source : sources) { |
||||
try { |
||||
classToReturn = ((Class<?>)source).getClassLoader().loadClass(className); |
||||
} catch (ClassNotFoundException e) { |
||||
classNotFoundException = e; |
||||
} |
||||
} |
||||
if (classToReturn != null) { |
||||
return classToReturn; |
||||
} |
||||
throw classNotFoundException; |
||||
} |
||||
|
||||
|
||||
private File[] getFileArguments(List<?> nonOptionArguments, Set<File> testerFiles) { |
||||
List<File> files = new ArrayList<File>(); |
||||
for (Object option : nonOptionArguments) { |
||||
if (option instanceof String) { |
||||
String filename = (String) option; |
||||
if ("--".equals(filename)) { |
||||
break; |
||||
} |
||||
if (filename.endsWith(".groovy") || filename.endsWith(".java")) { |
||||
File file = new File(filename); |
||||
if (file.isFile() && file.canRead()) { |
||||
files.add(file); |
||||
} |
||||
else { |
||||
URL url = getClass().getClassLoader().getResource(filename); |
||||
if (url != null) { |
||||
if (url.toString().startsWith("file:")) { |
||||
files.add(new File(url.toString().substring("file:".length()))); |
||||
} |
||||
} |
||||
else { |
||||
throw new RuntimeException("Can't find " + filename); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (files.size() == 0) { |
||||
throw new RuntimeException("Please specify a file to run"); |
||||
} |
||||
|
||||
for (File testerFile : testerFiles) { |
||||
files.add(testerFile); |
||||
} |
||||
|
||||
return files.toArray(new File[files.size()]); |
||||
} |
||||
|
||||
private void printReport(TestResults results) throws FileNotFoundException { |
||||
PrintWriter writer = new PrintWriter("results.txt"); |
||||
|
||||
String header = "Total: " + results.getRunCount() + |
||||
", Success: " + (results.getRunCount()-results.getFailureCount()) + |
||||
", : Failures: " + results.getFailureCount() + "\n" + |
||||
"Passed? " + results.wasSuccessful(); |
||||
|
||||
String trailer = ""; |
||||
String trace = ""; |
||||
for (Failure failure : results.getFailures()) { |
||||
trailer += failure.getDescription().toString(); |
||||
trace += failure.getTrace() + "\n"; |
||||
} |
||||
|
||||
writer.println(header); |
||||
writer.println(trace); |
||||
writer.close(); |
||||
|
||||
Log.info(header); |
||||
Log.info(trailer); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.command.tester; |
||||
|
||||
import java.io.FileNotFoundException; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
public abstract class AbstractTester { |
||||
|
||||
public TestResults findAndTest(List<Class<?>> compiled) throws FileNotFoundException { |
||||
Set<Class<?>> testable = findTestableClasses(compiled); |
||||
|
||||
if (testable.size() == 0) { |
||||
return TestResults.none; |
||||
} |
||||
|
||||
return test(testable.toArray(new Class<?>[]{})); |
||||
} |
||||
|
||||
abstract protected Set<Class<?>> findTestableClasses(List<Class<?>> compiled); |
||||
|
||||
abstract protected TestResults test(Class<?>[] testable); |
||||
|
||||
} |
||||
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.command.tester; |
||||
|
||||
/** |
||||
* Platform neutral way to capture a test failure |
||||
* |
||||
* NOTE: This is needed to avoid having to add JUnit jar file to the deployable artifacts |
||||
*/ |
||||
public class Failure { |
||||
private String description; |
||||
private String trace; |
||||
|
||||
public Failure(String description, String trace) { |
||||
this.description = description; |
||||
this.trace = trace; |
||||
} |
||||
|
||||
public String getDescription() { |
||||
return description; |
||||
} |
||||
|
||||
public void setDescription(String description) { |
||||
this.description = description; |
||||
} |
||||
|
||||
public String getTrace() { |
||||
return trace; |
||||
} |
||||
|
||||
public void setTrace(String trace) { |
||||
this.trace = trace; |
||||
} |
||||
} |
||||
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.command.tester; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Platform neutral way to collect test results |
||||
* |
||||
* NOTE: This is needed to avoid having to add JUnit's jar file to the deployable artifacts |
||||
*/ |
||||
public class TestResults { |
||||
|
||||
public static final NoTestResults none = new NoTestResults(); |
||||
|
||||
private int runCount; |
||||
private int failureCount; |
||||
private Failure[] failures = new Failure[0]; |
||||
|
||||
public void add(TestResults results) { |
||||
this.runCount += results.getRunCount(); |
||||
this.failureCount += results.getFailureCount(); |
||||
|
||||
List<Failure> failures = Arrays.asList(this.failures); |
||||
failures.addAll(Arrays.asList(results.getFailures())); |
||||
this.failures = failures.toArray(new Failure[]{}); |
||||
} |
||||
|
||||
|
||||
public boolean wasSuccessful() { |
||||
return this.failureCount == 0; |
||||
} |
||||
|
||||
public int getRunCount() { |
||||
return runCount; |
||||
} |
||||
|
||||
public void setRunCount(int runCount) { |
||||
this.runCount = runCount; |
||||
} |
||||
|
||||
public int getFailureCount() { |
||||
return failureCount; |
||||
} |
||||
|
||||
public void setFailureCount(int failureCount) { |
||||
this.failureCount = failureCount; |
||||
} |
||||
|
||||
public Failure[] getFailures() { |
||||
return failures; |
||||
} |
||||
|
||||
public void setFailures(Failure[] failures) { |
||||
this.failures = failures; |
||||
} |
||||
|
||||
private static class NoTestResults extends TestResults { |
||||
@Override |
||||
public int getRunCount() { |
||||
return 0; |
||||
} |
||||
|
||||
@Override |
||||
public int getFailureCount() { |
||||
return 0; |
||||
} |
||||
|
||||
@Override |
||||
public Failure[] getFailures() { |
||||
return new Failure[0]; |
||||
} |
||||
|
||||
@Override |
||||
public boolean wasSuccessful() { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.compiler.autoconfigure; |
||||
|
||||
import org.codehaus.groovy.ast.ClassNode; |
||||
import org.codehaus.groovy.control.CompilationFailedException; |
||||
import org.codehaus.groovy.control.customizers.ImportCustomizer; |
||||
import org.springframework.boot.cli.compiler.AstUtils; |
||||
import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; |
||||
import org.springframework.boot.cli.compiler.DependencyCustomizer; |
||||
|
||||
/** |
||||
* {@link CompilerAutoConfiguration} for JUnit |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
public class JUnitCompilerAutoConfiguration extends CompilerAutoConfiguration { |
||||
|
||||
@Override |
||||
public boolean matches(ClassNode classNode) { |
||||
return AstUtils.hasAtLeastOneAnnotation(classNode, "Test"); |
||||
} |
||||
|
||||
@Override |
||||
public void applyDependencies(DependencyCustomizer dependencies) |
||||
throws CompilationFailedException { |
||||
dependencies.add("junit").add("spring-test").add("hamcrest-library"); |
||||
} |
||||
|
||||
@Override |
||||
public void applyImports(ImportCustomizer imports) throws CompilationFailedException { |
||||
imports.addStarImports("org.junit") |
||||
.addStaticStars("org.junit.Assert").addImports() |
||||
.addStaticStars("org.hamcrest.MatcherAssert") |
||||
.addStaticStars("org.hamcrest.Matchers"); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli.compiler.autoconfigure; |
||||
|
||||
import org.codehaus.groovy.ast.ClassNode; |
||||
import org.codehaus.groovy.control.CompilationFailedException; |
||||
import org.codehaus.groovy.control.customizers.ImportCustomizer; |
||||
import org.springframework.boot.cli.compiler.AstUtils; |
||||
import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; |
||||
import org.springframework.boot.cli.compiler.DependencyCustomizer; |
||||
|
||||
/** |
||||
* {@link CompilerAutoConfiguration} for Spock test framework |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
public class SpockCompilerAutoConfiguration extends CompilerAutoConfiguration { |
||||
|
||||
@Override |
||||
public boolean matches(ClassNode classNode) { |
||||
return AstUtils.subclasses(classNode, "Specification"); |
||||
} |
||||
|
||||
@Override |
||||
public void applyDependencies(DependencyCustomizer dependencies) |
||||
throws CompilationFailedException { |
||||
dependencies.add("spock-core"); |
||||
} |
||||
|
||||
@Override |
||||
public void applyImports(ImportCustomizer imports) throws CompilationFailedException { |
||||
imports.addStarImports("spock.lang"); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
groovy.version: ${groovy.version} |
||||
hamcrest.version: ${hamcrest.version} |
||||
jetty.version: ${jetty.version} |
||||
junit.version: ${junit.version} |
||||
reactor.version: ${reactor.version} |
||||
spock.version: ${spock.version} |
||||
spring.version: ${spring.version} |
||||
spring-batch.version: ${spring-batch.version} |
||||
spring-boot.version: ${project.version} |
||||
spring-rabbit.version: ${spring-rabbit.version} |
||||
spring-security.version: ${spring-security.version} |
||||
spring-integration.version: ${spring-integration.version} |
||||
spring-integration-groovydsl.version: ${spring-integration-groovydsl.version} |
||||
tomcat.version: ${tomcat.version} |
||||
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.cli; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.BeforeClass; |
||||
import org.junit.Test; |
||||
import org.springframework.boot.cli.command.CleanCommand; |
||||
import org.springframework.boot.cli.command.TestCommand; |
||||
import org.springframework.boot.cli.command.tester.TestResults; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
/** |
||||
* Integration tests to exercise the CLI's test command. |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
public class TestCommandIntegrationTests { |
||||
|
||||
@BeforeClass |
||||
public static void cleanGrapes() throws Exception { |
||||
GrapesCleaner.cleanIfNecessary(); |
||||
// System.setProperty("ivy.message.logger.level", "3");
|
||||
} |
||||
|
||||
@Before |
||||
public void setup() throws Exception { |
||||
System.setProperty("disableSpringSnapshotRepos", "true"); |
||||
new CleanCommand().run("org.springframework"); |
||||
} |
||||
|
||||
@After |
||||
public void teardown() { |
||||
System.clearProperty("disableSpringSnapshotRepos"); |
||||
} |
||||
|
||||
@Test |
||||
public void noTests() throws Throwable { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/book.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(0, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
@Test |
||||
public void empty() throws Exception { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/empty.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(0, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
@Test(expected = RuntimeException.class) |
||||
public void noFile() throws Exception { |
||||
try { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/nothing.groovy"); |
||||
} catch (RuntimeException e) { |
||||
assertEquals("Can't find testscripts/nothing.groovy", e.getMessage()); |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void appAndTestsInOneFile() throws Exception { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/book_and_tests.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(1, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
@Test |
||||
public void appInOneFileTestsInAnotherFile() throws Exception { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/book.groovy", "testscripts/test.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(1, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
@Test |
||||
public void spockTester() throws Exception { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/spock.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(1, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
@Test |
||||
public void spockAndJunitTester() throws Exception { |
||||
TestCommand command = new TestCommand(); |
||||
command.run("testscripts/spock.groovy", "testscripts/book_and_tests.groovy"); |
||||
TestResults results = command.getResults(); |
||||
assertEquals(2, results.getRunCount()); |
||||
assertEquals(0, results.getFailureCount()); |
||||
assertTrue(results.wasSuccessful()); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License") |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import org.junit.runner.JUnitCore |
||||
import org.junit.runner.Result |
||||
import org.springframework.boot.cli.command.tester.Failure |
||||
import org.springframework.boot.cli.command.tester.TestResults |
||||
|
||||
import java.lang.annotation.Annotation |
||||
import java.lang.reflect.Method |
||||
|
||||
/** |
||||
* Groovy script to run JUnit tests inside the {@link TestCommand}. |
||||
* Needs to be compiled along with the actual code to work properly. |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
class JUnitTester extends AbstractTester { |
||||
|
||||
@Override |
||||
protected Set<Class<?>> findTestableClasses(List<Class<?>> compiled) { |
||||
// Look for @Test methods |
||||
Set<Class<?>> testable = new LinkedHashSet<Class<?>>() |
||||
for (Class<?> clazz : compiled) { |
||||
for (Method method : clazz.getMethods()) { |
||||
for (Annotation annotation : method.getAnnotations()) { |
||||
if (annotation.toString().contains("Test")) { |
||||
testable.add(clazz) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return testable |
||||
} |
||||
|
||||
@Override |
||||
protected TestResults test(Class<?>[] testable) { |
||||
Result results = JUnitCore.runClasses(testable) |
||||
|
||||
TestResults testResults = new TestResults() |
||||
testResults.setFailureCount(results.getFailureCount()) |
||||
testResults.setRunCount(results.getRunCount()) |
||||
|
||||
List<org.springframework.boot.cli.command.tester.Failure> failures = |
||||
new ArrayList<Failure>() |
||||
for (org.junit.runner.notification.Failure failure : results.getFailures()) { |
||||
failures.add(new Failure(failure.getDescription().toString(), failure.getTrace())) |
||||
} |
||||
|
||||
testResults.setFailures(failures.toArray(new Failure[0])) |
||||
|
||||
return testResults |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License") |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import org.junit.runner.Result |
||||
import org.springframework.boot.cli.command.tester.Failure |
||||
import org.springframework.boot.cli.command.tester.TestResults |
||||
import spock.lang.Specification |
||||
import spock.util.EmbeddedSpecRunner |
||||
|
||||
/** |
||||
* Groovy script to run Spock tests inside the {@link TestCommand}. |
||||
* Needs to be compiled along with the actual code to work properly. |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
class SpockTester extends AbstractTester { |
||||
|
||||
@Override |
||||
protected Set<Class<?>> findTestableClasses(List<Class<?>> compiled) { |
||||
// Look for classes that implement spock.lang.Specification |
||||
Set<Class<?>> testable = new LinkedHashSet<Class<?>>() |
||||
for (Class<?> clazz : compiled) { |
||||
if (Specification.class.isAssignableFrom(clazz)) { |
||||
testable.add(clazz) |
||||
} |
||||
} |
||||
return testable |
||||
} |
||||
|
||||
@Override |
||||
protected TestResults test(Class<?>[] testable) { |
||||
Result results = new EmbeddedSpecRunner().runClasses(Arrays.asList(testable)) |
||||
|
||||
TestResults testResults = new TestResults() |
||||
testResults.setFailureCount(results.getFailureCount()) |
||||
testResults.setRunCount(results.getRunCount()) |
||||
|
||||
List<org.springframework.boot.cli.command.tester.Failure> failures = |
||||
new ArrayList<Failure>() |
||||
for (org.junit.runner.notification.Failure failure : results.getFailures()) { |
||||
failures.add(new Failure(failure.getDescription().toString(), failure.getTrace())) |
||||
} |
||||
|
||||
testResults.setFailures(failures.toArray(new Failure[0])) |
||||
|
||||
return testResults |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
/* |
||||
* Copyright 2012-2013 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License") |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import org.springframework.boot.cli.command.tester.TestResults |
||||
|
||||
/** |
||||
* Groovy script define abstract basis for automated testers for {@link TestCommand}. |
||||
* Needs to be compiled along with the actual code to work properly. |
||||
* |
||||
* @author Greg Turnquist |
||||
*/ |
||||
public abstract class AbstractTester { |
||||
|
||||
public TestResults findAndTest(List<Class<?>> compiled) throws FileNotFoundException { |
||||
Set<Class<?>> testable = findTestableClasses(compiled) |
||||
|
||||
if (testable.size() == 0) { |
||||
return TestResults.none |
||||
} |
||||
|
||||
return test(testable.toArray(new Class<?>[0])) |
||||
} |
||||
|
||||
abstract protected Set<Class<?>> findTestableClasses(List<Class<?>> compiled) |
||||
|
||||
abstract protected TestResults test(Class<?>[] testable) |
||||
|
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
class Book { |
||||
String author |
||||
String title |
||||
} |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
class Book { |
||||
String author |
||||
String title |
||||
} |
||||
|
||||
class BookTests { |
||||
@Test |
||||
void testBooks() { |
||||
Book book = new Book(author: "Tom Clancy", title: "Threat Vector") |
||||
assertEquals("Tom Clancy", book.author) |
||||
} |
||||
} |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
class HelloSpock extends Specification { |
||||
def "length of Spock's and his friends' names"() { |
||||
expect: |
||||
name.size() == length |
||||
|
||||
where: |
||||
name | length |
||||
"Spock" | 5 |
||||
"Kirk" | 4 |
||||
"Scotty" | 6 |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
class BookTests { |
||||
@Test |
||||
void testBooks() { |
||||
Book book = new Book(author: "Tom Clancy", title: "Threat Vector") |
||||
assertEquals("Tom Clancy", book.author) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue