douque9815 2016-11-04 11:38
浏览 85
已采纳

如果没有执行测试,PHPUnit应该会失败

I use PHPUnit to execute unit tests on my Gitlab CI Server. When no tests are executed the build pass altough there could be an error (e.g. autoloader issue).

Is there a way to tell PHPUnit Command Line Runner it should exit with code 1 if no test is executed?

  • 写回答

1条回答 默认 最新

  • drpfu51608120170 2016-11-04 11:44
    关注

    If there's no tests, there's nothing PHPUnit can mark as failed. PHPUnit, therefore, can't do this. What you can use is another one of Sebastian Bergmann's tools phploc.

    This has a --count-tests option. Run that before running phpunit, process the result and if the count is 0, just exit 1 from a script.


    Update, I just realized I missed the obvious thing to do a bit earlier.

    A simple way to do this is would be:

     count=$(./phploc.phar --count-tests src | awk '/Tests/{getline; print}' | awk '{print $NF}') && [ "${count}" -ne "0" ]
    exit $?
    

    Most of the command breakdown below applies, so I'm leaving that as-is. The main difference is at the end:

    [ "${count}" -ne "0" ]
    exit $?
    

    This basically means: compare ${count} to 0, if it doesn't match 0, the comparison will exit with status 0, if it's 0, the exit status will be 1. We then simple reuse the exit status in our own exit statement: exit $? is basically saying: exit with the same exit status as the last thing we did.


    the simple command to get the exit status you're looking for can be obtained using this command:

     count=$(./phploc.phar --count-tests src | awk '/Tests/{getline; print}' | awk '{print $NF}') && [ "${count}" -eq "0" ] && exit 1 || exit 0
    

    Breaking it down a bit:

    ./phploc.phar --count-tests src
    

    This basically runs phploc on the src directory, and the output will contain a section that looks something like:

    Tests
        classes      123
        methods      1234
    

    What we're after is the line after Tests. so the output of the command is passed to awk, which will match Tests, get the next line and print that (ie: classes 123). This happens here:

    | awk '/Tests/{getline; print}'
    

    That string is passed to awk yet again, to extract the last part (the actual number of tests found):

    awk '{print $NF}'
    

    That value will be assigned to count, because we're running these commands like so:

    count=$(phploc | awk | awk)
    

    So the final output is assigned to count. Next, we want to see if the test count is zero or not, and based on that we need to exit with a zero, or non-zero status. This is something we can easily do like so:

     [ "${count}" -eq "0" ] && exit 1 || exit 0
    

    This is basically shorthand for:

    if [ "${count}" -eq "0" ]; then
        exit 1
    else
        exit 0
    fi
    

    That's thanks to short-circuit evaluation: if [ "${count}" -eq "0" ] evaluates to true, the && clause needs to be evaluated, which is an exit 1 statement, returning the desired non-zero exit code

    If we omit the || exit 0, the last status code would be the result of the [ "${count}" -eq "0" ] && exit 1 evaluation, which is false, resulting in an status code of 1. To avoid that, we have to add the || exit 0.

    You can easily check this by writing something like this on your CLI:

    foo="bar" && [ "${foo}" -eq "123" ] && echo 'foo matched 123'
    //run this, then run
    echo $?
    

    The output will be 1 (last command's exit status)


    Last update

    If the unit tests don't take much longer than a couple of minutes to run, and you don't care about running them twice, you can just check the output of phpunit. I've quickly tried running phpunit 5.4.6 on one of the projects I am working on, after removing the tests directory. The output was something like this:

    PHPUnit 5.4.6 by Sebastian Bergmann and contributors.
    
    
    
    Time: 51 ms, Memory: 8.50MB
    
    No tests executed!
    

    So running:

    vendor/bin/phpunit | grep -q 'No tests executed'
    

    yields the exit status 0 if there were no tests, 1 if there were. Simply check the exit status and exit with the opposite code. Something like this probably works:

    vendor/bin/phpunit | grep -q 'No tests executed' && exit 1 || exit 0
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比