Skip to content

Commit cb723b5

Browse files
Locate inner classes tests in outer test class if JUnit4 is used (#1674)
1 parent edc1d8d commit cb723b5

File tree

4 files changed

+31
-44
lines changed

4 files changed

+31
-44
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,6 @@ object Junit4 : TestFramework(id = "JUnit4",displayName = "JUnit 4") {
409409
)
410410
}
411411

412-
val enclosedClassId = BuiltinClassId(
413-
canonicalName = "org.junit.experimental.runners.Enclosed",
414-
simpleName = "Enclosed"
415-
)
416-
417412
override val nestedClassesShouldBeStatic = true
418413

419414
override val argListClassId: ClassId

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/TestFrameworkManager.kt

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ abstract class TestFrameworkManager(val context: CgContext)
8888

8989
abstract val annotationForNestedClasses: CgAnnotation?
9090

91-
abstract val annotationForOuterClasses: CgAnnotation?
92-
9391
/**
9492
* Determines whether appearance of expected exception in test method breaks current test execution or not.
9593
*/
@@ -261,9 +259,6 @@ internal class TestNgManager(context: CgContext) : TestFrameworkManager(context)
261259
override val annotationForNestedClasses: CgAnnotation?
262260
get() = null
263261

264-
override val annotationForOuterClasses: CgAnnotation?
265-
get() = null
266-
267262
override val isExpectedExceptionExecutionBreaking: Boolean = false
268263

269264
override val timeoutArgumentName: String = "timeOut"
@@ -409,20 +404,6 @@ internal class Junit4Manager(context: CgContext) : TestFrameworkManager(context)
409404
override val annotationForNestedClasses: CgAnnotation?
410405
get() = null
411406

412-
override val annotationForOuterClasses: CgAnnotation
413-
get() {
414-
require(testFramework is Junit4) { "According to settings, JUnit4 was expected, but got: $testFramework" }
415-
return statementConstructor.annotation(
416-
testFramework.runWithAnnotationClassId,
417-
testFramework.enclosedClassId.let {
418-
when (codegenLanguage) {
419-
CodegenLanguage.JAVA -> CgGetJavaClass(it)
420-
CodegenLanguage.KOTLIN -> CgGetKotlinClass(it)
421-
}
422-
}
423-
)
424-
}
425-
426407
override val isExpectedExceptionExecutionBreaking: Boolean = true
427408

428409
override fun expectException(exception: ClassId, block: () -> Unit) {
@@ -481,13 +462,9 @@ internal class Junit5Manager(context: CgContext) : TestFrameworkManager(context)
481462
override val annotationForNestedClasses: CgAnnotation
482463
get() {
483464
require(testFramework is Junit5) { "According to settings, JUnit5 was expected, but got: $testFramework" }
484-
485465
return statementConstructor.annotation(testFramework.nestedTestClassAnnotationId)
486466
}
487467

488-
override val annotationForOuterClasses: CgAnnotation?
489-
get() = null
490-
491468
override val isExpectedExceptionExecutionBreaking: Boolean = false
492469

493470
private val assertThrows: BuiltinMethodId

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgTestClassConstructor.kt

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.utbot.framework.codegen.tree
22

33
import org.utbot.framework.UtSettings
4+
import org.utbot.framework.codegen.domain.Junit4
5+
import org.utbot.framework.codegen.domain.Junit5
46
import org.utbot.framework.codegen.domain.ParametrizedTestSource
7+
import org.utbot.framework.codegen.domain.TestNg
58
import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider
69
import org.utbot.framework.codegen.domain.context.CgContext
710
import org.utbot.framework.codegen.domain.context.CgContextOwner
@@ -77,23 +80,30 @@ open class CgTestClassConstructor(val context: CgContext) :
7780
currentTestClassContext.collectedTestClassAnnotations += it
7881
}
7982
}
80-
if (testClassModel.nestedClasses.isNotEmpty()) {
81-
testFrameworkManager.annotationForOuterClasses?.let {
82-
currentTestClassContext.collectedTestClassAnnotations += it
83-
}
84-
}
8583

8684
body = buildClassBody(currentTestClass) {
85+
val notYetConstructedTestSets = testClassModel.methodTestSets.toMutableList()
86+
8787
for (nestedClass in testClassModel.nestedClasses) {
88-
nestedClassRegions += CgRealNestedClassesRegion(
89-
"Tests for ${nestedClass.classUnderTest.simpleName}",
90-
listOf(
91-
withNestedClassScope(nestedClass) { constructTestClass(nestedClass) }
92-
)
93-
)
88+
// It is not possible to run tests for both outer and inner class in JUnit4 at once,
89+
// so we locate all test methods in outer test class for JUnit4.
90+
// see https://stackoverflow.com/questions/69770700/how-to-run-tests-from-outer-class-and-nested-inner-classes-simultaneously-in-jun
91+
// or https://stackoverflow.com/questions/28230277/test-cases-in-inner-class-and-outer-class-with-junit4
92+
when (testFramework) {
93+
Junit4 -> {
94+
notYetConstructedTestSets += collectTestSetsFromInnerClasses(nestedClass)
95+
}
96+
Junit5,
97+
TestNg -> {
98+
nestedClassRegions += CgRealNestedClassesRegion(
99+
"Tests for ${nestedClass.classUnderTest.simpleName}",
100+
listOf(withNestedClassScope(nestedClass) { constructTestClass(nestedClass) })
101+
)
102+
}
103+
}
94104
}
95105

96-
for (testSet in testClassModel.methodTestSets) {
106+
for (testSet in notYetConstructedTestSets) {
97107
updateCurrentExecutable(testSet.executableId)
98108
val currentMethodUnderTestRegions = constructTestSet(testSet) ?: continue
99109
val executableUnderTestCluster = CgMethodsCluster(
@@ -161,6 +171,15 @@ open class CgTestClassConstructor(val context: CgContext) :
161171
return if (regions.any()) regions else null
162172
}
163173

174+
private fun collectTestSetsFromInnerClasses(model: TestClassModel): List<CgMethodTestSet> {
175+
val testSets = model.methodTestSets.toMutableList()
176+
for (nestedClass in model.nestedClasses) {
177+
testSets += collectTestSetsFromInnerClasses(nestedClass)
178+
}
179+
180+
return testSets
181+
}
182+
164183
private fun processFailure(testSet: CgMethodTestSet, failure: Throwable) {
165184
codeGenerationErrors
166185
.getOrPut(testSet) { mutableMapOf() }

utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonTestFrameworkManager.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ internal class PytestManager(context: CgContext) : TestFrameworkManager(context)
5353
override val dataProviderMethodsHolder: TestClassContext get() = TODO()
5454
override val annotationForNestedClasses: CgAnnotation
5555
get() = TODO("Not yet implemented")
56-
override val annotationForOuterClasses: CgAnnotation
57-
get() = TODO("Not yet implemented")
5856

5957
override fun assertEquals(expected: CgValue, actual: CgValue) {
6058
+CgPythonAssertEquals(
@@ -86,8 +84,6 @@ internal class UnittestManager(context: CgContext) : TestFrameworkManager(contex
8684
get() = TODO()
8785
override val annotationForNestedClasses: CgAnnotation
8886
get() = TODO("Not yet implemented")
89-
override val annotationForOuterClasses: CgAnnotation
90-
get() = TODO("Not yet implemented")
9187

9288
override fun expectException(exception: ClassId, block: () -> Unit) {
9389
require(testFramework is Unittest) { "According to settings, Unittest was expected, but got: $testFramework" }

0 commit comments

Comments
 (0)