92

Python では、コマンド ラインから unittest 関数に引数を渡すにはどうすればよいですか?

これまでのコードは次のとおりです。間違っていることはわかっています。

class TestingClass(unittest.TestCase):

    def testEmails(self):
        assertEqual(email_from_argument, "my_email@example.com")


if __name__ == "__main__":
    unittest.main(argv=[sys.argv[1]])
    email_from_argument = sys.argv[1]
4

7 に答える 7

156

ここにいる医者たちは「痛いって言ったでしょ?そんなことしないで!」と言っているのです。おそらく正しいです。しかし、どうしてもやりたい場合は、単体テスト テストに引数を渡す 1 つの方法を次に示します。

import sys
import unittest

class MyTest(unittest.TestCase):
    USERNAME = "jemima"
    PASSWORD = "password"

    def test_logins_or_something(self):
        print('username:', self.USERNAME)
        print('password:', self.PASSWORD)


if __name__ == "__main__":
    if len(sys.argv) > 1:
        MyTest.USERNAME = sys.argv.pop()
        MyTest.PASSWORD = sys.argv.pop()
    unittest.main()

これにより、次のように実行できます。

python mytests.py myusername mypassword

sが必要なargv.popので、コマンド ライン パラメータが unittest 自身のパラメータを台無しにしないようにします...

他に調べたいことは、環境変数の使用です。

import os
import unittest

class MyTest(unittest.TestCase):
    USERNAME = "jemima"
    PASSWORD = "password"

    def test_logins_or_something(self):
        print('username:', self.USERNAME)
        print('password:', self.PASSWORD)

if __name__ == "__main__":
    MyTest.USERNAME = os.environ.get('TEST_USERNAME', MyTest.USERNAME)
    MyTest.PASSWORD = os.environ.get('TEST_PASSWORD', MyTest.PASSWORD)
    unittest.main()

これにより、次のように実行できます。

TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py

また、ユニットテスト自体の引数の解析をいじらないという利点があります。欠点は、Windowsではそのように機能しないことです...

于 2013-12-20T11:47:58.530 に答える
34

すべきではないという正しい発言にもかかわらず、本当にこれをやりたい人のための別の方法:

import unittest

class MyTest(unittest.TestCase):

    def __init__(self, testName, extraArg):
        super(MyTest, self).__init__(testName)  # calling the super class init varies for different python versions.  This works for 2.7
        self.myExtraArg = extraArg

    def test_something(self):
        print(self.myExtraArg)

# call your test
suite = unittest.TestSuite()
suite.addTest(MyTest('test_something', extraArg))
unittest.TextTestRunner(verbosity=2).run(suite)
于 2014-04-28T21:43:40.480 に答える
12

テストの達人がそれをすべきではないと言っているとしても、私はします。コンテキストによっては、テストを正しい方向に進めるためのパラメーターを用意することは非常に理にかなっています。たとえば、次のようになります。

  • 今、このテストに使用するべき同一の USB カードは 12 枚ありますか?
  • このテストにはどのサーバーを使用する必要がありますか?
  • どの XXX を使用すればよいですか?

私にとっては、環境変数の使用は、パラメータを渡すための専用コードを記述する必要がないため、この用途には十分です。Python でサポートされています。すっきりとシンプルです。

もちろん、完全にパラメータ化可能なテストを推奨しているわけではありません。しかし、私たちは実用的である必要があり、前述したように、状況によっては 1 つまたは 2 つのパラメーターが必要です。私たちはそれを乱用すべきではありません:)

import os
import unittest


class MyTest(unittest.TestCase):
    def setUp(self):
        self.var1 = os.environ["VAR1"]
        self.var2 = os.environ["VAR2"]

    def test_01(self):
        print("var1: {}, var2: {}".format(self.var1, self.var2))

次に、コマンドラインから (Linux でテスト済み)

$ export VAR1=1
$ export VAR2=2
$ python -m unittest MyTest
var1: 1, var2: 2
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
于 2017-10-13T14:26:22.560 に答える
4

steffens21 のアプローチをで使用するunittest.TestLoader場合は、元のテスト ローダーを変更できます (「参考文献」を参照unittest.py)。

import unittest
from unittest import suite

class TestLoaderWithKwargs(unittest.TestLoader):
    """A test loader which allows to parse keyword arguments to the
       test case class."""
    def loadTestsFromTestCase(self, testCaseClass, **kwargs):
        """Return a suite of all tests cases contained in 
           testCaseClass."""
        if issubclass(testCaseClass, suite.TestSuite):
            raise TypeError("Test cases should not be derived from "\
                            "TestSuite. Maybe you meant to derive from"\ 
                            " TestCase?")
        testCaseNames = self.getTestCaseNames(testCaseClass)
        if not testCaseNames and hasattr(testCaseClass, 'runTest'):
            testCaseNames = ['runTest']

        # Modification here: parse keyword arguments to testCaseClass.
        test_cases = []
        for test_case_name in testCaseNames:
            test_cases.append(testCaseClass(test_case_name, **kwargs))
        loaded_suite = self.suiteClass(test_cases)

        return loaded_suite 

# call your test
loader = TestLoaderWithKwargs()
suite = loader.loadTestsFromTestCase(MyTest, extraArg=extraArg)
unittest.TextTestRunner(verbosity=2).run(suite)
于 2016-06-20T07:22:26.280 に答える
1

私も同じ問題を抱えてる。私の解決策は、argparse または別の方法を使用して引数を解析して処理した後、sys.argv から引数を削除することです。

sys.argv = sys.argv[:1]  

必要に応じて、main.parseArgs() から unittest 引数をフィルタリングできます。

于 2017-04-12T09:55:02.967 に答える