RefactorFirst Report for JUnit 4.13.3-SNAPSHOT

Show RefactorFirst some ❤️

Star Fork Watch Issue Sponsor

Class Map

Red lines represent relationships to remove.
Red nodes represent classes to remove.
Zoom in / out with your mouse wheel and click/move to drag the image.
Clicking on a node in the DOT graph (if present below) will open its source file in the repo. Right/Alt click to open in a new browser tab.
Excludes classes that have no incoming and outgoing edges
Number of classes: 382 Number of relationships: 1134

Class Relationship Removal Priority

Refactor Starting with Priority 1

Current Class Cycle Count: 28
Number of Class Relationships to Remove: 54
Classes with * should be broken apart
Removing class relationships below will eliminate class cycles
Class Relationship Priority In Class
Cycles
Relationship
Strength
Also Removes Pkg
Cycle Relationship
In Package
Cycles
AssertComparisonFailure : 1 1 3 1 false 0
AssertExactComparisonCriteria : 1 2 2 1 false 3
Request*JUnitCore : 1 3 2 1 false 0
AssertInexactComparisonCriteria : 2 4 2 2 false 3
ComparisonCriteriaAssert : 3 5 2 3 true 3
ComparisonFailure$ComparisonCompactor*ComparisonFailure$ComparisonCompactor$DiffExtractor : 6 6 2 6 false 0
Request*FilterRequest : 1 7 1 1 true 4
Request*SortingRequest : 1 8 1 1 true 4
RunListenerResult : 1 9 1 1 true 3
MemoizingRequestRequest* : 1 10 1 1 false 4
FromDataPointsSpecificDataPointsSupplier* : 1 11 1 1 false 1
Categories*Categories$CategoryFilter : 1 12 1 1 false 0
MaxHistory*MaxHistory$RememberingListener : 1 13 1 1 false 0
MaxHistory*MaxHistory$TestComparator : 1 14 1 1 false 0
ExpectedException*ExpectedException$ExpectedExceptionStatement : 1 15 1 1 false 0
Condition*Condition$Matched : 1 16 1 1 false 0
AllMembersSupplier$MethodParameterValueAllMembersSupplier* : 1 17 1 1 false 0
OrderableOrderer* : 1 18 1 1 false 0
SortableSorter* : 1 19 1 1 false 0
Condition$StepCondition* : 1 20 1 1 false 0
TestTestResult : 1 21 1 1 false 0
RuleMemberValidatorRuleMemberValidator$FieldMustBeARule : 1 22 1 1 false 0
RuleMemberValidatorRuleMemberValidator$MethodMustBeATestRule : 1 23 1 1 false 0
RuleMemberValidator$MethodMustBeARuleRuleMemberValidator : 1 24 1 1 false 0
RuleMemberValidator$FieldMustBeATestRuleRuleMemberValidator : 1 25 1 1 false 0
Throwables$State$1Throwables$State : 1 26 1 1 false 0
Throwables$StateThrowables$State$2 : 1 27 1 1 false 0
Throwables$StateThrowables$State$3 : 1 28 1 1 false 0
Throwables$StateThrowables$State$4 : 1 29 1 1 false 0
FilterFilter$1 : 1 30 1 1 false 0
ResultResult$Listener : 1 31 1 1 false 0
SelfDescribingDescription : 1 32 1 1 false 0
MultipleFailureExceptionMultipleFailureException : 2 33 1 2 false 3
TestedOnSupplier*TestedOn : 2 34 1 2 false 0
Condition*Condition$NotMatched : 2 35 1 2 false 0
CombinableMatcher*CombinableMatcher$CombinableBothMatcher : 2 36 1 2 false 0
CombinableMatcher*CombinableMatcher$CombinableEitherMatcher : 2 37 1 2 false 0
ComparisonFailureComparisonCompactor : 2 38 1 2 false 0
TestResultTestCase : 2 39 1 2 false 0
RuleMemberValidator$MemberMustBeNonStaticOrAlsoClassRuleRuleMemberValidator : 2 40 1 2 false 0
ThrowablesThrowables$State : 2 41 1 2 false 0
OrderingRequestRequest* : 3 42 1 3 false 4
TemporaryFolder*TemporaryFolder$Builder : 3 43 1 3 false 0
FailOnTimeout*FailOnTimeout$Builder : 4 44 1 4 false 0
Orderer*Ordering : 4 45 1 4 false 0
FilterFilterable : 4 46 1 4 false 0
JUnit4TestAdapter*JUnit4TestAdapterCache : 5 47 1 5 false 0
OrderingOrdering$Factory : 5 48 1 5 false 0
Timeout*Timeout$Builder : 6 49 1 6 false 0
ResultResult$SerializedForm : 6 50 1 6 false 0
Description$NullDescriptionDescription : 7 51 1 7 false 0
RunNotifier*RunNotifier$SafeNotifier : 9 52 1 9 false 0
Stopwatch$InternalWatcherStopwatch* : 12 53 1 12 false 0
RuleMemberValidatorRuleMemberValidator$Builder : 25 54 1 25 false 0







