2012-02-04 2 views
10

(かなり複雑な)Bash補完スクリプトの単体テストを書いておきたいと思います.Bit補完の値をプログラマチックに取得するだけです。 テストは次のようになります。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の完了をシミュレートすることができますか?

+2

ない下に配置され

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() 

[本](HTTP ://stackoverflow.com/questions/3520936/accesssing-bash-completions-for-specific-commands-programmatically)は役に立ちますか?私はそれを自分で試していない。 – Vikas

+1

ユーザインタラクションをシミュレートしたい場合、 'expect'はあなたの友人です - あなたのfs/envをpythonでセットアップし、サブプロセスを使ってexpectスクリプト内からbashを実行してください。エスケープは難しいかもしれませんが、そうでなければかなり簡単です。 – je4d

答えて

6

は、ファイル内のbash補完スクリプトを含む、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を使用するすべての補完のために働く必要がありますが、同様に他の人のために働くことがあります。ここでは、unittestの中にいることをやっての例です。

je4dさんのコメントexpectは、より完全なテストのための良い1つです。

+0

うわー、まさに私が望んでいた。 – ifischer

0

ボンバイダイビングのソリューションはほとんど私のために働いた。私はbash文字列スクリプトを変更しなければならなかった。私は追加の ';'セパレータを実行したbashスクリプトに置き換えます。そうしないと、Mac OS Xでは実行されません。

私はまた、さまざまなケースを処理するために、さまざまなCOMP_引数の初期化を一般化しました。

最終溶液は、上記のように試験が書き込まれるようにパイソンからbashの完了をテストするために、ヘルパークラスである:完了LIBをhttps://github.com/lacostej/unity3d-bash-completion/blob/master/lib/completion.py