pholser/junit-quickcheck

Junit-quickcheck fails for android runtime

vaioco opened this issue · 9 comments

Hi *,
trying to use quickcheck in android app as the following:

@RunWith(JUnitQuickcheck.class)
public class ExampleInstrumentedTest {
    @Property
    public void testSerialization(long a ) {
        CpuUsageInfo original = new CpuUsageInfo(a,a);
        [.....]
    } 

but the following error appears on execution:

E/TestRunner: java.lang.NoSuchMethodError: No virtual method getAnnotatedType()Ljava/lang/reflect/AnnotatedType; in class Ljava/lang/reflect/Parameter; or its super classes (declaration of 'java.lang.reflect.Parameter' appears in /apex/com.android.art/javalib/core-oj.jar)
        at com.pholser.junit.quickcheck.internal.ParameterTypeContext.forParameter(ParameterTypeContext.java:155)

By checking the android Parameter.java source code [1] I noticed the code was changed and the above virtual method was removed,
I was wondering whether it would be possible to make quickcheck compatible with the Android runtime or if the above API removed is a blocking modification.
thanks

[1] https://developer.android.com/reference/java/lang/reflect/Parameter

@vaioco Thanks for reporting this. I will investigate.

Hi, have you reached a conclusion on this question

Hello? Android doesn't support getAnnotatedType . Is there any way

My apologies -- I've found it difficult to carve out time to devote to junit-quickcheck lately.

I haven't come up with a way to address the issues with running junit-quickcheck on the Android runtime. It might be possible to offer slightly degraded service on Android if we can't come up with a suitable replacement for Parameter.getAnnotatedType(). I'll see if I can investigate some more this weekend.

I tried to make some modifications to AnnotatedType
Annotations, currently running stably on Android, but cannot generate random data for collection, Annotation for parameter types cannot be obtained because AnnotatedType is not supported, for example:

@from(LinkedListGenerator.class) List<@from(IntegerGenerator.class) Integer> i;

Do you have any good suggestions,thank you

@vaioco @zxd112355 My apologies for the delayed response. junit-quickcheck relies heavily on the AnnotatedTypes of parameters to property methods, fields, etc. Though it's a shame that the Android runtime does not offer Parameter.getAnnotatedType() and the like, I never specifically set out to have junit-quickcheck run on Android.

@jlink -- does jqwik face this issue? If not, did you do anything special to avoid or overcome it?

jlink commented

@pholser Anecdotal evidence suggests that jqwik runs on/with Android but I haven’t checked myself, and I didn’t do anything on purpose to make that work.
Setting up an Android project looks so complicated that I’d dive deeper if some is willing to provide a fully configured project setup that I can just clone.

jlink commented

@pholser I've done a bit more research and experimentation. The main things I learned:

  • The Android Java Runtime does not come with AnnotatedType and all subtypes like AnnotatedParameterizedType. All methods that return such a type or an array of it do not exist.
  • In order to at least ignore these missing features, you'll have to wrap all usages of AnnotatedType in your own type and delgate calls to the missing method to a place that can decide if you're on Android or on fully fledged Java.
  • Fully re-implementing everything behind AnnotatedType is not manageable for the poor OSS lib maintainer, so the best you can do is ignore the features that depend on AnnotatedType. In case of jqwik that would mostly be support for sophisticated generics like finding the correctly realized type for type variables and annotations on subtypes in forall-parameters.

Hope that helps to judge if going in that direction is feasible for Junit-quickcheck. For jqwik I decided to let it rest - at least for the time being.

@jlink Thanks for investigating. junit-quickcheck is pretty heavily invested in AnnotatedType and its derivatives, so if I choose to do anything, wrapping its uses might be the option to go with. I guess I got overly eager to use AnnotatedType even in places where just a Type would suffice.

I'll make some time to work on this in the coming days.