Package Map

Red lines represent relationships to remove.
Red nodes represent classes to remove.
Zoom in / out with your mouse wheel and click/move to drag the image.
Excludes packages that have no incoming and outgoing edges
Number of packages: 35 Number of relationships: 136

Package Relationship Removal Priority

Refactor Starting with Priority 1

Current Package Cycle Count: 6
Number of Package Relationships to Remove: 20
Packages and classes with * should be broken apart
Removing package relationships below will eliminate package cycles
Package Relationship Priority In Pkg
Cycles
Relationship
Strength
Class Relationships to Remove
To Break Package Relationship
org.junit.internal* → org.junit.runners* : 1 1 4 1 MethodSorterMethodSorters : 1
org.junit.internal.builders → org.junit.runners* : 1 2 4 1 JUnit4BuilderJUnit4 : 1
org.junit.runner → org.junit.internal.builders : 2 3 4 2 Request*AllDefaultPossibilitiesBuilder : 2
org.junit.runner → org.junit.internal.requests : 5 4 4 5 Request*ClassRequest : 2
Request*SortingRequest : 1
Request*FilterRequest : 1
Request*OrderingRequest : 1
org.junit.internal* → org.junit.runner : 12 5 4 12 TextListenerDescription : 2
TextListenerResult : 10
org.junit → org.junit.runners* : 1 6 3 1 FixMethodOrderMethodSorters : 1
org.junit.runner.notification* → org.junit.internal* : 2 7 3 2 Failure*Throwables : 2
org.junit.runners.model → org.junit.internal.runners.model : 2 8 3 2 FrameworkMethod*ReflectiveCallable : 1
MultipleFailureExceptionMultipleFailureException : 1
org.junit.internal.runners* → org.junit.runners.model : 5 9 3 5 ErrorReportingRunnerInvalidTestClassError : 1
ErrorReportingRunnerInitializationError : 3
MethodRoadieTestTimedOutException : 1
org.junit.internal* → org.junit : 8 10 3 8 InexactComparisonCriteriaAssert : 2
ExactComparisonCriteriaAssert : 1
ComparisonCriteriaAssert : 3
MethodSorterFixMethodOrder : 2
org.junit.runners* → org.junit.runners.parameterized : 15 11 3 15 Parameterized$RunnersFactoryBlockJUnit4ClassRunnerWithParametersFactory : 1
Parameterized$UseParametersRunnerFactoryParametersRunnerFactory : 1
Parameterized$RunnersFactoryTestWithParameters : 8
Parameterized$RunnersFactoryParametersRunnerFactory : 5
org.junit.runners.model → org.junit.runner : 15 12 3 15 RunnerBuilder*Description : 2
RunnerBuilder*OrderWith : 2
RunnerBuilder*Runner* : 11
org.junit.runner.notification* → org.junit.runner : 25 13 3 25 RunListenerResult : 1
RunListenerDescription : 6
SynchronizedRunListenerDescription : 6
RunNotifier*Result : 1
Failure*Description : 4
RunNotifier*Description : 6
SynchronizedRunListenerResult : 1
junit.framework → org.junit.runner : 39 14 3 39 JUnit4TestAdapter*Description : 13
JUnit4TestAdapterCacheDescription : 14
JUnit4TestCaseFacadeDescribable : 1
JUnit4TestCaseFacadeDescription : 4
JUnit4TestAdapter*Request* : 2
JUnit4TestAdapter*Runner* : 4
JUnit4TestAdapter*Describable : 1
org.junit.internal.runners* → org.junit.runner : 41 15 3 41 JUnit38ClassRunner$OldTestClassAdaptingListenerDescribable : 4
JUnit38ClassRunner*Runner* : 2
ErrorReportingRunnerDescription : 7
ErrorReportingRunnerRunner* : 1
JUnit38ClassRunner*Describable : 4
JUnit4ClassRunnerRunner* : 1
JUnit38ClassRunner$OldTestClassAdaptingListenerDescription : 2
JUnit38ClassRunner*Description : 8
ClassRoadieDescription : 2
JUnit4ClassRunnerDescription : 8
MethodRoadieDescription : 2
org.junit.validator → org.junit.runners.model : 31 16 2 31 AnnotationsValidator$FieldValidatorTestClass* : 2
AnnotationValidatorFrameworkMethod* : 1
AnnotationsValidator$MethodValidatorTestClass* : 2
AnnotationsValidatorTestClass* : 1
AnnotationsValidator$MethodValidatorFrameworkMethod* : 3
AnnotationsValidator$AnnotatableValidatorAnnotatable : 7
AnnotationValidatorFrameworkField : 1
AnnotationsValidator$FieldValidatorFrameworkField : 3
TestClassValidatorTestClass* : 1
AnnotationsValidator$ClassValidatorTestClass* : 4
AnnotationValidatorTestClass* : 1
PublicClassValidatorTestClass* : 3
AnnotationsValidator$AnnotatableValidatorTestClass* : 2
org.hamcrest → org.hamcrest.internal : 12 17 1 12 FeatureMatcherReflectiveTypeFinder : 2
TypeSafeDiagnosingMatcherReflectiveTypeFinder : 4
BaseDescriptionArrayIterator : 1
TypeSafeMatcherReflectiveTypeFinder : 4
BaseDescriptionSelfDescribingValueIterator : 1
org.junit.runner.manipulation → org.junit.runner : 44 18 1 44 OrderingDescription : 7
Sorter*Description : 11
Orderer*Description : 7
AlphanumericDescription : 5
FilterDescription : 10
Ordering$ContextDescription : 3
Ordering$1Description : 1
org.hamcrest → org.hamcrest.core : 51 19 1 51 CoreMatchers*IsSame : 2
CoreMatchers*StringEndsWith : 1
CoreMatchers*CombinableMatcher$CombinableBothMatcher : 1
CoreMatchers*CombinableMatcher* : 2
CoreMatchers*Every : 1
CoreMatchers*StringStartsWith : 1
CoreMatchers*IsNot : 2
CoreMatchers*CombinableMatcher$CombinableEitherMatcher : 1
CoreMatchers*AnyOf : 14
CoreMatchers*IsEqual : 1
CoreMatchers*IsNull : 4
CoreMatchers*AllOf : 7
CoreMatchers*IsCollectionContaining : 4
CoreMatchers*IsAnything : 2
CoreMatchers*DescribedAs : 1
CoreMatchers*StringContains : 1
CoreMatchers*IsInstanceOf : 2
CoreMatchers*Is : 4
org.junit.experimental.theories.internal → org.junit.experimental.theories* : 106 20 1 106 AllMembersSupplier$MethodParameterValuePotentialAssignment$CouldNotGenerateValueException : 3
EnumSupplierParameterSignature : 1
EnumSupplierPotentialAssignment : 4
SpecificDataPointsSupplier*ParametersSuppliedBy : 4
AssignmentsParametersSuppliedBy : 2
EnumSupplierParameterSupplier : 1
AssignmentsPotentialAssignment$CouldNotGenerateValueException : 5
BooleanSupplierPotentialAssignment : 3
BooleanSupplierParameterSignature : 1
AllMembersSupplier$MethodParameterValueDataPoint : 2
SpecificDataPointsSupplier*ParameterSignature : 8
SpecificDataPointsSupplier*DataPoint : 2
AllMembersSupplier$MethodParameterValuePotentialAssignment : 1
AssignmentsParameterSignature : 13
BooleanSupplierParameterSupplier : 1
AssignmentsPotentialAssignment : 11
AllMembersSupplier*DataPoints : 2
SpecificDataPointsSupplier*FromDataPoints : 4
SpecificDataPointsSupplier*DataPoints : 2
AllMembersSupplier*ParameterSupplier : 1
AllMembersSupplier*ParameterSignature : 17
AllMembersSupplier*PotentialAssignment : 13
AssignmentsParameterSupplier : 5







