Unconditionally execute a task in ant?

2019-06-20 04:37发布

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..

5条回答
手持菜刀,她持情操
2楼-- · 2019-06-20 05:07

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.

查看更多
Luminary・发光体
3楼-- · 2019-06-20 05:07

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.

查看更多
爷的心禁止访问
4楼-- · 2019-06-20 05:10

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>
查看更多
贪生不怕死
5楼-- · 2019-06-20 05:10

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.

查看更多
Explosion°爆炸
6楼-- · 2019-06-20 05:18

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

查看更多
登录 后发表回答