public class FailingAssertionCommentWriter extends java.lang.Object implements CodeWriter
CodeWriter
that comments out failing assertions when outputting JUnit tests. This
disables flaky tests that pass when run reflectively within Randoop, but fail when run from the
command line. The whole test is not commented or removed, because the test might have side
effects that later tests depend upon.
Iteratively does the following:
Modifier and Type | Class and Description |
---|---|
private static class |
FailingAssertionCommentWriter.Match
The line and first group from the match of a
Pattern . |
private static class |
FailingAssertionCommentWriter.NotMatchedException
An exception that indicates that an expected pattern was not found.
|
Modifier and Type | Field and Description |
---|---|
private static java.util.regex.Pattern |
FAILURE_HEADER_PATTERN |
private static java.util.regex.Pattern |
FAILURE_MESSAGE_PATTERN
A pattern matching the JUnit4 message indicating the total count of failures.
|
private java.util.HashSet<java.lang.String> |
flakyTestNames
Method names for flaky tests (e.g., "test005").
|
private JavaFileWriter |
javaFileWriter
The underlying
JavaFileWriter for writing a test class. |
private TestEnvironment |
testEnvironment
The
TestEnvironment for running the test classes. |
private static java.lang.String |
TYPE_REGEX
Matches a type: a class name, optional generics, optional array brackets.
|
private static @Regex(value=3) java.util.regex.Pattern |
VARIABLE_DECLARATION_LINE
Matches a variable declaration.
|
Constructor and Description |
---|
FailingAssertionCommentWriter(TestEnvironment testEnvironment,
JavaFileWriter javaFileWriter)
Create a
FailingAssertionCommentWriter . |
Modifier and Type | Method and Description |
---|---|
private java.lang.String |
commentCatchStatements(java.lang.String packageName,
java.lang.String javaCode,
java.util.List<javax.tools.Diagnostic<? extends javax.tools.JavaFileObject>> diagnostics,
java.nio.file.Path destinationDir,
FileCompiler.FileCompilerException e)
Comments out lines with unnecessary catch or try statements.
|
private java.lang.String |
commentFailingAssertions(java.lang.String packageName,
java.lang.String classname,
java.lang.String javaCode,
RunCommand.Status status,
java.util.Set<java.lang.String> flakyTests)
Comments out lines with failing assertions.
|
private void |
compilationError(java.nio.file.Path destinationDir,
java.lang.String classSource,
java.util.List<javax.tools.Diagnostic<? extends javax.tools.JavaFileObject>> diagnostics,
FileCompiler.FileCompilerException e)
Issue an exception because of a non-recoverable compilation error.
|
private java.nio.file.Path |
compileTestClass(java.lang.String packageName,
java.lang.String classname,
java.lang.String classSource,
java.nio.file.Path destinationDir)
Compiles the Java files in the list of files and writes the resulting class files to the
directory.
|
private java.nio.file.Path |
createWorkingDirectory(java.lang.String classname,
int pass)
Creates a temporary directory by concatenating the class name and a pass count to form the
directory name.
|
private java.lang.String |
flakyLineReplacement(java.lang.String flakyLine,
java.lang.String failure)
Given a flaky line (one that throws an exception but was not expected to), return a commented
version of the line that does no computation.
|
java.util.Set<java.lang.String> |
getFlakyTestNames()
Returns the set of flaky test names.
|
private int |
numJunitFailures(java.util.Iterator<java.lang.String> lineIterator,
RunCommand.Status status,
java.lang.String qualifiedClassname,
java.lang.String javaCode)
Return the number of JUnit failures, parsed from the JUnit output.
|
private FailingAssertionCommentWriter.Match |
readUntilMatch(java.util.Iterator<java.lang.String> lineIterator,
@Regex(value=1) java.util.regex.Pattern pattern)
Reads lines of the JUnit output using the iterator until finding a match for the pattern, and
then returns a pair containing the line and the text matching the first group of the pattern.
|
java.nio.file.Path |
writeClassCode(java.lang.String packageName,
java.lang.String classname,
java.lang.String classSource)
Writes the given class using this
CodeWriter . |
java.nio.file.Path |
writeUnmodifiedClassCode(java.lang.String packageName,
java.lang.String classname,
java.lang.String javaCode)
Writes the given class.
|
private static final java.util.regex.Pattern FAILURE_MESSAGE_PATTERN
private static final java.util.regex.Pattern FAILURE_HEADER_PATTERN
private static final java.lang.String TYPE_REGEX
private static final @Regex(value=3) java.util.regex.Pattern VARIABLE_DECLARATION_LINE
private final TestEnvironment testEnvironment
TestEnvironment
for running the test classes.private final JavaFileWriter javaFileWriter
JavaFileWriter
for writing a test class.private final java.util.HashSet<java.lang.String> flakyTestNames
public FailingAssertionCommentWriter(TestEnvironment testEnvironment, JavaFileWriter javaFileWriter)
FailingAssertionCommentWriter
.testEnvironment
- the TestEnvironment
for executing tests during filteringjavaFileWriter
- the JavaFileWriter
to write .java
files for the classespublic java.util.Set<java.lang.String> getFlakyTestNames()
public java.nio.file.Path writeClassCode(java.lang.String packageName, java.lang.String classname, java.lang.String classSource) throws RandoopOutputException
CodeWriter
. May modify the class text before writing
it. May write additional files (but those are not returned).
Replaces failing assertions by comments.
Assumes output from JUnit4 org.junit.runner.JUnitCore
runner used in TestEnvironment
.
writeClassCode
in interface CodeWriter
packageName
- the package name of the classclassname
- the simple name of the classclassSource
- the text of a Java class, must be compilablePath
object for the Java file writtenRandoopOutputException
- if there is an error while writing the codepublic java.nio.file.Path writeUnmodifiedClassCode(java.lang.String packageName, java.lang.String classname, java.lang.String javaCode) throws RandoopOutputException
CodeWriter
writeUnmodifiedClassCode
in interface CodeWriter
packageName
- the package name of the classclassname
- the simple name of the classjavaCode
- the text of the class to be written, must be compilablePath
object for the Java file writtenRandoopOutputException
- if there is an error while writing the codeprivate java.lang.String commentCatchStatements(java.lang.String packageName, java.lang.String javaCode, java.util.List<javax.tools.Diagnostic<? extends javax.tools.JavaFileObject>> diagnostics, java.nio.file.Path destinationDir, FileCompiler.FileCompilerException e)
packageName
- the package name of the test classjavaCode
- the source code for the test class; each assertion must be on its own linediagnostics
- the errors and warnings from compiling the classdestinationDir
- the directory that contains the source code, used only for debugginge
- the exception that was raised when compiling the source code, used only for debuggingRandoopBug
- if there is an unhandled compilation error (i.e., not about an unnecessary
catch or try statement)private void compilationError(java.nio.file.Path destinationDir, java.lang.String classSource, java.util.List<javax.tools.Diagnostic<? extends javax.tools.JavaFileObject>> diagnostics, FileCompiler.FileCompilerException e)
destinationDir
- the directory that contains the source code, used only for debuggingclassSource
- the text of the test classdiagnostics
- the errors and warnings from compiling the classe
- the exception that was raised when compiling the source code, used only for debuggingprivate java.lang.String commentFailingAssertions(java.lang.String packageName, java.lang.String classname, java.lang.String javaCode, RunCommand.Status status, java.util.Set<java.lang.String> flakyTests)
status
from
running JUnit with javaCode
to identify lines with failing assertions.packageName
- the package name of the test classclassname
- the simple (unqualified) name of the test classjavaCode
- the source code for the test class; each assertion must be on its own linestatus
- the result of running the test with JUnitflakyTests
- names of flaky tests, e.g. "test005". This is an output parameter that is
augmented by this method.RandoopBug
- if status
contains output for a failure not involving a
Randoop-generated test methodprivate int numJunitFailures(java.util.Iterator<java.lang.String> lineIterator, RunCommand.Status status, java.lang.String qualifiedClassname, java.lang.String javaCode)
lineIterator
- an iterator over the lines of JUnit outputstatus
- the result of running JUnitqualifiedClassname
- the name of the JUnit class, used only for debugging outputjavaCode
- the JUnit class source code, used only for debugging outputprivate java.lang.String flakyLineReplacement(java.lang.String flakyLine, java.lang.String failure)
flakyLine
- the line that throws an exceptionfailure
- the reason for flakiness, which is put in a comment in the returned lineprivate FailingAssertionCommentWriter.Match readUntilMatch(java.util.Iterator<java.lang.String> lineIterator, @Regex(value=1) java.util.regex.Pattern pattern)
lineIterator
- the iterator for reading from the JUnit outputpattern
- the pattern for a regex with at least one groupRandoopBug
- if the iterator has no more lines, but the pattern hasn't been matchedprivate java.nio.file.Path compileTestClass(java.lang.String packageName, java.lang.String classname, java.lang.String classSource, java.nio.file.Path destinationDir) throws FileCompiler.FileCompilerException
packageName
- the package name for the test classclassname
- the name of the test classclassSource
- the text of the test classdestinationDir
- the directory for class file outputFileCompiler.FileCompilerException
- if the file does not compileprivate java.nio.file.Path createWorkingDirectory(java.lang.String classname, int pass)
classname
- the class namepass
- the pass countPath
for the directory created