15

(かなり複雑な)Bash補完スクリプトのユニットテストを、できればPythonで書きたいと思います-Bash補完の値をプログラムで取得するだけのものです。テストは次のようになります。

def test_completion():
  # trigger_completion should return what a user should get on triggering 
  # Bash completion like this: 'pbt createkvm<TAB>' 
  assert trigger_completion('pbt createkvm') == "module1 module2 module3" 

Bash の補完をプログラムでシミュレートして、ツールのテストスイート内の補完の値を確認するにはどうすればよいですか?

4

2 に答える 2

9

という名前のファイルに bash-completion スクリプトがありasdf-completion、次を含むとします。

_asdf() {
COMPREPLY=()
local cur prev
cur=$(_get_cword)
COMPREPLY=( $( compgen -W "one two three four five six" -- "$cur") )
return 0
}    
complete -F _asdf asdf

これはシェル関数_asdfを使用して、架空のasdfコマンドの補完を提供します。適切な環境変数を (bash の man ページから) 設定すると、同じ結果が得られます。これは、COMPREPLY変数への潜在的な展開の配置です。単体テストでそれを行う例を次に示します。

import subprocess
import unittest

class BashTestCase(unittest.TestCase):
    def test_complete(self):
        completion_file="asdf-completion"
        partial_word="f"
        cmd=["asdf", "other", "arguments", partial_word]
        cmdline = ' '.join(cmd)

        out = subprocess.Popen(['bash', '-i', '-c',
            r'source {compfile}; COMP_LINE="{cmdline}" COMP_WORDS=({cmdline}) COMP_CWORD={cword} COMP_POINT={cmdlen} $(complete -p {cmd} | sed "s/.*-F \\([^ ]*\\) .*/\\1/") && echo ${{COMPREPLY[*]}}'.format(
                compfile=completion_file, cmdline=cmdline, cmdlen=len(cmdline), cmd=cmd[0], cword=cmd.index(partial_word)
                )],
            stdout=subprocess.PIPE)
        stdout, stderr = out.communicate()
        self.assertEqual(stdout, "four five\n")

if (__name__=='__main__'):
    unittest.main()

これは、 を使用するすべての補完で機能するはずですが、他の補完で-Fも機能する可能性があります。

使用する je4d のコメントexpectは、より完全なテストに適しています。

于 2012-02-29T19:01:02.187 に答える
1

bonsaiviking のソリューションは、ほとんどうまくいきました。bash 文字列スクリプトを変更する必要がありました。余分な「;」を追加しました セパレーターを実行された bash スクリプトに追加しないと、実行が Mac OS X で機能しません。理由はよくわかりません。

また、最終的に発生したさまざまなケースを処理するために、さまざまな COMP_ 引数の初期化を少し一般化しました。

最終的な解決策は、上記のテストが次のように記述されるように、Python からの bash の完了をテストするヘルパー クラスです。

from completion import BashCompletionTest

class AdsfTestCase(BashCompletionTest):
    def test_orig(self):
        self.run_complete("other arguments f", "four five")

    def run_complete(self, command, expected):
        completion_file="adsf-completion"
        program="asdf"
        super(AdsfTestCase, self).run_complete(completion_file, program, command, expected)


if (__name__=='__main__'):
    unittest.main()

補完ライブラリは、https://github.com/lacostej/unity3d-bash-completion/blob/master/lib/completion.pyにあります。

于 2012-04-21T14:24:27.873 に答える