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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上