-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow J2clTestingProcessor to run on more than one J2clTestInput-annotated class per round #100
Comments
I didn't understand this. Junit4 only supports tests and test suites and we are doing the same? |
What I mean is that each This is the same with That |
Are you saying Gradle plugin need to see/process whole src/test/java from a single APT run and generate all test code in a single pass? (vs. doing that per package or per suite etc.) |
And could you share little bit on how the whole mechanism in Gradle normally works for testing and what is your plan in the J2CL case? For example, how Gradle choose which tests to run, in which grouping do they run; do they share single VM instance etc. I'm trying to understand what should fold into plugin space vs compiler space; why our instance per "user defined" test target doesn't fit here. For clarification, the change is not a big deal, it is just doesn't fit into our mental model; |
I think I may have found a better way to ask the question: If I was giving you an executable that was generating a "JavaScript" test files from a "JUnit4" test executable source (let's say if it was a Graal image), wouldn't have that worked fine? Or are we just trying to exploit the fact that this is implemented as an APT in order to gain much better performance in Gradle? |
For a standard JVM project, there's a single task to compile I haven't yet wrapped my head around how to integrate J2CL testing with Gradle, but in any case this won't be based on any existing mechanism used for JVM tests. The J2CL Maven Plugin reimplements the whole build pipeline itself (similarly to GWT) due to limitations of Maven, which conversely gives it more flexibility. It currently expects users to annotate their test classes with For Gradle, I have a task that runs Graphviz sourcedigraph {
"src/main" -> stripGwtIncompatible [label="**/*.java"]
stripGwtIncompatible [shape=box]
stripGwtIncompatible -> "<stripped sources>"
"<stripped sources>" -> compileJava
compileJava [shape=box]
compileJava -> "<compiled classes>"
compileJava -> "<generated sources>"
"src/main" -> transpileJ2cl [label="**/*.native.js"]
"<stripped sources>" -> transpileJ2cl
"<generated sources>" -> transpileJ2cl
transpileJ2cl [shape=box]
transpileJ2cl -> "<transpiled sources>"
"src/main" -> compileClosure [label="**/*.js !**/*.native.js"]
compileClosure [shape=box]
"<transpiled sources>" -> compileClosure
"src/test" -> stripTestGwtIncompatible [label="**/*.java"]
stripTestGwtIncompatible [shape=box]
stripTestGwtIncompatible -> "<stripped test sources>"
"<stripped test sources>" -> compileTestJava
"<compiled classes>" -> compileTestJava
compileTestJava [shape=box]
compileTestJava -> "<compiled test classes>"
compileTestJava -> "<generated test sources>"
"src/test" -> transpileTestJ2cl [label="**/*.native.js"]
"<compiled classes>" -> transpileTestJ2cl
"<stripped test sources>" -> transpileTestJ2cl
"<generated test sources>" -> transpileTestJ2cl
transpileTestJ2cl [shape=box]
transpileTestJ2cl -> "<transpiled test sources>"
"<compiled classes>" -> test
"<compiled test classes>" -> test
"<transpiled sources>" -> test
"<transpiled test sources>" -> test
test [shape=box]
"src/test" -> test [label="**/*.js !**/*.native.js"]
} The big unknown is how to so that "test" task, and where to put that
Putting the Now I fully understand that in Bazel the annotation processor, and even the Note that caching in Gradle works at the task level (inputs → outputs), and you cannot really generate tasks "on the fly". The above process could be split up in phases (at a minimum to generate the closure-compiled tests and then run them), and splitting further means going back to the above graph, possibly enriched further: Graphviz sourcedigraph {
"src/main" -> stripGwtIncompatible [label="**/*.java"]
stripGwtIncompatible [shape=box]
stripGwtIncompatible -> "<stripped sources>"
"<stripped sources>" -> compileJava
compileJava [shape=box]
compileJava -> "<compiled classes>"
compileJava -> "<generated sources>"
"src/main" -> transpileJ2cl [label="**/*.native.js"]
"<stripped sources>" -> transpileJ2cl
"<generated sources>" -> transpileJ2cl
transpileJ2cl [shape=box]
transpileJ2cl -> "<transpiled sources>"
"src/main" -> compileClosure [label="**/*.js !**/*.native.js"]
compileClosure [shape=box]
"<transpiled sources>" -> compileClosure
"src/test" -> stripTestGwtIncompatible [label="**/*.java"]
stripTestGwtIncompatible [shape=box]
stripTestGwtIncompatible -> "<stripped test sources>"
"<stripped test sources>" -> compileTestJava
"<compiled classes>" -> compileTestJava
compileTestJava [shape=box]
compileTestJava -> "<compiled test classes>"
compileTestJava -> "<generated test sources>"
"<compiled classes>" -> generateTests [color=red]
"<compiled test classes>" -> generateTests [color=red]
generateTests [shape=box, color=red]
generateTests -> "<generated tests>" [color=red]
"<generated tests>" [color=red]
"<generated tests>" -> compileTestClosure [color=red, label="**/test_summary.json **/*.testsuite"]
"<generated tests>" -> transpileTestJ2cl [color=red, label="**/*.java"]
"src/test" -> transpileTestJ2cl [label="**/*.native.js"]
"<compiled classes>" -> transpileTestJ2cl
"<stripped test sources>" -> transpileTestJ2cl
"<generated test sources>" -> transpileTestJ2cl
transpileTestJ2cl [shape=box]
transpileTestJ2cl -> "<transpiled test sources>"
"<transpiled sources>" -> compileTestClosure
"<transpiled test sources>" -> compileTestClosure
"src/test" -> compileTestClosure [label="**/*.js !**/*.native.js"]
compileTestClosure [shape=box, color=orange]
compileTestClosure -> "<closure compiled tests>" [color=orange]
"<closure compiled tests>" [color=orange]
"<closure compiled tests>" -> test [color=orange]
test [shape=box, color=orange]
} (here, |
Yes that was the intention! Idea is you create a J2clTestInput for every executable test unit that intended to be run together (annotation happens to be how we communicate currently) and we provide you a summary for that execution unit. Currently externally we are lacking the "open-source tool" (potentially based on Karma) that takes the code/summary and execute the test based on that (which is essentially replacement of the JVM based Junit runner). Since such tool is a shared piece, we should put that into a centralized place. But I don't have the bandwidth for that. |
One problem to note; |
Except, Gradle exposes an API to get incremental changes in source files so a task can adapt its actual action 😉 E.g. let's say you change a test case ( This is indeed very different from Bazel's more basic (but very efficient!) way of only deciding whether to run targets or not. Fwiw, I have that
Fwiw, we (Maven and Gradle plugins) would probably rather rely on calling Selenium WebDriver directly in Java anyway. |
wrt slowness I was referring to: at the end you will include all the JavaScript sources when bundling the test. Or am I missing something? |
We can have the same granularity as BTW, am I right (from how the Maven plugin works) that you do one compilation per JS file listed in the |
It is one compilation per JS file.
I think there is still misunderstanding. I'm not asking about java recompilation. I'm talking about bundled code for test execution or closure compilation. For example given Guava:
IIUC, these tests will be all defined in the same project and collect/SomeTests.java will need to bundle all src/** in the bundle right? In the Bazel case, the target granularity provides you that information by giving you independent dep graphs. Without that information, you need to supply all the project input to development bundler or compiler to process. |
The maven plugin presently runs the annotation processor first, so will get the At least for maven/gradle (unlike bazel as I understand it), this is how traditional jvm tests would operate as well - much more fine-grained assembling the classpath. In maven/gradle it is generally assumed that anything in a given java or java test directory can reference anything else in there. One further note on the current state of j2cl in maven: while you can produce a single large BUNDLE js output per
It appears this effect could also be achieved through the |
Your example is doing similarly to what I was referring. You need to run your test with all the source files even you divided into 3 chunks per test (suite + all sources on javatests + all source on java). Bazel follows your depgraph from the test since the test need to define its own dependencies instead of assuming everything in the project is a dependency (so it will only collect the source of collections, collections tests). If we were following similar, Guava testing would have taken quite longer (and probably won't even have worked?). The part I didn't understand is how did you reduce output on the order of tens of GBs by the setup you described. You included all the sources at the end? |
Yes, I was talking about closure compilation, and yes unless we have some information about file dependencies (e.g. #99, or something based on Closure internals to also include non-J2CL sources) we'll have to feed everything (suite + all sources on javatests + all sources on java) to the Closure Compiler and let it prune unneeded dependencies. |
Generating a (transpiling the generated tests works too; I'm still working on bundling and running those tests) |
Filing this as a feature request as it's related to using J2CL outside of the Bazel tooling (testing isn't supported with Bazel either anyway)
Is your feature request related to a problem? Please describe.
J2clTestingProcessor
(from//junit/generator/java/com/google/j2cl/junit/apt:junit_processor
) expects a single@J2clTestInput
-annotated class per roundj2cl/junit/generator/java/com/google/j2cl/junit/apt/J2clTestingProcessingStep.java
Line 66 in f4420bf
This works well with Bazel where the rule is to run one test class at a time, each in its own small library, but doesn't quite fit other "project-oriented" build tools.
Describe the solution you'd like
Process all annotated classes, not just one; as in Vertispan@faa8505
Describe alternatives you've considered
Technically, Maven or Gradle-based (or Sbt, Buildr, whatever) tooling (another annotation processor based on JUnit 4 annotations and/or matching all classes to find JUnit 3 tests?) could generate a JUnit 4 suite class, as the sole
@J2clTestInput
-annotated class so the processor doesn't error out.Or require that only one class is annotated, expecting that it is a JUnit 4 suite in most cases.
The text was updated successfully, but these errors were encountered: