enabling assertions in ant - java

I want to enable the assertion facility in ant. In my ant build.xml, I put the follows, trying to enable assertions.
<project> ...
<assertions>
<enable/>
</assertions>
</project>
I put assertion in a junit file, which includes only one function,
testAssertions() {
assert false;
}
when running ant, assertion fails are not thrown.. How to enable assertion in this setting?

It looks like your <assertions> subelement is a child of <project>, is this correct?
I am assuming that you are running the test via the <junit> ant task. If this is correct, making the <assertions><enable/></assertions> subelement a child of <junit> should work.

To enable assertions, I edited nbproject/project.properties and changed
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
to
run.jvmargs=\
-ea
After doing this, assertions were enabled when I executed ant run.

Related

How to run my Spring tests before every commit/push?

Surprisingly, I was not able to find a this question on this website, so here it comes :
How can I run my Spring tests before every git commit/push (CLI, GUI and IDE integration) and have this command fail on test fail ?
I am aware of the existence of git hooks and run my tests using mvnw test. How to combine this to get the described behavior ?
You can use any (bash) script as a git pre-commit or pre-push hook. Git should abort if the script returns a non-zero return code.
So create a script named pre-commit.tests or pre-push.tests that looks roughly like this
#!/bin/bash
mvnw test
and register the hook, e.g. by placing the script in .git/hooks.
mvn test should already return a non-zero return code if tests fail.
If not you would need to determine whether the tests succeeded in your script. For instance by piping the result to grep and looking for an ERROR entry or a more indicative line that either indicates success or failure.
Note: If you happen to be working in a Windows/Mac environment you'd likely need to adapt this based on how you integrated git, i.e. whether you run in a bash-compatible console or not.

How do I disable Java assertions for a junit test in the code

How do I disable java assertions (not junit assert) for a junit test in the code
Ive written a junit test but when I run it it doesnt fail as expected because assertions are enabled, whereas they are not in production.
Is there a way to disable assertions just in the code so that it work as expected when run within IDE and when built as part of Maven
Within Java (disabling assertions in single class)
To enable or disable assertion checking within Java use setClassAssertionStatus in the ClassLoader. For example:
Foo.class.getClassLoader().setClassAssertionStatus(Foo.class.getName(), false);
Within Maven (disabling assertions for all classes)
Since version 2.3.1, Maven Surefire has a separate enableAssertions flag.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>your_version</version>
<configuration>
<enableAssertions>false</enableAssertions>
</configuration>
</plugin>
With JUnit 4 Assume (for single test case)
Ideally, your tests should pass regardless of assertions are enabled or disabled. If one of the tests depends on assertions being disabled, the intended JUnit mechanism is to use an assumption:
import static org.junit.Assume.assumeTrue;
#Test
public foo onlyWithoutAssertions() {
assumeTrue(assertionsDisabled());
// your tricky test comes here, and is only executed in
// environments with assertion checking disabled.
}
public static boolean assertionsDisabled() {
return !Foo.class.desiredAssertionStatus();
}
Note: I typically use this option the other way around: To check that an assert works as expected, in rare cases I have a test that assumes that assertion checking is enabled.
With JUnit 5 Assume
JUnit 5 assumptions are an extension of the JUnit 4 ones.
Thus, for JUnit 5, the only change to the JUnit 4 code is the import, which now is from jupiter:
import static org.junit.jupiter.api.Assumptions.assumeTrue;
Typically you use surefire with maven for JUnit tests. Adding -disableassertions or the synonym -da as an argument should work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>your_version</version>
<configuration>
<argLine>-disableassertions</argLine>
</configuration>
</plugin>
If the tests are launched different through the IDE (that is outside of maven), you probably need to edit some launch configuration and pass the parameter. This is, however, IDE dependent.
Look at -da and -ea parameters for java tool. So, in you case just use one of them (+ specify correspond package on your application) as you want to disable or enable assertions.
With no arguments, -enableassertions or -ea enables assertions.
With one argument ending in "...", the switch enables assertions in the specified package and any subpackages.
If the argument is "...", then the switch enables assertions in the unnamed package in the current working directory.
With one argument not ending in "...", the switch enables assertions in the specified class.
Note: Do you use such (java) assertion at all, if you disable assertions during tests? If no, just remove given assertion! It is just boilerplate.
If you use it (in some UI tests, acceptance tests or in performance tests) and thus you are expecting that given asserts will catch some regressions and they will be not triggered during normal release pipeline, it is good thing to check if someone has not removed such assertion without any knowledge!
You can expect exception (AssertionError extends Error extends Throwable) in test. Use assertThrows in junit testing for example.

Fail ant build by checking junit report?

I need to cause my build to fail based only on the junit report. Is there a way to do this. I know how to fail the build using haltonfailure in junit tag, but in my build.xml I have access only to the junit report. I am using ant.
Try something like
<fail if="testFail" message="At least one unit test failed"/>
in your unit test target.
Refer to this: http://ant.apache.org/manual/Tasks/junit.html ,
try using failureproperty="failed.unit.test.property" inside junit ant task & check if its set & fail when your run completes with :
<fail if="failed.unit.test.property" message="Unit tests failed with more custom msg to your test class/suite"/>

How to step-debug annotation processor during compile?

