Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Speeding up the code-test cycle for Java developers
69 points by artpar on May 17, 2023 | hide | past | favorite | 15 comments
Hello HN, I am Parth. In my experience, the current form of testing automation takes too long. To solve this, I am creating a developer tool to speed up the code-test cycle for Java developers. It has two main parts:

Direct Invoke - lets you call any Java function directly, without the need to execute the whole call hierarchy. (e.g. an HTTP endpoint) In my normal coding workflow, I use the “Evaluate Expression” feature inside IntelliJ IDE. I usually put a breakpoint somewhere in the code and after hitting the breakpoint by calling an HTTP api, let the execution remain paused while I explore and see the return values of functions. “Evaluate Expression” was quite useful in exploring new codebases and checking return values of my own functions as a sanity test. The direct invoke feature implements the same functionality without needing to hit a breakpoint. Now, I can just navigate to any function in the editor and execute it. The parameter values are input as JSON and deserialize to an object of the required class instances.

Atomic Run - lets you hot-reload the code changes and highlights the difference in the return values of the changed function before and after the hot-reload. I feel Atomic Run has the potential of replacing unit test cases, but there is a long way to go. I am thinking of implementing

  - Option for mocking dependency calls: We want to give the developer more control over the testing environment by allowing them to mock downstream dependency calls.


  - Customizing assertions: Not all differences in return values indicate breaking changes. Assertions should be flexible to accommodate non-breaking changes.


  - Workflow to save this data to a file (thinking something like JSON based fixtures): making it easier to organize and reuse test data.

This plugin is still in the early stages, so we'd appreciate your help in ironing out any bugs you come across. Get in touch with me on my discord channel.

To try it out, install Unlogged from the IntelliJ Marketplace and start your java application using the java agent (the plugin has instructions to download)

Link to try the plugin: https://plugins.jetbrains.com/plugin/18529-unlogged




That's really cool. I think there's still a lot of untapped potential in Java & Kotlin tooling, despite how far ahead of most other languages the IDE story is there anyway.

Your HTTP use case was a good one as that is still very tedious generally. There are some less well integrated solutions that have come up from time to time, but in general being able to run the HTTP request once and from then on mock the request/result easily would be great.

Hot reload seems to be something that comes and goes. Android Studio has had it and then not had it and then had it again several times. The cases in which it works seem to be fairly arbitrary. Improvements in this space would be great.


Yeah I understand what you mean when you say hot reloading is something that comes and goes. There are a variety of edge cases even though there is increasing support from the jvm vendors and also jrebel has been done a lot of work in that direction. We are trying to rely on those efforts for atomic run difference detectors. In our internal testing we figured that for method level changes even the default jvm vendor based hot reloading works to a great extent for most modern stacks (spring/dropwizard/play framework) .

About android, just want to point out that our current builds are not compatible with android since dalvik has different ways of working (register based) compared to desktop jvms (stack based)


Hey HN, I am Shardul - I am the other co-founder. Link to try the plugin: https://plugins.jetbrains.com/plugin/18529-unlogged

Connect with us: https://discord.gg/Hhwvay8uTa

Atomic Run & Direct Invoke Demo: https://www.youtube.com/watch?v=W0hAWx8EXcY

Happy to answer any questions you may have.


> without the need to execute the whole call hierarchy. (e.g. an HTTP endpoint)... > “Evaluate Expression” was quite useful in exploring new codebases and checking return values of my own functions as a sanity test.

Keep pulling on this thread... pretty soon you'll be writing unit tests!


I just mentioned this in another response but will say this again, generating junit test cases is what we started doing in the first place.

We have still have that in the plugin. If you are interested I can share a custom build with that enabled for you to try it out. Just send me an email or ping us on the discord group.

We also have a boilerplate test case generator which uses dummy values, and this one you can use even without using the java agent. Its the first tab you will see in the plugin window after installing.


Isn't this just reinventing the wheel and just replicating a built in IDE feature? I.e. what is wrong with Intellij's existing right click-execute on a single junit test method to debug and inspecting variables that way?

