This is a Maven project. Its purpose is to automatically generate unit tests basing on real-time execution data, captured using Aspect Oriented Programming techniques. It can also replay the same execution over and over. It is therefore split over 3 modules (Recording, Replaying, Test-Generation), a "common" module and a test-cases module.
This project is still under quick-and-dirty development, and therefore many classes are NOT written as I would like to, and again... that is why this repository is not public yet, as it would be "impossible" to manage contributions from different people. Before going out in the wild this project needs:
- Single-responsibility patterns and separation of concerns (e.g. TestMethodsWriter class completely refactored).
- Comments on most methods and several chunks of code.
Run these sections in sequence:
- SETUP
- RECORDING
- REPLAYING
- GENERATING TESTS
- Open a shell to the root of Montezuma and issue the commands:
a. mvn eclipse:clean
b. mvn eclipse:eclipse - In Eclipse import Montezuma as Existing Maven Project (File --> Import... --> Maven --> Existing Maven Projects)
- Open Eclipse's preferences, navigate to Java —> Compiler —> Errors/Warnings —> Deprecated and restricted API, and set "Forbidden reference (access rules):" to Warning or Ignore. This will be required until the project will start using Objenesis.
No exceptions are expected to appear in the console output during the following steps, but red lines should appear due to AspectJ logging.
- In Eclipse navigate to montezuma-cases/src/main/java/org/montezuma/test/traffic/recording/cases/RecordAll.java (or any in that same package), right-click on it and Run As... Java Application. It will run without recording execution data.
- Change the last Run Configuration (Menu Run --> Run Configurations...) to add VM arguments (Arguments tab --> VM arguments): add "-javaagent:/Users/username/.m2/repository/org/aspectj/aspectjweaver/1.8.6/aspectjweaver-1.8.6.jar" without double-quotes; change the path (username) and versions according to what you have on your PC.
- Run the RecordAll.java class again. It should run recording the execution data. To check that, check the montezuma-cases/recordings directory. It should now not be empty any more.
- You can replay the executions by running as Java Application: montezuma-cases/src/main/java/org/montezuma/test/traffic/replaying/cases/ReplayAll.java (it doesn't need extra VM arguments)
- Run as Java Application montezuma-cases/src/main/java/org/montezuma/test/traffic/writing/cases/WriteAllMocking.java
- Refresh the montezuma-cases/src/generatedtests folder. A 'java' subfolder should appear.
- Right-click on the appeared 'java', click on Build Path --> Use as Source Folder. The new source folder will contain the generated test classes, possibly with compile-time errors.
- Right-click on the newly added java source folder (montezuma-cases/src/generatedtests/java) and Run As... Unit Tests. Confirm if asked to proceed regardless of the existing project errors. Unit tests should be run, succeeding except for some of those in packages with "untestable.until" in their paths.
- In a terminal shell run the script "move_tests_to_previous.sh" in the Montezuma's root folder.
- Back in eclipse, Run As... Java Application: montezuma-cases/src/main/java/org/montezuma/test/traffic/writing/cases/WriteAllNoMocking.java
- In the terminal run the shell script "compare_generated_tests.sh" in the Montezuma's root folder. This should fire-up 'meld' comparing the test classes as generated by WriteAllMocking and WriteAllNoMocking. If you don't have meld, you can install it on Mac with 'brew install meld' or on Linux probably with something like 'sudo apt-get install meld' or on Windows use WinMerge, or perhaps just compare the 'montezuma-cases/previous_generated_tests' and 'montezuma-cases/src/generatedtests' folders with a diff program, like 'diff'.
In order to record your code execution, you have to add to the Java command-line: - a javaagent option, e.g.: -javaagent:/path/to/aspectjweaver-1.8.9.jar - a recording option, e.g.: -Dmontezuma.recordings.dir=/path/to/my/recordings/dir - some required libraries, e.g.: /path/to/montezuma-common-0.0.1-SNAPSHOT.jar:/path/to/montezuma-recording-0.0.1-SNAPSHOT.jar:/path/to/kryo-3.0.3.jar:/path/to/minlog-1.3.0.jar:/path/to/objenesis-2.1.jar: If your normal Java command-line is... java -cp myproject/target/classes/ my.package.MainClass ...then it will become... java -javaagent:/path/to/aspectjweaver-1.8.9.jar -Dmontezuma.recordings.dir=/path/to/my/recordings/dir -cp /path/to/montezuma-common-0.0.1-SNAPSHOT.jar:/path/to/montezuma-recording-0.0.1-SNAPSHOT.jar:/path/to/kryo-3.0.3.jar:/path/to/minlog-1.3.0.jar:/path/to/objenesis-2.1.jar:myproject/target/classes/ my.package.MainClass
Replaying is done by invoking the TrafficReplayer class by command-line... java -cp /path/to/montezuma-replaying-0.0.1-SNAPSHOT.jar:/path/to/montezuma-common-0.0.1-SNAPSHOT.jar:/path/to/kryo-3.0.3.jar:/path/to/kryo-3.0.3.jar:/path/to/minlog-1.3.0.jar:/path/to/reflectasm-1.10.1.jar:/path/to/objenesis-2.1.jar:/path/to/asm-5.0.3.jar:/path/to/commons-cli-1.3.1.jar:myproject/target/classes/ org.montezuma.test.traffic.replaying.TrafficReplayer --classname=canonical.name.of.the.class.to.Replay --recordingspath=/path/to/my/recordings/dir ...or from Java... TrafficReplayer.replay(Class<?> clazz, File recordingDir);
Generating tests is done by invoking the TrafficToUnitTestsWriter class... java -cp /path/to/montezuma-test-generation-0.0.1-SNAPSHOT.jar:/path/to/montezuma-common-0.0.1-SNAPSHOT.jar:/path/to/kryo-3.0.3.jar:/path/to/kryo-3.0.3.jar:/path/to/minlog-1.3.0.jar:/path/to/reflectasm-1.10.1.jar:/path/to/objenesis-2.1.jar:/path/to/asm-5.0.3.jar:/path/to/commons-cli-1.3.1.jar:myproject/target/classes/ org.montezuma.test.traffic.writing.TrafficToUnitTestsWriter --classname=canonical.name.of.the.class.to.Replay --recordingspath=/path/to/my/recordings/dir --dontmock=java.lang.,java.math.,java.text.,java.util. --destinationclasspath=/path/to/my/src/generatedtests/java [--testclassnameprefix=Prefix] [--testclassjavadoc=Javadoc] ...or from Java... new TrafficToUnitTestsWriter().generateTestsFor(final Class<?> clazz, File recordingDir, List dontMockRegexList, String outputClassPath, String testClassNamePrefix, String classJavadoc);
The "WriteAll" class runs all the code with all possible option combinations, so what is not run by it is dead code.