Skip to content

Locate inner classes tests in outer test class if JUnit4 is used #1674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,6 @@ object Junit4 : TestFramework(id = "JUnit4",displayName = "JUnit 4") {
)
}

val enclosedClassId = BuiltinClassId(
canonicalName = "org.junit.experimental.runners.Enclosed",
simpleName = "Enclosed"
)

override val nestedClassesShouldBeStatic = true

override val argListClassId: ClassId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ abstract class TestFrameworkManager(val context: CgContext)

abstract val annotationForNestedClasses: CgAnnotation?

abstract val annotationForOuterClasses: CgAnnotation?

/**
* Determines whether appearance of expected exception in test method breaks current test execution or not.
*/
Expand Down Expand Up @@ -261,9 +259,6 @@ internal class TestNgManager(context: CgContext) : TestFrameworkManager(context)
override val annotationForNestedClasses: CgAnnotation?
get() = null

override val annotationForOuterClasses: CgAnnotation?
get() = null

override val isExpectedExceptionExecutionBreaking: Boolean = false

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

override val annotationForOuterClasses: CgAnnotation
get() {
require(testFramework is Junit4) { "According to settings, JUnit4 was expected, but got: $testFramework" }
return statementConstructor.annotation(
testFramework.runWithAnnotationClassId,
testFramework.enclosedClassId.let {
when (codegenLanguage) {
CodegenLanguage.JAVA -> CgGetJavaClass(it)
CodegenLanguage.KOTLIN -> CgGetKotlinClass(it)
}
}
)
}

override val isExpectedExceptionExecutionBreaking: Boolean = true

override fun expectException(exception: ClassId, block: () -> Unit) {
Expand Down Expand Up @@ -481,13 +462,9 @@ internal class Junit5Manager(context: CgContext) : TestFrameworkManager(context)
override val annotationForNestedClasses: CgAnnotation
get() {
require(testFramework is Junit5) { "According to settings, JUnit5 was expected, but got: $testFramework" }

return statementConstructor.annotation(testFramework.nestedTestClassAnnotationId)
}

override val annotationForOuterClasses: CgAnnotation?
get() = null

override val isExpectedExceptionExecutionBreaking: Boolean = false

private val assertThrows: BuiltinMethodId
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.utbot.framework.codegen.tree

import org.utbot.framework.UtSettings
import org.utbot.framework.codegen.domain.Junit4
import org.utbot.framework.codegen.domain.Junit5
import org.utbot.framework.codegen.domain.ParametrizedTestSource
import org.utbot.framework.codegen.domain.TestNg
import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider
import org.utbot.framework.codegen.domain.context.CgContext
import org.utbot.framework.codegen.domain.context.CgContextOwner
Expand Down Expand Up @@ -77,23 +80,30 @@ open class CgTestClassConstructor(val context: CgContext) :
currentTestClassContext.collectedTestClassAnnotations += it
}
}
if (testClassModel.nestedClasses.isNotEmpty()) {
testFrameworkManager.annotationForOuterClasses?.let {
currentTestClassContext.collectedTestClassAnnotations += it
}
}

body = buildClassBody(currentTestClass) {
val notYetConstructedTestSets = testClassModel.methodTestSets.toMutableList()

for (nestedClass in testClassModel.nestedClasses) {
nestedClassRegions += CgRealNestedClassesRegion(
"Tests for ${nestedClass.classUnderTest.simpleName}",
listOf(
withNestedClassScope(nestedClass) { constructTestClass(nestedClass) }
)
)
// It is not possible to run tests for both outer and inner class in JUnit4 at once,
// so we locate all test methods in outer test class for JUnit4.
// see https://stackoverflow.com/questions/69770700/how-to-run-tests-from-outer-class-and-nested-inner-classes-simultaneously-in-jun
// or https://stackoverflow.com/questions/28230277/test-cases-in-inner-class-and-outer-class-with-junit4
when (testFramework) {
Junit4 -> {
notYetConstructedTestSets += collectTestSetsFromInnerClasses(nestedClass)
}
Junit5,
TestNg -> {
nestedClassRegions += CgRealNestedClassesRegion(
"Tests for ${nestedClass.classUnderTest.simpleName}",
listOf(withNestedClassScope(nestedClass) { constructTestClass(nestedClass) })
)
}
}
}

for (testSet in testClassModel.methodTestSets) {
for (testSet in notYetConstructedTestSets) {
updateCurrentExecutable(testSet.executableId)
val currentMethodUnderTestRegions = constructTestSet(testSet) ?: continue
val executableUnderTestCluster = CgMethodsCluster(
Expand Down Expand Up @@ -161,6 +171,15 @@ open class CgTestClassConstructor(val context: CgContext) :
return if (regions.any()) regions else null
}

private fun collectTestSetsFromInnerClasses(model: TestClassModel): List<CgMethodTestSet> {
val testSets = model.methodTestSets.toMutableList()
for (nestedClass in model.nestedClasses) {
testSets += collectTestSetsFromInnerClasses(nestedClass)
}

return testSets
}

private fun processFailure(testSet: CgMethodTestSet, failure: Throwable) {
codeGenerationErrors
.getOrPut(testSet) { mutableMapOf() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ internal class PytestManager(context: CgContext) : TestFrameworkManager(context)
override val dataProviderMethodsHolder: TestClassContext get() = TODO()
override val annotationForNestedClasses: CgAnnotation
get() = TODO("Not yet implemented")
override val annotationForOuterClasses: CgAnnotation
get() = TODO("Not yet implemented")

override fun assertEquals(expected: CgValue, actual: CgValue) {
+CgPythonAssertEquals(
Expand Down Expand Up @@ -86,8 +84,6 @@ internal class UnittestManager(context: CgContext) : TestFrameworkManager(contex
get() = TODO()
override val annotationForNestedClasses: CgAnnotation
get() = TODO("Not yet implemented")
override val annotationForOuterClasses: CgAnnotation
get() = TODO("Not yet implemented")

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