Also this is seems to be unit testing, E2E (or to be precise "component") testing in my experience is what takes much longer and is where time is lost constructing the fixtures, but importantly E2E tells you if you've made stupid mistakes like using GET instead of POST, or have an XML serialiser overriding the JSON one you intended, which you don't pick up in unit tests.

Now if you could somehow save an entire VM stack/state of a system for E2E tests that wasn't brittle to code change, that could just rebuild that state with a single line of code, that would be my dream time saver. The closest I've seen anything like that is recording HTTP request responses or serialising individual Java objects to JSON and using those as fixtures...


> I.e. what is wrong with Intellij's existing right click-execute on a single junit test method to debug and inspecting variables that way?

There is definitely nothing wrong with it if there are unit test cases available. But there is some extent of context switching in the current code-test cycle. And in the worst case scenario there are no test cases altogether and the team would rely on sanity testing + qa testing, eventually leading to some regressions on production. So you would be able to do the same thing with Atomic Run which you are doing currently with junit test cases but faster.

> Isn't this just reinventing the wheel and just replicating a built in IDE feature?

There is an overlap of functionality but no reinventing of wheel for sure. What we are trying to invent is construction of test cases itself without them being in the form of a junit test case (which is a maintenance overhead)

> Also this is seems to be unit testing, E2E (or to be precise "component") testing in my experience is what takes much longer and is where time is lost constructing the fixtures, but importantly E2E tells you if you've made stupid mistakes like using GET instead of POST, or have an XML serialiser overriding the JSON one you intended, which you don't pick up in unit tests.

So this is actually E2E testing and not unit testing because we don't have the capability of mocking down stream calls. If you do a Atomic Run on method1 which calls method2 and method3 on a different service, the method2/method3 would still be invoked and the outcome would depend on their response. Once we have the downstream mocking ready then it would be a unit test.

> Now if you could somehow save an entire VM stack/state of a system for E2E tests that wasn't brittle to code change, that could just rebuild that state with a single line of code, that would be my dream time saver. The closest I've seen anything like that is recording HTTP request responses or serialising individual Java objects to JSON and using those as fixtures...

Believe me this is what we started doing in the first place, and we have still have that in the plugin. It is just hidden from the UI since we received a mediocre response on generating junit test cases (maintenance headache). So we trimmed it down to the current form. If you are interested I can share a custom build with that enabled for you to try it out. Just send me an email or ping us on the discord group.


when i want to play with java stuff interactively i just actually open it up in clojure repl


A jshell session can also work for that, but IntelliJ doesn’t add all your classes to the module path so jshell doesn’t usually know about them, which is a big oversight IMO.


You can provide the classpath to the jshell (usually jshell -c target/classes) and with that jshell can locate your compiled classes.

But you will have to create the instances of your target class object (plus all of its dependencies) which is going to be really cumbersome.

Consider a Spring service class which uses another redis service and a database service and you want to call a method on this service. So now you have to create the redis service first (copy/paste their config values etc), then the database service and then the actual spring service you want to test.

Once you have created the service, now you need to create the parameter values required by your target method, which you would either create using a new Xyz(), variable.setX, setY and so on, or alternatively now try to import a JSON mapper (ok so now we need to add the classpath to the dependencies as well), and then reconstruct the parameter with objectMapper.readValueAsString("{json here}", Xyz.class);

You can see how this gets unnecessarily complicated depending on the project you are working with.

So with direct invoke you have all the class instances ready in the correct state and you can just call a function. The service classes are being setup by your start up procedure anyways. And for the parameters we are currently using the objectMapper approach so its all setup and ready to use.


I have actually never used clojure repl, I'll check it out. How does it work with application code ? Or is it for Java SDK ?

I encourage you to give this a try, surely this should be less context switching if you are using intellij as your ide.


You can open a Clojure REPL in IntelliJ. But, you need nrepl running in your server/running Clojure


The reloading part reminded me about https://www.jrebel.com/


Right, we are not doing anything in the hot reloading area. We are depending on either the jvm vendor provided hot reloading or jrebel


An extremely complicated solution for a problem which does not actually exist.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: