@@ -3,28 +3,14 @@ package org.utbot.external.api
3
3
import org.utbot.common.FileUtil
4
4
import org.utbot.common.nameOfPackage
5
5
import org.utbot.framework.UtSettings
6
- import org.utbot.framework.codegen.domain.ForceStaticMocking
7
- import org.utbot.framework.codegen.domain.Junit5
8
- import org.utbot.framework.codegen.domain.NoStaticMocking
9
- import org.utbot.framework.codegen.domain.ProjectType
10
- import org.utbot.framework.codegen.domain.StaticsMocking
11
- import org.utbot.framework.codegen.domain.TestFramework
12
- import org.utbot.framework.codegen.generator.CodeGenerator
6
+ import org.utbot.framework.codegen.domain.*
13
7
import org.utbot.framework.codegen.generator.CodeGeneratorParams
14
8
import org.utbot.framework.codegen.services.language.CgLanguageAssistant
15
- import org.utbot.framework.context.simple.SimpleApplicationContext
9
+ import org.utbot.framework.context.ApplicationContext
16
10
import org.utbot.framework.context.utils.transformValueProvider
17
11
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData
18
12
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
19
13
import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
20
- import org.utbot.framework.plugin.api.ClassId
21
- import org.utbot.framework.plugin.api.CodegenLanguage
22
- import org.utbot.framework.plugin.api.MockFramework
23
- import org.utbot.framework.plugin.api.MockStrategyApi
24
- import org.utbot.framework.plugin.api.TestCaseGenerator
25
- import org.utbot.framework.plugin.api.UtMethodTestSet
26
- import org.utbot.framework.plugin.api.UtPrimitiveModel
27
- import org.utbot.framework.plugin.api.UtSymbolicExecution
28
14
import org.utbot.framework.plugin.api.util.UtContext
29
15
import org.utbot.framework.plugin.api.util.executableId
30
16
import org.utbot.framework.plugin.api.util.id
@@ -36,26 +22,53 @@ import org.utbot.framework.plugin.api.util.stringClassId
36
22
import org.utbot.framework.plugin.api.util.withUtContext
37
23
import org.utbot.framework.plugin.api.util.wrapperByPrimitive
38
24
import org.utbot.framework.plugin.services.JdkInfoDefaultProvider
39
- import org.utbot.fuzzer.FuzzedType
40
25
import org.utbot.fuzzer.FuzzedValue
41
- import org.utbot.fuzzing.FuzzedDescription
42
26
import org.utbot.fuzzing.JavaValueProvider
43
27
import org.utbot.fuzzing.Seed
44
- import org.utbot.fuzzing.ValueProvider
45
28
import org.utbot.instrumentation.ConcreteExecutor
46
29
import org.utbot.instrumentation.execute
47
- import org.utbot.instrumentation.instrumentation.execution.SimpleUtExecutionInstrumentation
48
- import java.io.File
49
30
import kotlin.reflect.jvm.kotlinFunction
31
+ import org.utbot.framework.codegen.domain.StaticsMocking
32
+ import org.utbot.framework.plugin.api.*
33
+ import java.lang.reflect.Method
50
34
51
35
object UtBotJavaApi {
52
36
37
+ /* *
38
+ * For running tests it could be reasonable to reuse the same concrete executor
39
+ */
53
40
@JvmStatic
54
41
var stopConcreteExecutorOnExit: Boolean = true
55
42
43
+ /* *
44
+ * Generates test code
45
+ * @param methodsForGeneration specify methods that are supposed to be executed concretely.
46
+ * In order to execute method you are supposed to provide some
47
+ * values to pass in it this is why we use [TestMethodInfo] here.
48
+ * @param generatedTestCases specify [UtMethodTestSet]s that are used for test code
49
+ * generation. By comparison with the first parameter,
50
+ * {@code UtMethodTestSet} contains more information about
51
+ * test, including result of the executions. Note, that
52
+ * you can get the object with any sort of analysis,
53
+ * for instance, symbolic or fuzz execution.
54
+ * @param destinationClassName the name of containing class for the generated tests
55
+ * @param classpath classpath that are used to build the class under test
56
+ * @param dependencyClassPath class path including dependencies required for the code generation
57
+ * @param classUnderTest for this class test should be generated
58
+ * @param projectType JVM, Spring, Python, or other type of project
59
+ * @param testFramework test framework that is going to be used for running generated tests
60
+ * @param mockFramework framework that will be used in the generated tests
61
+ * @param codegenLanguage the target language of the test generation. It can be different from the source language.
62
+ * @param staticsMocking the approach to the statics mocking
63
+ * @param generateWarningsForStaticMocking enable generation of warning about forced static mocking in comments
64
+ * of generated tests.
65
+ * @param forceStaticMocking enables static mocking
66
+ * @param testClassPackageName package name for the generated class with the tests
67
+ * @param applicationContext specify application context here
68
+ */
56
69
@JvmStatic
57
70
@JvmOverloads
58
- fun generate (
71
+ fun generateTestCode (
59
72
methodsForGeneration : List <TestMethodInfo >,
60
73
generatedTestCases : List <UtMethodTestSet > = mutableListOf(),
61
74
destinationClassName : String ,
@@ -69,16 +82,18 @@ object UtBotJavaApi {
69
82
staticsMocking : StaticsMocking = NoStaticMocking ,
70
83
generateWarningsForStaticMocking : Boolean = false,
71
84
forceStaticMocking : ForceStaticMocking = ForceStaticMocking .DO_NOT_FORCE ,
72
- testClassPackageName : String = classUnderTest.nameOfPackage
85
+ testClassPackageName : String = classUnderTest.nameOfPackage,
86
+ applicationContext : ApplicationContext
73
87
): String {
74
88
75
- val utContext = UtContext (classUnderTest.classLoader)
76
-
77
89
val testSets: MutableList <UtMethodTestSet > = generatedTestCases.toMutableList()
78
90
79
91
val concreteExecutor = ConcreteExecutor (
80
- SimpleUtExecutionInstrumentation .Factory (pathsToUserClasses = classpath.split(File .pathSeparator).toSet()),
81
- classpath,
92
+ applicationContext.createConcreteExecutionContext(
93
+ fullClasspath = dependencyClassPath,
94
+ classpathWithoutDependencies = classpath
95
+ ).instrumentationFactory,
96
+ classpath
82
97
)
83
98
84
99
testSets.addAll(generateUnitTests(concreteExecutor, methodsForGeneration, classUnderTest))
@@ -87,8 +102,8 @@ object UtBotJavaApi {
87
102
concreteExecutor.close()
88
103
}
89
104
90
- return withUtContext(utContext ) {
91
- val codeGenerator = CodeGenerator (
105
+ return withUtContext(UtContext (classUnderTest.classLoader) ) {
106
+ applicationContext.createCodeGenerator (
92
107
CodeGeneratorParams (
93
108
classUnderTest = classUnderTest.id,
94
109
projectType = projectType,
@@ -99,11 +114,9 @@ object UtBotJavaApi {
99
114
staticsMocking = staticsMocking,
100
115
forceStaticMocking = forceStaticMocking,
101
116
generateWarningsForStaticMocking = generateWarningsForStaticMocking,
102
- testClassPackageName = testClassPackageName
117
+ testClassPackageName = testClassPackageName,
103
118
)
104
- )
105
-
106
- codeGenerator.generateAsString(testSets, destinationClassName)
119
+ ).generateAsString(testSets, destinationClassName)
107
120
}
108
121
}
109
122
@@ -114,29 +127,36 @@ object UtBotJavaApi {
114
127
*/
115
128
@JvmStatic
116
129
@JvmOverloads
117
- fun generateTestSets (
118
- methodsForAutomaticGeneration : List <TestMethodInfo >,
130
+ fun generateTestSetsForMethods (
131
+ methodsToAnalyze : List <Method >,
119
132
classUnderTest : Class <* >,
120
133
classpath : String ,
121
134
dependencyClassPath : String ,
122
135
mockStrategyApi : MockStrategyApi = MockStrategyApi .OTHER_PACKAGES ,
123
- generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis
136
+ generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis,
137
+ applicationContext : ApplicationContext
124
138
): MutableList <UtMethodTestSet > {
125
139
140
+ assert (methodsToAnalyze.all {classUnderTest.declaredMethods.contains(it)})
141
+ { " Some methods are absent in the ${classUnderTest.name} class." }
142
+
126
143
val utContext = UtContext (classUnderTest.classLoader)
127
144
val testSets: MutableList <UtMethodTestSet > = mutableListOf ()
128
145
129
146
testSets.addAll(withUtContext(utContext) {
130
147
val buildPath = FileUtil .isolateClassFiles(classUnderTest).toPath()
131
- TestCaseGenerator (listOf (buildPath), classpath, dependencyClassPath, jdkInfo = JdkInfoDefaultProvider ().info)
132
- .generate(
133
- methodsForAutomaticGeneration.map {
134
- it.methodToBeTestedFromUserInput.executableId
135
- },
136
- mockStrategyApi,
137
- chosenClassesToMockAlways = emptySet(),
138
- generationTimeoutInMillis
139
- )
148
+ TestCaseGenerator (
149
+ listOf (buildPath),
150
+ classpath,
151
+ dependencyClassPath,
152
+ jdkInfo = JdkInfoDefaultProvider ().info,
153
+ applicationContext = applicationContext
154
+ ).generate(
155
+ methodsToAnalyze.map { it.executableId },
156
+ mockStrategyApi,
157
+ chosenClassesToMockAlways = emptySet(),
158
+ generationTimeoutInMillis
159
+ )
140
160
})
141
161
142
162
return testSets
@@ -145,19 +165,24 @@ object UtBotJavaApi {
145
165
/* *
146
166
* Generates test cases using only fuzzing workflow.
147
167
*
148
- * @see [generateTestSets ]
168
+ * @see [generateTestSetsForMethods ]
149
169
*/
150
170
@JvmStatic
151
171
@JvmOverloads
152
172
fun fuzzingTestSets (
153
- methodsForAutomaticGeneration : List <TestMethodInfo >,
173
+ methodsToAnalyze : List <Method >,
154
174
classUnderTest : Class <* >,
155
175
classpath : String ,
156
176
dependencyClassPath : String ,
157
177
mockStrategyApi : MockStrategyApi = MockStrategyApi .OTHER_PACKAGES ,
158
178
generationTimeoutInMillis : Long = UtSettings .utBotGenerationTimeoutInMillis,
159
- primitiveValuesSupplier : CustomFuzzerValueSupplier = CustomFuzzerValueSupplier { null }
179
+ primitiveValuesSupplier : CustomFuzzerValueSupplier = CustomFuzzerValueSupplier { null },
180
+ applicationContext : ApplicationContext
160
181
): MutableList <UtMethodTestSet > {
182
+
183
+ assert (methodsToAnalyze.all {classUnderTest.declaredMethods.contains(it)})
184
+ { " Some methods are absent in the ${classUnderTest.name} class." }
185
+
161
186
fun createPrimitiveModels (supplier : CustomFuzzerValueSupplier , classId : ClassId ): Sequence <UtPrimitiveModel > =
162
187
supplier
163
188
.takeIf { classId.isPrimitive || classId.isPrimitiveWrapper || classId == stringClassId }
@@ -189,14 +214,12 @@ object UtBotJavaApi {
189
214
classpath,
190
215
dependencyClassPath,
191
216
jdkInfo = JdkInfoDefaultProvider ().info,
192
- applicationContext = SimpleApplicationContext () .transformValueProvider { defaultModelProvider ->
217
+ applicationContext = applicationContext .transformValueProvider { defaultModelProvider ->
193
218
customModelProvider.withFallback(defaultModelProvider)
194
219
}
195
220
)
196
221
.generate(
197
- methodsForAutomaticGeneration.map {
198
- it.methodToBeTestedFromUserInput.executableId
199
- },
222
+ methodsToAnalyze.map{ it.executableId },
200
223
mockStrategyApi,
201
224
chosenClassesToMockAlways = emptySet(),
202
225
generationTimeoutInMillis,
0 commit comments