diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractTestClassConstructor.kt index 34d4d47c0b..11ec2c751d 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractTestClassConstructor.kt @@ -17,7 +17,6 @@ import org.utbot.framework.codegen.domain.models.CgTestMethodCluster import org.utbot.framework.codegen.domain.models.CgTripleSlashMultilineComment import org.utbot.framework.codegen.domain.models.CgUtilEntity import org.utbot.framework.codegen.domain.models.CgUtilMethod -import org.utbot.framework.codegen.domain.models.SimpleTestClassModel import org.utbot.framework.codegen.domain.models.TestClassModel import org.utbot.framework.codegen.renderer.importUtilMethodDependencies import org.utbot.framework.codegen.reports.TestsGenerationReport @@ -25,8 +24,12 @@ import org.utbot.framework.codegen.services.CgNameGenerator import org.utbot.framework.codegen.services.framework.TestFrameworkManager import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.MethodId +import org.utbot.framework.plugin.api.UtExecution +import org.utbot.framework.plugin.api.UtExecutionFailure +import org.utbot.framework.plugin.api.UtExecutionSuccess import org.utbot.framework.plugin.api.UtMethodTestSet import org.utbot.framework.plugin.api.util.description +import org.utbot.framework.util.calculateSize abstract class CgAbstractTestClassConstructor(val context: CgContext): CgContextOwner by context, @@ -91,6 +94,12 @@ abstract class CgAbstractTestClassConstructor(val context: C ) { val (_, _, clustersInfo) = testSet + // `stateAfter` is not accounted here, because usually most of it is not rendered + val executionToSizeCache = testSet.executions.associateWith { execution -> + execution.stateBefore.calculateSize() + + ((execution.result as? UtExecutionSuccess)?.model?.calculateSize() ?: 1) + } + for ((clusterSummary, executionIndices) in clustersInfo) { val currentTestCaseTestMethods = mutableListOf() emptyLineIfNeeded() @@ -100,11 +109,23 @@ abstract class CgAbstractTestClassConstructor(val context: C executionIndices to false } - for (i in checkedRange) { - withExecutionIdScope(i) { - currentTestCaseTestMethods += methodConstructor.createTestMethod(testSet, testSet.executions[i]) + testSet.executions + .withIndex() + .toList() + .slice(checkedRange) + .sortedWith( + // NPE tests are rendered last, because oftentimes they are meaningless in a sense + // that they pass `null` somewhere where `null` is never passed in production + compareBy> { (_, execution) -> + if ((execution.result as? UtExecutionFailure)?.exception is NullPointerException) 1 else -1 + } + // we place "smaller" tests earlier, since they are easier to read + .thenComparingInt { (_, execution) -> executionToSizeCache.getValue(execution) } + ).forEach { (i, execution) -> + withExecutionIdScope(i) { + currentTestCaseTestMethods += methodConstructor.createTestMethod(testSet, execution) + } } - } val comments = listOf("Actual number of generated tests (${executionIndices.last - executionIndices.first}) exceeds per-method limit (${UtSettings.maxTestsPerMethodInRegion})", "The limit can be configured in '{HOME_DIR}/.utbot/settings.properties' with 'maxTestsPerMethod' property") diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/util/SizeUtils.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SizeUtils.kt index 5b10330093..d6da8d7f25 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/util/SizeUtils.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/util/SizeUtils.kt @@ -35,7 +35,7 @@ fun EnvironmentModels.calculateSize(): Int { * calculated the size for [this] model and [this] is [UtReferenceModel], then in codegen we would have already * created variable for [this] model and do not need to create it again, so size should be equal to 0. */ -private fun UtModel.calculateSize(used: MutableSet = mutableSetOf()): Int { +fun UtModel.calculateSize(used: MutableSet = mutableSetOf()): Int { if (this in used) return 0 if (this is UtReferenceModel)