@@ -53,11 +53,7 @@ import org.utbot.framework.codegen.model.tree.CgStatement
53
53
import org.utbot.framework.codegen.model.tree.CgStaticFieldAccess
54
54
import org.utbot.framework.codegen.model.tree.CgTestMethod
55
55
import org.utbot.framework.codegen.model.tree.CgTestMethodType
56
- import org.utbot.framework.codegen.model.tree.CgTestMethodType.CRASH
57
- import org.utbot.framework.codegen.model.tree.CgTestMethodType.FAILING
58
- import org.utbot.framework.codegen.model.tree.CgTestMethodType.PARAMETRIZED
59
- import org.utbot.framework.codegen.model.tree.CgTestMethodType.SUCCESSFUL
60
- import org.utbot.framework.codegen.model.tree.CgTestMethodType.TIMEOUT
56
+ import org.utbot.framework.codegen.model.tree.CgTestMethodType.*
61
57
import org.utbot.framework.codegen.model.tree.CgTryCatch
62
58
import org.utbot.framework.codegen.model.tree.CgTypeCast
63
59
import org.utbot.framework.codegen.model.tree.CgValue
@@ -310,15 +306,13 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
310
306
assertEquality(expected, actual)
311
307
}
312
308
}
313
- .onFailure { exception ->
314
- processExecutionFailure(currentExecution, exception)
315
- }
309
+ .onFailure { exception -> processExecutionFailure(exception) }
316
310
}
317
311
else -> {} // TODO: check this specific case
318
312
}
319
313
}
320
314
321
- private fun processExecutionFailure (execution : UtExecution , exception : Throwable ) {
315
+ private fun processExecutionFailure (exception : Throwable ) {
322
316
val methodInvocationBlock = {
323
317
with (currentExecutable) {
324
318
when (this ) {
@@ -329,42 +323,36 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
329
323
}
330
324
}
331
325
332
- if (shouldTestPassWithException(execution, exception)) {
333
- testFrameworkManager.expectException(exception::class .id) {
334
- methodInvocationBlock()
335
- }
336
- methodType = SUCCESSFUL
337
-
338
- return
339
- }
340
-
341
- if (shouldTestPassWithTimeoutException(execution, exception)) {
342
- writeWarningAboutTimeoutExceeding()
343
- testFrameworkManager.expectTimeout(hangingTestsTimeout.timeoutMs) {
344
- methodInvocationBlock()
326
+ when (methodType) {
327
+ SUCCESSFUL -> error(" Unexpected successful without exception method type for execution with exception $exception " )
328
+ PASSED_EXCEPTION -> {
329
+ testFrameworkManager.expectException(exception::class .id) {
330
+ methodInvocationBlock()
331
+ }
345
332
}
346
- methodType = TIMEOUT
347
-
348
- return
349
- }
350
-
351
- when (exception) {
352
- is ConcreteExecutionFailureException -> {
353
- methodType = CRASH
354
- writeWarningAboutCrash()
333
+ TIMEOUT -> {
334
+ writeWarningAboutTimeoutExceeding()
335
+ testFrameworkManager.expectTimeout(hangingTestsTimeout.timeoutMs) {
336
+ methodInvocationBlock()
337
+ }
355
338
}
356
- is AccessControlException -> {
357
- methodType = CRASH
358
- writeWarningAboutFailureTest(exception)
359
- return
339
+ CRASH -> when (exception) {
340
+ is ConcreteExecutionFailureException -> {
341
+ writeWarningAboutCrash()
342
+ methodInvocationBlock()
343
+ }
344
+ is AccessControlException -> {
345
+ // exception from sandbox
346
+ writeWarningAboutFailureTest(exception)
347
+ }
348
+ else -> error(" Unexpected crash suite for failing execution with $exception exception" )
360
349
}
361
- else -> {
362
- methodType = FAILING
350
+ FAILING -> {
363
351
writeWarningAboutFailureTest(exception)
352
+ methodInvocationBlock()
364
353
}
354
+ PARAMETRIZED -> error(" Unexpected $PARAMETRIZED method type for failing execution with $exception exception" )
365
355
}
366
-
367
- methodInvocationBlock()
368
356
}
369
357
370
358
private fun shouldTestPassWithException (execution : UtExecution , exception : Throwable ): Boolean {
@@ -1193,9 +1181,7 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1193
1181
constructorCall(* methodArguments.toTypedArray())
1194
1182
}
1195
1183
}
1196
- .onFailure { exception ->
1197
- processExecutionFailure(currentExecution, exception)
1198
- }
1184
+ .onFailure { exception -> processExecutionFailure(exception) }
1199
1185
}
1200
1186
1201
1187
/* *
@@ -1261,6 +1247,12 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1261
1247
) {
1262
1248
thisInstance[executable](* methodArguments.toTypedArray())
1263
1249
}
1250
+
1251
+ // We need to clear scope of created variables
1252
+ // because after invocation of MUT some expressions could be changed.
1253
+ // For example, fields of object that were null could be assigned to some new objects
1254
+ // and previously created variables do not reflect these changes.
1255
+ createdFromExpressionVariables.clear()
1264
1256
}
1265
1257
else -> {} // TODO: check this specific case
1266
1258
}
@@ -1290,11 +1282,22 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1290
1282
val name = paramNames[executableId]?.get(index)
1291
1283
methodArguments + = variableConstructor.getOrCreateVariable(param, name)
1292
1284
}
1293
- rememberInitialEnvironmentState(modificationInfo)
1285
+
1286
+ if (requiresFieldStateAssertions()) {
1287
+ // we should generate field assertions only for successful tests
1288
+ // that does not break the current test execution after invocation of method under test
1289
+ rememberInitialEnvironmentState(modificationInfo)
1290
+ }
1291
+
1294
1292
recordActualResult()
1295
1293
generateResultAssertions()
1296
- rememberFinalEnvironmentState(modificationInfo)
1297
- generateFieldStateAssertions()
1294
+
1295
+ if (requiresFieldStateAssertions()) {
1296
+ // we should generate field assertions only for successful tests
1297
+ // that does not break the current test execution after invocation of method under test
1298
+ rememberFinalEnvironmentState(modificationInfo)
1299
+ generateFieldStateAssertions()
1300
+ }
1298
1301
}
1299
1302
1300
1303
if (statics.isNotEmpty()) {
@@ -1343,6 +1346,10 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1343
1346
}
1344
1347
}
1345
1348
1349
+ private fun requiresFieldStateAssertions (): Boolean =
1350
+ ! methodType.isThrowing ||
1351
+ (methodType == PASSED_EXCEPTION && ! testFrameworkManager.isExpectedExceptionExecutionBreaking)
1352
+
1346
1353
private val expectedResultVarName = " expectedResult"
1347
1354
private val expectedErrorVarName = " expectedError"
1348
1355
@@ -1373,7 +1380,8 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1373
1380
substituteStaticFields(statics, isParametrized = true )
1374
1381
1375
1382
// build this instance
1376
- thisInstance = genericExecution.stateBefore.thisInstance?.let { currentMethodParameters[CgParameterKind .ThisInstance ] }
1383
+ thisInstance =
1384
+ genericExecution.stateBefore.thisInstance?.let { currentMethodParameters[CgParameterKind .ThisInstance ] }
1377
1385
1378
1386
// build arguments for method under test and parameterized test
1379
1387
for (index in genericExecution.stateBefore.parameters.indices) {
@@ -1597,6 +1605,7 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1597
1605
private fun <R > withTestMethodScope (execution : UtExecution , block : () -> R ): R {
1598
1606
clearTestMethodScope()
1599
1607
currentExecution = execution
1608
+ determineExecutionType()
1600
1609
statesCache = EnvironmentFieldStateCache .emptyCacheFor(execution)
1601
1610
return try {
1602
1611
block()
@@ -1664,6 +1673,27 @@ internal class CgMethodConstructor(val context: CgContext) : CgContextOwner by c
1664
1673
testSet.executions.any { it.result is UtExecutionFailure }
1665
1674
1666
1675
1676
+ /* *
1677
+ * Determines [CgTestMethodType] for current execution according to its success or failure.
1678
+ */
1679
+ private fun determineExecutionType () {
1680
+ val currentExecution = currentExecution!!
1681
+
1682
+ currentExecution.result
1683
+ .onSuccess { methodType = SUCCESSFUL }
1684
+ .onFailure { exception ->
1685
+ methodType = when {
1686
+ shouldTestPassWithException(currentExecution, exception) -> PASSED_EXCEPTION
1687
+ shouldTestPassWithTimeoutException(currentExecution, exception) -> TIMEOUT
1688
+ else -> when (exception) {
1689
+ is ConcreteExecutionFailureException -> CRASH
1690
+ is AccessControlException -> CRASH // exception from sandbox
1691
+ else -> FAILING
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
+
1667
1697
private fun testMethod (
1668
1698
methodName : String ,
1669
1699
displayName : String? ,
0 commit comments