God Classes

Problem:God Classes take on too much responsibility,
Solution:Extract related islands of functionality into separate classes. Leave God classes that don't change often alone.

God Classes Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

God Classes by the numbers: (Refactor Starting with Priority 1)

Class Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
BlockJUnit4ClassRunner.java 1 2 1 3/14/19, 9:06 AM 104
ParentRunner.java 2 1 2 11/27/19, 1:46 PM 97







Data Classes

Problem:Data Classes are dumb data holders that other classes rely on.
Solution:Move the data/variable(s) to the same class as the operation.

Data Classes Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

Data Classes by the numbers: (Refactor Starting with Priority 1)

Class Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
Failure.java 1 1 1 2/5/17, 6:35 PM 13
FrameworkField.java 2 2 2 1/4/21, 4:01 PM 27







Refused Parent Bequest

Problem:Child class is large and often complex, but doesn't override or use many of the parent class's methods
Solution:Do one or more of the following:
- Extract the child class into a separate class. Move the methods that are used from the parent class into the child class.
- Make unused protected members private in the parent class.
- If a parent class has multiple children, move methods not used by all descendants to another class.

Refused Parent Bequest Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

Refused Parent Bequest by the numbers: (Refactor Starting with Priority 1)

Class Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
IsEqual.java 1 15 1 1/18/38, 9:14 PM 0
Theories.java 2 12 6 5/25/17, 11:19 AM 46
BlockJUnit4ClassRunner.java 3 14 9 3/14/19, 9:06 AM 104
ErrorReportingRunner.java 4 6 2 10/10/22, 3:22 PM 28
Categories.java 5 11 7 1/9/17, 9:18 PM 39
Categories.java 6 11 10 1/9/17, 9:18 PM 39
TestRunner.java 7 2 3 3/29/15, 4:17 PM 6
JUnit4ClassRunner.java 8 3 4 9/12/14, 3:18 PM 16
JUnit38ClassRunner.java 9 4 5 7/30/18, 12:07 PM 23
ParentRunner.java 10 13 14 11/27/19, 1:46 PM 97
BlockJUnit4ClassRunnerWithParameters.java 11 5 8 6/23/17, 4:16 PM 7
FailOnTimeout.java 12 9 12 12/30/21, 2:49 AM 40
TemporaryFolder.java 13 8 13 10/11/20, 9:56 AM 34
AllMembersSupplier.java 14 7 14 6/18/14, 1:42 AM 33
TestCase.java 15 1 11 10/28/16, 3:01 PM 5