I have an annotation processor for an annotation of retention policy=SOURCE.
I have not idea how to step-debug it.
I have issued print statements, logger info when I run mvn install, compile or package or ant javac, and I see their sysouts in the compile log.
However, I have no idea how to step-debug the processor in Eclipse. I mean, how do you step-debug compile-time?
An option in recent times is to use something like http://github.com/google/compile-testing which lets you invoke the compilation job against arbitrary annotation processors, which you can set break points, step through, etc.
#Test public void testStuff() {
// Create a source file to process, or load one from disk.
JavaFileObject file = JavaFileObjects.fromSourceLines("test.Foo",
"package test;",
"",
"import bar.*;",
"",
"#MyAnnotation(blah=false)",
"interface TestInterface {",
" Bar someBar();",
"}",
// assert conditions following a compilation in the context of MyProcessor.
assert_().about(javaSource()).that(file)
.processedWith(new MyProcessor())
.failsToCompile()
.withErrorContaining("some error message").in(file).onLine(5);
}
This test expects you will get some error message because #MyAnnotation is incorrectly declared in the test data source. If this assertion fails, you can run it in debug mode in your IDE, set breakpoints in MyProcessor, and step through with a full compiler environment active during debugging.
For unit testing specific methods within your processor, you can also use the #Rule called CompilationRule from which you can obtain Elements and Types utility classes in order to test specific logic in your compiler in a more isolated way.
You have to invoke the Java compiler from Eclipse, using a debug configuration (you'll need to create the configuration manually, from the "Debug Configurations..." menu choice.
The "correct" way to invoke the Java compiler under JDK 1.6 or above is to use the JavaCompiler interface in javax.tools, which you get from the ToolProvider (I include all the links because there's a decent amount of class/package documentation that you should read).
The "quick-and-dirty" way (that should work, but I make no guarantees) is to invoke com.sun.tools.javac.Main.main(), passing it your normal command-line arguments. To do this, you'll need tools.jar on your classpath (it's found in $JAVA_HOME/lib).
Annotation processing occurs during compilation, so normal debugging won't work. If you want to debug it in the context of you project, you can use Eclipse remote debugging, while having Gradle or Maven in debug mode. Then you can put breakpoints in the Annotation Processor's files.
See Debugging an Annotation Processor in any project.
Disclaimer: I wrote the post.

Unconditionally execute a task in ant?

I'm trying to define a task that emits (using echo) a message when a target completes execution, regardless of whether that target was successful or not. Specifically, the target executes a task to run some unit tests, and I want to emit a message indicating where the results are available:
<target name="mytarget">
<testng outputDir="${results}" ...>
...
</testng>
<echo>Tests complete. Results available in ${results}</echo>
</target>
Unfortunately, if the tests fail, the task fails and execution aborts. So the message is only output if the tests pass - the opposite of what I want. I know I can put the task before the task, but this will make it easier for users to miss this message. Is what I'm trying to do possible?
Update: It turns out I'm dumb. I had haltOnFailure="true" in my <testng> task, which explains the behaviour I was seeing. Now the issue is that setting this to false causes the overall ant build to succeed even if tests fail, which is not what I want. The answer below using the task looks like it might be what I want..
You can use a try-catch block like so:
<target name="myTarget">
<trycatch property="foo" reference="bar">
<try>
<testing outputdir="${results}" ...>
...
</testing>
</try>
<catch>
<echo>Test failed</echo>
</catch>
<finally>
<echo>Tests complete. Results available in ${results}</echo>
</finally>
</trycatch>
</target>
According to the Ant docs, there are two properties that control whether the build process is stopped or not if the testng task fails:
haltonfailure - Stop the build process
if a failure has occurred during the
test run. Defaults to false.
haltonskipped - Stop the build process
if there is at least on skipped test.
Default to false.
I can't tell from the snippet if you're setting this property or not. May be worth trying to explicitly set haltonfailure to false if it's currently set to true.
Also, assuming you're using the <exec> functionality in Ant, there are similar properties to control what happens if the executed command fails:
failonerror - Stop the buildprocess if the command exits with a return code
signaling failure. Defaults to false.
failifexecutionfails - Stop the build if we can't start the program.
Defaults to true.
Can't tell based on the partial code snippet in your post, but my guess is that the most likely culprit is failonerror or haltonfailure being set to true.
The solution to your problem is to use the failureProperty in conjunction with the haltOnFailure property of the testng task like this:
<target name="mytarget">
<testng outputDir="${results}" failureProperty="tests.failed" haltOnFailure="false" ...>
...
</testng>
<echo>Tests complete. Results available in ${results}</echo>
</target>
Then, elsewhere when you want the build to fail you add ant code like this:
<target name="doSomethingIfTestsWereSuccessful" unless="tests.failed">
...
</target>
<target name="doSomethingIfTestsFailed" if="tests.failed">
...
<fail message="Tests Failed" />
</target>
You can then call doSomethingIfTestsFailed where you want your ant build to fail.
Although you are showing a fake task called "testng" in your example I presume you are using the junit target.
In this case, it is strange you are seeing these results because the junit target by default does NOT abort execution on a test failure.
There is a way to actually tell ant to stop the build on a junit failure or error by using the halt attributes, eg. haltonfailure:
<target name="junit" depends="junitcompile">
<junit printsummary="withOutAndErr" fork="yes" haltonfailure="yes">
However, both haltonfailure and haltonerror are by default set to off. I suppose you could check your build file to see if either of these flags have been set. They can even be set globally, so one thing you could try is to explicitly set it to "no" on your task to make sure it is overridden in case it is set in the global scope.
http://ant.apache.org/manual/Tasks/junit.html
Can you fork the testng task ? If yes, then, you might want to use that feature so that the testng task will run on a different JVM.

Categories