11

sys.argvを使用してさまざまなことを実行し、パラメーターにアクセスするスクリプトがありますが、スクリプトがコードの単体テスト部分に到達すると、このためのモジュールがないと表示されます。私が持っているスクリプトは次のとおりです。

class MyScript():

    def __init__(self):
        self.value = sys.argv[1]

    def hello(self):
        print self.value

    def suite(self):
        modules_to_test = ('external_sanity_onvif', 'starttest')
        alltests = unittest.TestSuite()
        for module in map(__import__, modules_to_test):
            alltests.addTest(unittest.findTestCases(module))
        return alltests


if __name__ == '__main__': 
    Run = MyScript()
    Run.hello()
    log_file = 'log_file.txt'
    test_file = open(log_file, "w") 
    runner = unittest.TextTestRunner(test_file)
    unittest.main(defaultTest='Run.suite', testRunner=runner)

./script.py Helloコマンドラインに入力するとします。私が得るエラーは次のとおりです。

AttributeError: 'module' object has no attribute 'Hello'

unittestモジュールを削除すると、機能します。また、テストランナーログを削除して、次の場所に残しておくと、次のようになります。

unittest.main(defaultTest='Run.suite')

これはまだ機能しません。

誰でも助けることができます。

ありがとう

私はこのハックを試しましたが、それでもを読み込もうとしますsys.argv

project = sys.argv[4:]
sys.argv = sys.argv[0:4]

私はこれを試してみましたargvが、それでも余分なパラメータを読み取るのは面倒です。

4

4 に答える 4

19

問題はunittest.main()、貴重な argv を独自に使用したいということです! 関数パラメーターとして指定した argv を使用するか、sys.argv明示的に argv を指定しない場合は、指定した引数の名前のテストをロードしようとします。Helloこの場合、これは、 という名前のサブモジュール、 という名前のTestCaseクラス、 という名前Helloのテスト ケース クラス内のテスト ケース メソッド、または またはインスタンスを返す というHello呼び出し可能なオブジェクトのいずれかを、すべてモジュール 'script' 内で探していることを意味します。HelloTestCaseTestSuite

これを修正するには、いくつかの方法があります。

  • 低レベルの unittest 関数を自分でバイパスunittest.main()して呼び出し、考えているテスト ケースをセットアップして実行します。
  • へのコードの依存関係を削除しsys.argv、そのunittest.main()動作を有利に利用してください。モジュールが単体テスト以外で独立して実行されることを意図していない場合、モジュールの呼び出し元はあなたが argv から読み取ることを期待していない可能性があるため、これはおそらく理にかなっています!
  • テスト コードとメイン ルーチンを別のテスト モジュールに分けます。テスト モジュールから正しい argv をコードに取り込む方法を理解する必要があります。
  • argv=[sys.argv[0]]への引数として指定しunittest.main()ます。それはあなたのものを読もうとしないようにするはずです。
于 2010-05-15T05:19:23.937 に答える
9

unittest モジュールのコマンドライン機能が必要ない場合は、呼び出す直前に sys.argv を変更することで、optparse モジュールと unittest モジュールをうまく連携させることができます。unittest.main()

unittest.main()通話の直前にこれを試してください:

del sys.argv[1:]

これにより、コマンド ライン引数が unittest に表示される前に削除されます。

optparse モジュールを使用していない場合は、代わりにこれを行うことができます。

my_args = sys.argv[1:]
del sys.argv[1:]
# do_stuff(my_args)
unittest.main()
于 2011-08-13T17:50:29.527 に答える
1

一般的に言えば、単体テストの背後にある考え方は、外部ドライバーなしでテストを実行することです。たとえば、コマンド ラインからの入力に依存したくない場合などです。お探しのソリューションは、Fixtures の使用によるものでしょうか?

import sys
import unittest

class MyScript(unittest.TestCase):
    def setUp(self):
        self.value = "Default Value"

    def setHello(self, value):
        self.value = value

    def hello(self):
        return self.value

class UserA(MyScript):
    def setUp(self):
        self.setHello("UserA")

    def testMyName(self):
        self.failUnlessEqual(self.hello(), "UserA")

class UserB(MyScript):
    def setUp(self):
        self.setHello("UserB")

    def testMyName(self):
        self.failUnlessEqual(self.hello(), "UserB")

if __name__ == '__main__': 
    unittest.main()
于 2010-05-11T16:45:51.950 に答える
-1

Python は可能な限りすべての情報を提供します。あなたがテストしようとしているもののセット全体を投稿したくない場合を除いて、私たちはあなたが何を達成しようとしているのかを推測することしかできません. エラーは、「Hello」という名前の属性がないことを示しているため、テストしようとしているモジュールは、そのような変数、関数、またはその他を取得する必要があります。

だけを使用していない理由はありますunittest.main()か?

于 2010-05-11T16:13:32.917 に答える