Intensive Coupling

Problem:Method calls too many methods from a few unrelated classes (often in a separate package).
Solution:Move the calling method to a class more closely related to the other classes that the original method can call.

Intensive Coupling Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

Intensive Coupling by the numbers: (Refactor Starting with Priority 1)

Class Method Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
ParentRunner.java order(Orderer) 1 4 1 11/27/19, 1:46 PM 97
Theories.java validateTestMethods(List<Throwable>) 2 3 2 5/25/17, 11:19 AM 46
MethodValidator.java validateTestMethods(Class<?>,boolean) 3 1 1 6/4/15, 11:26 PM 6
AllMembersSupplier.java addMultiPointMethods(ParameterSignature,List<PotentialAssignment>) 4 2 3 6/18/14, 1:42 AM 33







Dispersed Coupling

Problem:Method calls a few methods in many classes
Solution:Reduce the size of the calling method. Extract methods from the calling method into the target classes.

Dispersed Coupling Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

Dispersed Coupling by the numbers: (Refactor Starting with Priority 1)

Class Method Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
ParentRunner.java filter(Filter) 1 14 1 11/27/19, 1:46 PM 97
Theories.java validateDataPointMethods(List<Throwable>) 2 12 3 5/25/17, 11:19 AM 46
Theories.java validateDataPointFields(List<Throwable>) 3 12 3 5/25/17, 11:19 AM 46
Throwables.java getCauseStackTraceLines(Throwable) 4 9 2 1/4/21, 4:25 PM 8
Assert.java assertThrows(String,Class<T>,ThrowingRunnable) 5 13 6 9/6/20, 12:53 PM 62
Throwables.java getTrimmedStackTraceLines(Throwable) 6 9 3 1/4/21, 4:25 PM 8
TestRunner.java start(String[]) 7 5 1 3/29/15, 4:17 PM 6
BlockJUnit4ClassRunnerWithParameters.java createTestUsingFieldInjection() 8 10 7 6/23/17, 4:16 PM 7
BaseTestRunner.java getTest(String) 9 6 4 10/14/16, 5:19 PM 9
JUnit38ClassRunner.java makeDescription(Test) 10 7 5 7/30/18, 12:07 PM 23
SpecificDataPointsSupplier.java getDataPointsMethods(ParameterSignature) 11 4 5 3/16/13, 7:30 PM 2
SpecificDataPointsSupplier.java getDataPointsFields(ParameterSignature) 12 4 5 3/16/13, 7:30 PM 2
SpecificDataPointsSupplier.java getSingleDataPointMethods(ParameterSignature) 13 4 5 3/16/13, 7:30 PM 2
SpecificDataPointsSupplier.java getSingleDataPointFields(ParameterSignature) 14 4 5 3/16/13, 7:30 PM 2







