marccarre / commons-testing Goto Github PK
View Code? Open in Web Editor NEWUtilities to assist with testing
Utilities to assist with testing
When capturing level is > configured log level, no log entries with (capturing level > level >= log level) are printed on the console.
E.g. for this:
@Rule
public ExpectedLogs warnAndErrorLog = new ExpectedLogs() {{
captureFor(Foo.class, LogLevel.WARN);
}};
No INFO
level logs are printed - regardless of additivity
setting.
Cannot have two rules for different capturing levels (or query instance for level of a given log entry), e.g. :
@Rule
public ExpectedLogs infoLog= new ExpectedLogs() {{
captureFor(Foo.class, LogLevel.INFO);
}};
@Rule
public ExpectedLogs warnLog= new ExpectedLogs() {{
captureFor(Foo.class, LogLevel.WARN);
}};
Nota Bene:
Given other issues raised, it may be worth to have a mode where not just log messages are returned but also:
It may also be useful to be able to create an ExpectedLogs
object capturing absolutely everything.
This looks very promising... I saw it at StackOverflow here
But I'm getting this when I run your ATMTest programme (using Gradle).
java.lang.IllegalStateException: Could not find any binding for [ILogCapturerFactory] on classpath. Make sure you make one available.
at com.carmatechnologies.commons.testing.utils.Postconditions.require(Postconditions.java:10)
at com.carmatechnologies.commons.testing.logging.impl.Binder.tryCreateLogCapturerFactory(Binder.java:34)
at com.carmatechnologies.commons.testing.logging.impl.Binder.createLogCapturerFactory(Binder.java:20)
at com.carmatechnologies.commons.testing.logging.ExpectedLogs.(ExpectedLogs.java:23)
at core.ATMTest$1.(ATMTest.java:21)
... I'm using SLF4J and logback binding.
Any ideas what this is about? Merci d'avance ;-)
Currently only the message is captured, but stacktraces could also be useful.
There currently is:
log.contains("...");
The below should probably be added:
log.containsRegex("...");
When the code names the logger itself:
private static final Logger logger = LoggerFactory.getLogger("arbitrary name")
It would be nice to be able to capture the logs by passing a String:
@Rule
public final ExpectedLogs logs = new ExpectedLogs() {{
captureFor("arbitrary name", LogLevel.WARN);
}};
Is there an example of usage in scala tests, using ScalaTest or Specs2?
Specifically, we use the StrictLogging trait from type safe, so this looks like it could be a useful utility to make assertions about messages being logged using that logger, without needing to override the logger with a mock in tests.
Very nice project, thanks for sharing :).
A further improvement to the expected logs framework could be to leverage the hamcrest style matchers, this would allow you to put a more useful error message on failure, Currently it'll just output 'was true, should be false'.
eg.
@Test
public void someTest() throws Exception {
// Rest of test.
assertThat(log, contains("garbage"));
}
private Matcher<ExpectedLogs> contains(final String expected) {
return new TypeSafeMatcher<ExpectedLogs>() {
@Override protected boolean matchesSafely(ExpectedLogs expectedLogs) {
return expectedLogs.contains(expected);
}
@Override public void describeTo(Description description) {
description.appendText(String.format("Logs to contain the string [%s]", expected));
}
@Override protected void describeMismatchSafely(ExpectedLogs item, Description mismatchDescription) {
mismatchDescription
.appendText(String.format("Logs did not contain the string [%s]%n", expected))
.appendValueList(String.format("Actual log output:%n - "), String.format("%n - "), String.format("%n%n"), item);
}
};
}
Produces:
java.lang.AssertionError:
Expected: Logs to contain the string [garbage]
but: Logs did not contain the string [garbage]
Actual log output:
- "Unable to get the total number of files in the SQLite database file to be loaded - progress messages will not contain this information: [SQLITE_CORRUPT] The database disk image is malformed (database disk image is malformed). Stack trace follows."
But without the fancy matchers, produces:
java.lang.AssertionError:
Expected: is <true>
but: was <false>
Current cannot make assertions regarding ordering of log statements - e.g. assertThat("abc" is present before "def" in the log).
A possible implementation would be, using a builder pattern:
assertThat(log.inOrder().contains("abc").then("def").andThen("ghi"), is(true));
or
assertThat(log.containsInOrder("abc", "def", "ghi"), is(true));
or preferably some Hamcrest matcher:
assertThat(log, containsInOrder("abc", "def", "ghi"));
Execution of the test case in the below class results in the following:
java.lang.RuntimeException: Cannot find invoker for the parameterised method. Using wrong JUnit version?
at junitparams.internal.ParameterisedTestMethodRunner.findParameterisedMethodInvokerInChain(ParameterisedTestMethodRunner.java:71)
at junitparams.internal.ParameterisedTestMethodRunner.findChildForParams(ParameterisedTestMethodRunner.java:58)
at junitparams.internal.ParameterisedTestMethodRunner.runTestMethod(ParameterisedTestMethodRunner.java:39)
at junitparams.internal.ParameterisedTestClassRunner.runParameterisedTest(ParameterisedTestClassRunner.java:143)
at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:405)
at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:383)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Commenting out @Rule
results in a successful run.
Versions:
junit:junit:4.11
pl.pragmatists:JUnitParams:1.0.2
com.carmatechnologies.commons:commons-testing:1.0.1
StringConcat.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StringConcat {
public static final Logger LOGGER = LoggerFactory.getLogger(StringConcat.class);
public String concat(String prefix, String suffix) {
LOGGER.info("concatenating [{}] and [{}]", prefix, suffix);
return prefix + suffix;
}
}
StringConcatTest.java
import com.carmatechnologies.commons.testing.logging.ExpectedLogs;
import com.carmatechnologies.commons.testing.logging.api.LogLevel;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@RunWith(JUnitParamsRunner.class)
public class StringConcatTest {
@Rule
public ExpectedLogs log = new ExpectedLogs() {{
captureFor(StringConcat.class, LogLevel.INFO);
}};
@Parameters({"a, b, ab", "1, 2, 12"})
@Test
public void concat_shouldConcanateInputs(String prefix, String suffix, String expectedResult) throws Exception {
assertThat(new StringConcat().concat(prefix, suffix), is(expectedResult));
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.