Last week I had to debug some unstable tests, which were only launched externally from Ant (launched from Maven). The tests were largely not directly runnable from the IDE, and did not run equivalently.
Obviously this is outdated practice and not good TDD, but sometimes we need to work with such assets anyway š
Given that, how could I debug & fix these tests?
Go to the Tools
My go-to when trying to reproduce a process (such as TestNG run from Ant run from Maven), is replicate the process launch independently.
Once I’ve can replicate & control the JVM launch, it should be easy to add debug parameters and attach the IDE debugger to it.
My go-to tool for capturing process launches (Windows) is SysInternals Process Explorer.This is an uber-tool for process monitoring & management on Windows, written my Microsoft guru MarkĀ Russinovich.
Capturing the Process Launch
- launch the top-level process (Maven & Ant in this case).
- pause the console once TestNG is running.
- Ā open Process Explorer.
- use the cross-hairs & drag to the target window to find your process. (In the case of a child process, the deepest nested ‘java.exe’ JVM will be the process you are after.)
- right-click it and choose Properties.
- the ‘Image’ tab shows the command-line. Copy it to a text editor.
Note that rarely, a command-line may have line-breaks in it & not be fully visible — this happened to me. Use Home and Shift-End to select all and paste to a text editor.
Reproducing the Process Launch
This is conceptually pretty easy. You just save the process command-line as a .bat file.
In my case (TestNG launch) TestNG was also using some temporary file to pass a few parameters, so I also copied that to a file under my control & updated the command-line to reference that.
I then added JVM debug parameters to the command-line, created a debug configuration in my IDE, and voila!Ā Problem reproduced & able to be solved.
Batch file ‘run-like-ant.bat’ excerpt below:
@rem reproduce TestNG execution as though from Maven & Ant @rem C:\Dev\jdk1.8.0_131\jre\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=y -ea -Doracle.jdbc.timezoneAsRegion=false -classpath C:\Workspace\trunk\sqlb\ant\test;C:\Workspace\trunk\sqlb\test;C:\Workspace\trunk\sqlb\test\conf;C:\Workspace\trunk\sqlb\test\conf\props;C:\Workspace\trunk\sqlb\test\data;etc;etcĀ org.testng.TestNG @run-like-ant-testng.params