Shotgun Surgery

Problem:Method is called by many methods in many classes
Solution:- Move the method closer to the calling classes (move the behavior closer to the data) if it is small.
- If it is a large method, treat is as a Brain Method and decompose it into two or more smaller methods.

Shotgun Surgery Chart Legend:

X-Axis: Effort to refactor
Y-Axis: Relative churn
Color: Priority of what to fix first
Circle size: Priority (Visual) of what to fix first

Shotgun Surgery by the numbers: (Refactor Starting with Priority 1)

Class Method Priority Change Proneness Rank Effort Rank Most Recent Commit Date Commit Count
Description.java appendValue(Object) 1 8 2 1/18/38, 9:14 PM 0
Description.java appendDescriptionOf(SelfDescribing) 2 8 3 1/18/38, 9:14 PM 0
Matcher.java describeMismatch(Object,Description) 3 7 4 1/18/38, 9:14 PM 0
FrameworkMethod.java getName() 4 2 1 4/3/18, 9:57 PM 34
Matcher.java matches(Object) 5 7 6 1/18/38, 9:14 PM 0
Description.java appendText(String) 6 8 7 1/18/38, 9:14 PM 0
TestClass.java getAnnotatedMethods(Class<?>) 7 3 3 4/13/19, 5:49 PM 51
Statement.java evaluate() 8 1 5 10/4/12, 3:16 PM 5







Class Cycles

Class Cycles by the numbers:

Cycle Name Priority Class Count Relationship Count
JUnitCore 1 9 16
InexactComparisonCriteria 2 7 13
RuleMemberValidator$MethodMustBeARule 3 7 12
Ordering 4 6 11
Throwables 5 6 10
ComparisonFailure 6 6 11
TestResult 7 5 9
Result 8 4 7
Condition$Step 9 4 8
FilterFactories 10 4 6
ComparisonFailure$ComparisonCompactor 11 4 5
MaxHistory 12 3 4
ComparisonCompactor 13 3 3
Filterable 14 3 4
CombinableMatcher$CombinableBothMatcher 15 3 4
SelfDescribing 16 3 5
Timeout$Builder 17 2 2
Stopwatch$InternalWatcher 18 2 2
JUnit4TestAdapter 19 2 2
MultipleFailureException 20 2 2
ExpectedException$ExpectedExceptionStatement 21 2 2
TemporaryFolder$Builder 22 2 2
RunNotifier$SafeNotifier 23 2 2
AllMembersSupplier 24 2 2
FromDataPoints 25 2 2
TestedOn 26 2 2
FailOnTimeout 27 2 2
Categories 28 2 2





Largest Class Cycle : JUnitCore

Limiting number of cycles displayed to 1 to keep page load time fast

Cycle Map

Red lines represent relationships to remove.
Red nodes represent classes to remove.
Zoom in / out with your mouse wheel and click/move to drag the image.
Clicking on a node in the DOT graph (if present below) will open its source file in the repo. Right/Alt click to open in a new browser tab.


* indicates class to remove, bold text indicates relationships to remove to decompose cycle
Number of classes: 9 Number of relationships: 16
Classes Relationships
JUnitCore JUnitCore → JUnitCommandLineParseResult : 3
JUnitCore → Request : 3
Request* Request → ClassRequest : 2
Request → JUnitCore : 1*
Request → FilterRequest : 1*
Request → SortingRequest : 1*
Request → OrderingRequest : 1
OrderingRequest OrderingRequest → MemoizingRequest : 1
OrderingRequest → Request : 3*
MemoizingRequest MemoizingRequest → Request : 1*
SortingRequest SortingRequest → Request : 4
FilterRequest FilterRequest → Request : 4
ClassRequest ClassRequest → MemoizingRequest : 1
JUnitCommandLineParseResult JUnitCommandLineParseResult → Request : 8
JUnitCommandLineParseResult → FilterFactories : 1
FilterFactories FilterFactories → Request : 2

Last Published: 7/5/26, 3:54 PM