Commit 329a950b authored by Andy Wilkinson's avatar Andy Wilkinson

Remove testing support from the CLI

The testing support in the CLI has proven to be more trouble than
it's worth. Our recommendation is that, once an app gets to the stage
of requiring a test suite, it should be converted to a Maven or
Gradle project. This makes it easy to version, publish, deploy etc
using the vast ecosystems of the two build systems.

As part of this change, the dependency management for Spock has been
moved into spring-boot-parent, thereby making it "private". This
allows it to continue to manage the test-only Spock dependency in
spring-boot-test without also managing the version of Spring that is
used by a user's application.

Closes gh-9087
Fixes gh-9043
parent acda8e64
...@@ -137,11 +137,6 @@ ...@@ -137,11 +137,6 @@
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
...@@ -154,6 +149,11 @@ ...@@ -154,6 +149,11 @@
<artifactId>spring-boot-test</artifactId> <artifactId>spring-boot-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<resources> <resources>
......
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -45,7 +45,7 @@ public class CommandLineIT { ...@@ -45,7 +45,7 @@ public class CommandLineIT {
assertThat(cli.await(), equalTo(0)); assertThat(cli.await(), equalTo(0));
assertThat("Unexpected error: \n" + cli.getErrorOutput(), assertThat("Unexpected error: \n" + cli.getErrorOutput(),
cli.getErrorOutput().length(), equalTo(0)); cli.getErrorOutput().length(), equalTo(0));
assertThat(cli.getStandardOutputLines().size(), equalTo(11)); assertThat(cli.getStandardOutputLines().size(), equalTo(10));
} }
@Test @Test
......
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -30,7 +30,6 @@ import org.springframework.boot.cli.command.init.InitCommand; ...@@ -30,7 +30,6 @@ import org.springframework.boot.cli.command.init.InitCommand;
import org.springframework.boot.cli.command.install.InstallCommand; import org.springframework.boot.cli.command.install.InstallCommand;
import org.springframework.boot.cli.command.install.UninstallCommand; import org.springframework.boot.cli.command.install.UninstallCommand;
import org.springframework.boot.cli.command.run.RunCommand; import org.springframework.boot.cli.command.run.RunCommand;
import org.springframework.boot.cli.command.test.TestCommand;
/** /**
* Default implementation of {@link CommandFactory}. * Default implementation of {@link CommandFactory}.
...@@ -40,9 +39,9 @@ import org.springframework.boot.cli.command.test.TestCommand; ...@@ -40,9 +39,9 @@ import org.springframework.boot.cli.command.test.TestCommand;
public class DefaultCommandFactory implements CommandFactory { public class DefaultCommandFactory implements CommandFactory {
private static final List<Command> DEFAULT_COMMANDS = Arrays.<Command>asList( private static final List<Command> DEFAULT_COMMANDS = Arrays.<Command>asList(
new VersionCommand(), new RunCommand(), new TestCommand(), new GrabCommand(), new VersionCommand(), new RunCommand(), new GrabCommand(), new JarCommand(),
new JarCommand(), new WarCommand(), new InstallCommand(), new WarCommand(), new InstallCommand(), new UninstallCommand(),
new UninstallCommand(), new InitCommand()); new InitCommand());
@Override @Override
public Collection<Command> getCommands() { public Collection<Command> getCommands() {
......
/*
* Copyright 2012-2016 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.test;
import joptsimple.OptionSet;
import org.springframework.boot.cli.command.Command;
import org.springframework.boot.cli.command.OptionParsingCommand;
import org.springframework.boot.cli.command.options.CompilerOptionHandler;
import org.springframework.boot.cli.command.options.OptionSetGroovyCompilerConfiguration;
import org.springframework.boot.cli.command.options.SourceOptions;
import org.springframework.boot.cli.command.status.ExitStatus;
/**
* {@link Command} to run a groovy test script or scripts.
*
* @author Greg Turnquist
* @author Phillip Webb
*/
public class TestCommand extends OptionParsingCommand {
public TestCommand() {
super("test", "Run a spring groovy script test", new TestOptionHandler());
}
@Override
public String getUsageHelp() {
return "[options] <files> [--] [args]";
}
private static class TestOptionHandler extends CompilerOptionHandler {
private TestRunner runner;
@Override
protected ExitStatus run(OptionSet options) throws Exception {
SourceOptions sourceOptions = new SourceOptions(options);
TestRunnerConfiguration configuration = new TestRunnerConfigurationAdapter(
options, this);
this.runner = new TestRunner(configuration, sourceOptions.getSourcesArray(),
sourceOptions.getArgsArray());
this.runner.compileAndRunTests();
return ExitStatus.OK.hangup();
}
/**
* Simple adapter class to present the {@link OptionSet} as a
* {@link TestRunnerConfiguration}.
*/
private class TestRunnerConfigurationAdapter extends
OptionSetGroovyCompilerConfiguration implements TestRunnerConfiguration {
TestRunnerConfigurationAdapter(OptionSet options,
CompilerOptionHandler optionHandler) {
super(options, optionHandler);
}
}
}
}
/*
* Copyright 2012-2014 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.test;
import org.springframework.boot.cli.command.CommandException;
/**
* Thrown when tests fail to execute.
*
* @author Graeme Rocher
* @since 1.2.0
*/
public class TestFailedException extends CommandException {
public TestFailedException(Throwable cause) {
super(cause, Option.HIDE_MESSAGE);
}
}
/*
* Copyright 2012-2017 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.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.cli.compiler.GroovyCompiler;
import org.springframework.boot.groovy.DelegateTestRunner;
import org.springframework.util.ReflectionUtils;
/**
* Compile and run groovy based tests.
*
* @author Phillip Webb
* @author Graeme Rocher
*/
public class TestRunner {
private static final String JUNIT_TEST_ANNOTATION = "org.junit.Test";
private final String[] sources;
private final GroovyCompiler compiler;
private volatile Throwable threadException;
/**
* Create a new {@link TestRunner} instance.
* @param configuration the configuration
* @param sources the sources
* @param args the args
*/
TestRunner(TestRunnerConfiguration configuration, String[] sources, String[] args) {
this.sources = sources.clone();
this.compiler = new GroovyCompiler(configuration);
}
public void compileAndRunTests() throws Exception {
Object[] sources = this.compiler.compile(this.sources);
if (sources.length == 0) {
throw new RuntimeException(
"No classes found in '" + Arrays.toString(this.sources) + "'");
}
// Run in new thread to ensure that the context classloader is setup
RunThread runThread = new RunThread(sources);
runThread.start();
runThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable ex) {
TestRunner.this.threadException = ex;
}
});
runThread.join();
if (this.threadException != null) {
TestFailedException ex = new TestFailedException(this.threadException);
this.threadException = null;
throw ex;
}
}
/**
* Thread used to launch the Spring Application with the correct context classloader.
*/
private class RunThread extends Thread {
private final Class<?>[] testClasses;
private final Class<?> spockSpecificationClass;
/**
* Create a new {@link RunThread} instance.
* @param sources the sources to launch
*/
RunThread(Object... sources) {
super("testrunner");
setDaemon(true);
if (sources.length != 0 && sources[0] instanceof Class) {
setContextClassLoader(((Class<?>) sources[0]).getClassLoader());
}
this.spockSpecificationClass = loadSpockSpecificationClass(
getContextClassLoader());
this.testClasses = getTestClasses(sources);
}
private Class<?> loadSpockSpecificationClass(ClassLoader contextClassLoader) {
try {
return getContextClassLoader().loadClass("spock.lang.Specification");
}
catch (Exception ex) {
return null;
}
}
private Class<?>[] getTestClasses(Object[] sources) {
List<Class<?>> testClasses = new ArrayList<>();
for (Object source : sources) {
if ((source instanceof Class) && isTestable((Class<?>) source)) {
testClasses.add((Class<?>) source);
}
}
return testClasses.toArray(new Class<?>[testClasses.size()]);
}
private boolean isTestable(Class<?> sourceClass) {
return (isJunitTest(sourceClass) || isSpockTest(sourceClass));
}
private boolean isJunitTest(Class<?> sourceClass) {
for (Method method : sourceClass.getMethods()) {
for (Annotation annotation : method.getAnnotations()) {
if (annotation.annotationType().getName()
.equals(JUNIT_TEST_ANNOTATION)) {
return true;
}
}
}
return false;
}
private boolean isSpockTest(Class<?> sourceClass) {
return (this.spockSpecificationClass != null
&& this.spockSpecificationClass.isAssignableFrom(sourceClass));
}
@Override
public void run() {
try {
if (this.testClasses.length == 0) {
System.out.println("No tests found");
}
else {
ClassLoader contextClassLoader = Thread.currentThread()
.getContextClassLoader();
Class<?> delegateClass = contextClassLoader
.loadClass(DelegateTestRunner.class.getName());
Class<?> resultClass = contextClassLoader
.loadClass("org.junit.runner.Result");
Method runMethod = delegateClass.getMethod("run", Class[].class,
resultClass);
Object result = resultClass.newInstance();
runMethod.invoke(null, this.testClasses, result);
boolean wasSuccessful = (Boolean) resultClass
.getMethod("wasSuccessful").invoke(result);
if (!wasSuccessful) {
throw new RuntimeException("Tests Failed.");
}
}
}
catch (Exception ex) {
ReflectionUtils.rethrowRuntimeException(ex);
}
}
}
}
/*
* Copyright 2012-2014 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.test;
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration;
/**
* Configuration for {@link TestRunner}.
*
* @author Phillip Webb
*/
public interface TestRunnerConfiguration extends GroovyCompilerConfiguration {
}
/*
* Copyright 2012-2016 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("spring-boot-starter-test");
}
@Override
public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
imports.addStarImports("org.junit").addStaticStars("org.junit.Assert")
.addStaticStars("org.hamcrest.MatcherAssert")
.addStaticStars("org.hamcrest.Matchers");
}
}
/*
* 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").add("junit").add("spring-test")
.add("hamcrest-library");
}
@Override
public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
imports.addStarImports("spock.lang").addStarImports("org.junit")
.addStaticStars("org.junit.Assert")
.addStaticStars("org.hamcrest.MatcherAssert")
.addStaticStars("org.hamcrest.Matchers");
}
}
/*
* Copyright 2012-2014 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.groovy;
import org.junit.internal.TextListener;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.springframework.boot.cli.command.test.TestRunner;
/**
* Delegate test runner to launch tests in user application classpath.
*
* @author Phillip Webb
* @see TestRunner
*/
public final class DelegateTestRunner {
private DelegateTestRunner() {
}
public static void run(Class<?>[] testClasses, Result result) {
JUnitCore jUnitCore = new JUnitCore();
jUnitCore.addListener(new TextListener(System.out));
jUnitCore.addListener(result.createListener());
jUnitCore.run(testClasses);
}
}
...@@ -6,8 +6,6 @@ org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfigurat ...@@ -6,8 +6,6 @@ org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfigurat
org.springframework.boot.cli.compiler.autoconfigure.CachingCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.CachingCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.JdbcCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.JdbcCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.JmsCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.JmsCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.JUnitCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.SpockCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.TransactionManagementCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.TransactionManagementCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.SpringIntegrationCompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.SpringIntegrationCompilerAutoConfiguration
org.springframework.boot.cli.compiler.autoconfigure.SpringSecurityOAuth2CompilerAutoConfiguration org.springframework.boot.cli.compiler.autoconfigure.SpringSecurityOAuth2CompilerAutoConfiguration
......
...@@ -40,7 +40,6 @@ import org.springframework.boot.cli.command.OptionParsingCommand; ...@@ -40,7 +40,6 @@ import org.springframework.boot.cli.command.OptionParsingCommand;
import org.springframework.boot.cli.command.archive.JarCommand; import org.springframework.boot.cli.command.archive.JarCommand;
import org.springframework.boot.cli.command.grab.GrabCommand; import org.springframework.boot.cli.command.grab.GrabCommand;
import org.springframework.boot.cli.command.run.RunCommand; import org.springframework.boot.cli.command.run.RunCommand;
import org.springframework.boot.cli.command.test.TestCommand;
import org.springframework.boot.test.rule.OutputCapture; import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.util.SocketUtils; import org.springframework.util.SocketUtils;
...@@ -77,17 +76,6 @@ public class CliTester implements TestRule { ...@@ -77,17 +76,6 @@ public class CliTester implements TestRule {
return getOutput(); return getOutput();
} }
public String test(String... args) throws Exception {
Future<TestCommand> future = submitCommand(new TestCommand(), args);
try {
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
catch (Exception ex) {
return getOutput();
}
}
public String grab(String... args) throws Exception { public String grab(String... args) throws Exception {
Future<GrabCommand> future = submitCommand(new GrabCommand(), args); Future<GrabCommand> future = submitCommand(new GrabCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS)); this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
......
/*
* Copyright 2012-2016 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.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.cli.command.test.TestCommand;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests to exercise the CLI's test command.
*
* @author Greg Turnquist
* @author Phillip Webb
*/
public class TestCommandIntegrationTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public CliTester cli = new CliTester("test-samples/");
@Before
public void setUp() throws Exception {
System.setProperty("disableSpringSnapshotRepos", "false");
}
@After
public void tearDown() {
System.clearProperty("disableSpringSnapshotRepos");
}
@Test
public void noTests() throws Throwable {
String output = this.cli.test("book.groovy");
assertThat(output).contains("No tests found");
}
@Test
public void empty() throws Exception {
String output = this.cli.test("empty.groovy");
assertThat(output).contains("No tests found");
}
@Test
public void noFile() throws Exception {
TestCommand command = new TestCommand();
this.thrown.expect(RuntimeException.class);
this.thrown.expectMessage("Can't find nothing.groovy");
command.run("nothing.groovy");
}
@Test
public void appAndTestsInOneFile() throws Exception {
String output = this.cli.test("book_and_tests.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void appInOneFileTestsInAnotherFile() throws Exception {
String output = this.cli.test("book.groovy", "test.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void integrationTest() throws Exception {
String output = this.cli.test("integration.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void integrationAutoConfigEmbeddedTest() throws Exception {
String output = this.cli.test("integration_auto.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void integrationAutoConfigTest() throws Exception {
String output = this.cli.test("integration_auto_test.groovy", "app.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void spockTester() throws Exception {
String output = this.cli.test("spock.groovy");
assertThat(output).contains("OK (1 test)");
}
@Test
public void spockAndJunitTester() throws Exception {
String output = this.cli.test("spock.groovy", "book_and_tests.groovy");
assertThat(output).contains("OK (2 tests)");
}
@Test
public void verifyFailures() throws Exception {
String output = this.cli.test("failures.groovy");
assertThat(output).contains("Tests run: 5, Failures: 3");
}
}
/*
* Copyright 2012-2015 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.test;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link TestRunner}.
*
* @author Andy Wilkinson
*/
public class TestRunnerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void exceptionMessageWhenSourcesContainsNoClasses() throws Exception {
TestRunnerConfiguration configuration = mock(TestRunnerConfiguration.class);
given(configuration.getClasspath()).willReturn(new String[0]);
this.thrown.expect(RuntimeException.class);
this.thrown.expectMessage(equalTo("No classes found in '[foo, bar]'"));
new TestRunner(configuration, new String[] { "foo", "bar" }, new String[0])
.compileAndRunTests();
}
}
...@@ -152,7 +152,6 @@ ...@@ -152,7 +152,6 @@
<slf4j.version>1.7.25</slf4j.version> <slf4j.version>1.7.25</slf4j.version>
<snakeyaml.version>1.18</snakeyaml.version> <snakeyaml.version>1.18</snakeyaml.version>
<solr.version>6.5.0</solr.version> <solr.version>6.5.0</solr.version>
<spock.version>1.0-groovy-2.4</spock.version>
<spring.version>5.0.0.BUILD-SNAPSHOT</spring.version> <spring.version>5.0.0.BUILD-SNAPSHOT</spring.version>
<spring-amqp.version>2.0.0.BUILD-SNAPSHOT</spring-amqp.version> <spring-amqp.version>2.0.0.BUILD-SNAPSHOT</spring-amqp.version>
<spring-cloud-connectors.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-connectors.version> <spring-cloud-connectors.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-connectors.version>
......
...@@ -252,41 +252,6 @@ http://platform.spring.io/[Spring IO Platform], e.g. ...@@ -252,41 +252,6 @@ http://platform.spring.io/[Spring IO Platform], e.g.
[[cli-testing]]
=== Testing your code
The `test` command allows you to compile and run tests for your application. Typical
usage looks like this:
[indent=0]
----
$ spring test app.groovy tests.groovy
Total: 1, Success: 1, : Failures: 0
Passed? true
----
In this example, `tests.groovy` contains JUnit `@Test` methods or Spock `Specification`
classes. All the common framework annotations and static methods should be available to
you without having to `import` them.
Here is the `tests.groovy` file that we used above (with a JUnit test):
[source,groovy,indent=0]
----
class ApplicationTests {
@Test
void homeSaysHello() {
assertEquals("Hello World!", new WebApplication().home())
}
}
----
TIP: If you have more than one test source files, you might prefer to organize them
into a `test` directory.
[[cli-multiple-source-files]] [[cli-multiple-source-files]]
=== Applications with multiple source files === Applications with multiple source files
You can use "`shell globbing`" with all commands that accept file input. This allows you You can use "`shell globbing`" with all commands that accept file input. This allows you
...@@ -297,14 +262,6 @@ to easily use multiple files from a single directory, e.g. ...@@ -297,14 +262,6 @@ to easily use multiple files from a single directory, e.g.
$ spring run *.groovy $ spring run *.groovy
---- ----
This technique can also be useful if you want to segregate your "`test`" or "`spec`" code
from the main application code:
[indent=0]
----
$ spring test app/*.groovy test/*.groovy
----
[[cli-jar]] [[cli-jar]]
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.version>3.1.1</maven.version> <maven.version>3.1.1</maven.version>
<spock.version>1.0-groovy-2.4</spock.version>
</properties> </properties>
<scm> <scm>
<url>http://github.com/spring-projects/spring-boot</url> <url>http://github.com/spring-projects/spring-boot</url>
...@@ -209,6 +210,22 @@ ...@@ -209,6 +210,22 @@
<artifactId>plexus-build-api</artifactId> <artifactId>plexus-build-api</artifactId>
<version>0.0.7</version> <version>0.0.7</version>
</dependency> </dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>${spock.version}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>${spock.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.zeroturnaround</groupId> <groupId>org.zeroturnaround</groupId>
<artifactId>zt-zip</artifactId> <artifactId>zt-zip</artifactId>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment