Der benutzerdefinierte JQF-Generator kann die Filialabdeckung nicht erhöhenJava

Java-Forum
Guest
 Der benutzerdefinierte JQF-Generator kann die Filialabdeckung nicht erhöhen

Post by Guest »

Ich verwende JQF+Zest zum Fuzzing.
Da ich viele verschiedene Klassen testen muss, möchte ich nicht für jede einzelne manuell einen Generator schreiben, also habe ich den folgenden einfachen generischen Generator geschrieben:

Code: Select all

package caohch1;

import com.pholser.junit.quickcheck.generator.Generator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
import com.pholser.junit.quickcheck.generator.GenerationStatus;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

public class GenericGenerator extends Generator {
private final Class type;

public GenericGenerator(Class type) {
super(type);
this.type = type;
}

@Override
public T generate(SourceOfRandomness random, GenerationStatus status) {
random.nextBytes(4); // Consume some random bytes for JQF

try {
T instance = createInstance(random);
if (instance != null) {
populateFields(instance, random);
}
return instance;
} catch (Exception e) {
return null;
}
}

private T createInstance(SourceOfRandomness random) {
Constructor[] constructors = type.getDeclaredConstructors();
Arrays.sort(constructors, (c1, c2) ->
Integer.compare(c1.getParameterCount(), c2.getParameterCount()));

for (Constructor constructor : constructors) {
constructor.setAccessible(true);
try {
Class[] paramTypes = constructor.getParameterTypes();
Object[] params = new Object[paramTypes.length];

for (int i = 0; i < paramTypes.length; i++) {
params[i] = generateRandomValue(paramTypes[i], random);
}

@SuppressWarnings("unchecked")
T instance = (T) constructor.newInstance(params);
return instance;
} catch (Exception e) {
continue;
}
}
return null;
}

private void populateFields(T instance, SourceOfRandomness random) {
try {
for (Field field : instance.getClass().getFields()) {
if (!Modifier.isStatic(field.getModifiers()) &&
!Modifier.isFinal(field.getModifiers())) {
Object value = generateRandomValue(field.getType(), random);
if (value != null) {
field.set(instance, value);
}
}
}
} catch (Exception e) {
// Ignore field population errors
}
}

private Object generateRandomValue(Class type, SourceOfRandomness random) {
random.nextBytes(1);

if (type == int.class || type == Integer.class) {
return random.nextInt();
}
if (type == long.class || type == Long.class) {
return random.nextLong();
}
if (type == boolean.class || type == Boolean.class) {
return random.nextBoolean();
}
if (type == byte.class || type == Byte.class) {
return random.nextByte(Byte.MIN_VALUE, Byte.MAX_VALUE);
}
if (type == char.class || type == Character.class) {
return (char) random.nextChar(Character.MIN_VALUE, Character.MAX_VALUE);
}
if (type == double.class || type == Double.class) {
return random.nextDouble();
}
if (type == float.class || type == Float.class) {
return random.nextFloat();
}
if (type == String.class) {
int length = random.nextInt(); // Example length, adjust as needed
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length;  i++) {
sb.append(random.nextChar(Character.MIN_VALUE, Character.MAX_VALUE));
}

return sb.toString();
}
if (type.isEnum()) {
Object[] constants = type.getEnumConstants();
return constants[random.nextInt(constants.length)];
}
if (List.class.isAssignableFrom(type)) {
return new ArrayList();
}
if (Set.class.isAssignableFrom(type)) {
return new HashSet();
}
if (Map.class.isAssignableFrom(type)) {
return new HashMap();
}

try {
return new GenericGenerator(type).generate(random, null);
} catch (Exception e) {
return null;
}
}
}
Ich verwende einen einfachen Fall, um diesen Generator zu testen

Code: Select all

public class Test {
@Fuzz
public void fuzzLocalDateTime(@From(GenericGenerator.class) String var1, @From(GenericGenerator.class) String var2) throws IllegalArgumentException, DateTimeParseException {
LocalDateTime.parse(var1, DateTimeFormatter.ofPattern(var2));
}
}
Nachdem ich jedoch ../bin/jqf-zest -c "$DEPENDENCY": ausgeführt habe. Testen Sie fuzzLocalDateTime. Ich beobachte, dass die Codeabdeckung hängen bleibt und sich nicht wie folgt erhöht

Code: Select all

Semantic Fuzzing with Zest
--------------------------

Test name:            Test#fuzzLocalDateTime
Instrumentation:      Janala
Results directory:    ...../fuzz-results
Elapsed time:         9s (no time limit)
Number of executions: 11,578 (no trial limit)
Valid inputs:         11,578 (100.00%)
Cycles completed:     10
Unique failures:      0
Queue size:           3 (1 favored last cycle)
Current parent input: 0 (favored) {627/1000 mutations}
Execution speed:      2,116/sec now | 1,178/sec overall
Total coverage:       147 branches (0.22% of map)
Valid coverage:       147 branches (0.22% of map)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post